initial brax3 device makefiles
* boots and works fine Signed-off-by: erascape <erascape@proton.me>
This commit is contained in:
commit
59281ccd87
67 changed files with 3271 additions and 0 deletions
769
ramdisk-overlay/scripts/halium
Normal file
769
ramdisk-overlay/scripts/halium
Normal file
|
@ -0,0 +1,769 @@
|
|||
# Local filesystem mounting -*- shell-script -*-
|
||||
|
||||
_log_msg() {
|
||||
if [ "$quiet" = "y" ]; then return; fi
|
||||
printf "$@" > /dev/kmsg || true
|
||||
}
|
||||
|
||||
pre_mountroot() {
|
||||
[ "$quiet" != "y" ] && log_begin_msg "Running /scripts/local-top"
|
||||
run_scripts /scripts/local-top
|
||||
[ "$quiet" != "y" ] && log_end_msg
|
||||
}
|
||||
|
||||
tell_kmsg() {
|
||||
# Echos a string into /dev/kmsg, ignoring errors.
|
||||
echo "initrd: $1" >/dev/kmsg || true
|
||||
}
|
||||
|
||||
halium_panic() {
|
||||
# Puts panic reason into kmsg and then starts the panic handlers
|
||||
REASON="$1"
|
||||
tell_kmsg "PANIC for reason: $REASON"
|
||||
panic $REASON
|
||||
}
|
||||
|
||||
identify_boot_mode() {
|
||||
# Our current list of supported boot modes:
|
||||
## BOOT_MODE = halium and android
|
||||
BOOT_MODE='halium'
|
||||
|
||||
# The boot reason is exported via /proc/cmdline
|
||||
# The standard method is using androidboot.mode parameter.
|
||||
|
||||
for x in $(cat /proc/cmdline); do
|
||||
case ${x} in
|
||||
androidboot.mode=*)
|
||||
android_bootmode=${x#*=}
|
||||
;;
|
||||
# Android 9 system-as-root
|
||||
skip_initramfs)
|
||||
normal_boot="y"
|
||||
;;
|
||||
# Android 10+ recovery-as-boot
|
||||
androidboot.force_normal_boot=1)
|
||||
normal_boot="y"
|
||||
;;
|
||||
# Android 12+ (GKI 2.0+) recovery-as-boot
|
||||
bootconfig)
|
||||
if grep -q 'androidboot.force_normal_boot = "1"' /proc/bootconfig; then
|
||||
normal_boot="y"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if echo "$android_bootmode" | grep charger; then
|
||||
BOOT_MODE="android"
|
||||
fi
|
||||
|
||||
## Some devices may be using 'bootreason', others 'boot_reason'
|
||||
## XXX: Find a better way to handle device specifics here
|
||||
|
||||
# Krillin
|
||||
if [ -f /sys/class/BOOT/BOOT/boot/boot_mode ]; then
|
||||
boot_reason=$(cat /sys/class/BOOT/BOOT/boot/boot_mode)
|
||||
case "${boot_reason}" in
|
||||
1) BOOT_MODE="android" ;; # Meta
|
||||
4) BOOT_MODE="android" ;; # Factory
|
||||
8) BOOT_MODE="android" ;; # Power off charging
|
||||
9) BOOT_MODE="android" ;; # Low power charging
|
||||
esac
|
||||
fi
|
||||
|
||||
# System-as-root or a device without dedicated recovery partition
|
||||
if [ -f /ramdisk-recovery.img ] && [ -z "$normal_boot" ]; then
|
||||
BOOT_MODE="recovery"
|
||||
fi
|
||||
|
||||
# On Android 8+ devices the 'android' boot mode is broken and should be avoided.
|
||||
# This behavior can be overridden with the cmdline flag 'halium_no_avoid_android_mode'
|
||||
# List of API levels and referred Android versions: https://source.android.com/setup/start/build-numbers
|
||||
if ! grep -wq halium_no_avoid_android_mode /proc/cmdline; then
|
||||
api_level=$(sed -n 's/^ro.build.version.sdk=//p' /android-system/build.prop) # e.g. 26 for Android 8.0
|
||||
[ -z "$api_level" ] && api_level=0
|
||||
tell_kmsg "Android system image API level is $api_level"
|
||||
if [ "$BOOT_MODE" = "android" ] && [ $api_level -ge 26 ]; then
|
||||
tell_kmsg "Android 8+ device detected! Charging is to be handled by rootfs, continue boot normally"
|
||||
BOOT_MODE='halium'
|
||||
fi
|
||||
fi
|
||||
|
||||
tell_kmsg "boot mode: $BOOT_MODE"
|
||||
}
|
||||
|
||||
identify_android_image() {
|
||||
# Checks for the provided Android image. If it's called system.img, it
|
||||
# should be mounted at Android's /system. If it's called android-rootfs.img,
|
||||
# it should be mounted at Android's /.
|
||||
# Sets $ANDROID_IMAGE_MODE to:
|
||||
# * "rootfs" if the image should be mounted at '/android/'
|
||||
# * "system" if the image should be mounted at '/android/system/'
|
||||
# * "unknown" if neither is found
|
||||
|
||||
[ -f /tmpmnt/system.img ] && ANDROID_IMAGE_MODE="system"
|
||||
[ -f /tmpmnt/android-rootfs.img ] && ANDROID_IMAGE_MODE="rootfs"
|
||||
[ -f /halium-system/var/lib/lxc/android/system.img ] && ANDROID_IMAGE_MODE="system"
|
||||
[ -f /halium-system/var/lib/lxc/android/android-rootfs.img ] && ANDROID_IMAGE_MODE="rootfs"
|
||||
[ -z $ANDROID_IMAGE_MODE ] && ANDROID_IMAGE_MODE="unknown"
|
||||
}
|
||||
|
||||
set_halium_version_properties() {
|
||||
halium_system=$1
|
||||
android_data=$2
|
||||
|
||||
channel_ini=$1/etc/system-image/channel.ini
|
||||
def_language=$1/custom/default_language
|
||||
|
||||
halium="unknown"
|
||||
device="unknown"
|
||||
custom="unknown"
|
||||
version="unknown"
|
||||
channel="unknown"
|
||||
def_lang="unknown"
|
||||
|
||||
if [ -f "$channel_ini" ]; then
|
||||
IFS=','
|
||||
for i in $(grep version_detail $channel_ini | awk -F ' ' '{print $2}'); do
|
||||
id=${i%=*}
|
||||
case $id in
|
||||
halium) halium=${i#halium=} ;;
|
||||
device) device=${i#device=} ;;
|
||||
custom) custom=${i#custom=} ;;
|
||||
version) version=${i#version=} ;;
|
||||
esac
|
||||
done
|
||||
unset IFS
|
||||
channel=$(grep channel $channel_ini | awk -F ' ' '{print $2}')
|
||||
fi
|
||||
|
||||
if [ -f "$def_language" ]; then
|
||||
lang=$(cat $def_language)
|
||||
if [ -n "$lang" ]; then
|
||||
def_lang=$lang
|
||||
fi
|
||||
fi
|
||||
|
||||
# Write down so the android property system can load them automatically
|
||||
mkdir -p $android_data/property
|
||||
chmod 700 $android_data/property
|
||||
echo -n "$halium" >$android_data/property/persist.halium.version.rootfs
|
||||
echo -n "$device" >$android_data/property/persist.halium.version.device
|
||||
echo -n "$custom" >$android_data/property/persist.halium.version.custom
|
||||
echo -n "$channel" >$android_data/property/persist.halium.version.channel
|
||||
echo -n "$version" >$android_data/property/persist.halium.version
|
||||
echo -n "$def_lang" >$android_data/property/persist.halium.default_language
|
||||
chmod 600 $android_data/property/persist.halium*
|
||||
}
|
||||
|
||||
mount_android_partitions() {
|
||||
fstab=$1
|
||||
mount_root=$2
|
||||
real_userdata=$3
|
||||
|
||||
tell_kmsg "checking fstab $fstab for additional mount points"
|
||||
|
||||
# On systems with A/B partition layout, current slot is provided via cmdline parameter.
|
||||
ab_slot_suffix=$(grep -o 'androidboot\.slot_suffix=..' /proc/cmdline | tail -1 | cut -d "=" -f2)
|
||||
[ ! -z "$ab_slot_suffix" ] && tell_kmsg "A/B slot system detected! Slot suffix is $ab_slot_suffix"
|
||||
|
||||
cat ${fstab} | while read line; do
|
||||
set -- $line
|
||||
|
||||
# stop processing if we hit the "#endhalium" comment in the file
|
||||
echo $1 | egrep -q "^#endhalium" && break
|
||||
|
||||
# Skip any unwanted entry
|
||||
echo $1 | egrep -q "^#" && continue
|
||||
([ -z "$1" ] || [ -z "$2" ] || [ -z "$3" ] || [ -z "$4" ]) && continue
|
||||
([ "$2" = "/system" ] || [ "$2" = "/data" ] || [ "$2" = "/" ]) && continue
|
||||
|
||||
label=$(echo $1 | awk -F/ '{print $NF}')
|
||||
[ -z "$label" ] && continue
|
||||
|
||||
tell_kmsg "checking mount label $label"
|
||||
|
||||
# In case fstab provides /dev/mmcblk0p* lines
|
||||
path="/dev/$label"
|
||||
for dir in by-partlabel by-name by-label by-path by-uuid by-partuuid by-id; do
|
||||
# On A/B systems not all of the partitions are duplicated, so we have to check with and without suffix
|
||||
if [ -e "/dev/disk/$dir/$label$ab_slot_suffix" ]; then
|
||||
path="/dev/disk/$dir/$label$ab_slot_suffix"
|
||||
break
|
||||
elif [ -e "/dev/disk/$dir/$label" ]; then
|
||||
path="/dev/disk/$dir/$label"
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
[ ! -e "$path" ] && continue
|
||||
|
||||
mkdir -p ${mount_root}/$2
|
||||
tell_kmsg "mounting $path as ${mount_root}/$2"
|
||||
mount $path ${mount_root}/$2 -t $3 -o $4
|
||||
done
|
||||
|
||||
# Provide a bind mount from /cache to /userdata/cache on systems without a dedicated cache partition
|
||||
if [ ! -e ${mount_root}/cache ] || ! grep -q "${mount_root}/cache" /proc/mounts; then
|
||||
if [ ! -d ${real_userdata}/cache ]; then
|
||||
mkdir ${real_userdata}/cache
|
||||
fi
|
||||
mkdir ${mount_root}/cache
|
||||
mount -o bind ${real_userdata}/cache ${mount_root}/cache
|
||||
fi
|
||||
|
||||
# Create an appropriate symlink for vendor files
|
||||
if [ ! -e ${mount_root}/vendor ]; then
|
||||
ln -sf system/vendor ${mount_root}/vendor
|
||||
fi
|
||||
}
|
||||
|
||||
mount_halium_overlay() {
|
||||
source=$1
|
||||
target=$2
|
||||
|
||||
if [ -d ${source} ]; then
|
||||
OLD_PWD=$PWD
|
||||
cd ${source}
|
||||
|
||||
for overlay in $(find . -type f); do
|
||||
[ -f ${target}/${overlay} ] && mount --bind ${source}/${overlay} ${target}/${overlay}
|
||||
done
|
||||
|
||||
cd $OLD_PWD
|
||||
fi
|
||||
}
|
||||
|
||||
sync_dirs() {
|
||||
base=$1
|
||||
source=$2
|
||||
target=$3
|
||||
|
||||
OLD_PWD=$PWD
|
||||
cd $base
|
||||
|
||||
for file in $source/*; do
|
||||
# Skip empty directories
|
||||
[ ! -e "$base/$file" -a ! -L "$base/$file" ] && continue
|
||||
|
||||
# If the target already exists as a file or link, there's nothing we can do
|
||||
[ -e "$target/$file" -o -L "$target/$file" ] && [ ! -d "$target/$file" ] && continue
|
||||
|
||||
# If the target doesn't exist, just copy it over
|
||||
if [ ! -e "$target/$file" -a ! -L "$target/$file" ]; then
|
||||
cp -Ra "$base/$file" "$target/$file"
|
||||
continue
|
||||
fi
|
||||
|
||||
# That leaves us with directories and a recursive call
|
||||
[ -d $file ] && sync_dirs $base $file $target
|
||||
done
|
||||
|
||||
cd $OLD_PWD
|
||||
}
|
||||
|
||||
resize_userdata_if_needed() {
|
||||
|
||||
# See if the filesystem on the userdata partition needs resizing (usually on first boot).
|
||||
# If the difference between the partition size and the filesystem size is above a small
|
||||
# threshold, assume it needs resizing to fill the partition.
|
||||
|
||||
path=$1
|
||||
|
||||
# Partition size in 1k blocks
|
||||
case $path in
|
||||
/dev/mmcblk*)
|
||||
pblocks=$(grep ${path#/dev/*} /proc/partitions | awk {'print $3'})
|
||||
;;
|
||||
/dev/disk*)
|
||||
pblocks=$(grep $(basename $(readlink $path)) /proc/partitions | awk {'print $3'})
|
||||
;;
|
||||
esac
|
||||
# Filesystem size in 4k blocks
|
||||
fsblocks=$(dumpe2fs -h $path | grep "Block count" | awk {'print $3'})
|
||||
# Difference between the reported sizes in 1k blocks
|
||||
dblocks=$((pblocks - 4 * fsblocks))
|
||||
if [ $dblocks -gt 10000 ]; then
|
||||
resize2fs -f $path
|
||||
tell_kmsg "resized userdata filesystem to fill $path"
|
||||
fi
|
||||
}
|
||||
|
||||
identify_file_layout() {
|
||||
# Determine if we have a Halium rootfs.img & system.img
|
||||
|
||||
# $file_layout = "halium" means there is a separate rootfs.img and system.img on userdata
|
||||
#
|
||||
# = "partition" means the rootfs is located on the device's system partition
|
||||
# and will contain /var/lib/lxc/android/system.img
|
||||
#
|
||||
# = "subdir" means the rootfs is located in a folder on the device's userdata partition
|
||||
# and will contain /var/lib/lxc/android/system.img
|
||||
|
||||
if [ -e /tmpmnt/rootfs.img ]; then
|
||||
imagefile=/tmpmnt/rootfs.img
|
||||
file_layout="halium"
|
||||
elif [ -e /tmpmnt/ubuntu.img ]; then
|
||||
imagefile=/tmpmnt/ubuntu.img
|
||||
file_layout="legacy"
|
||||
elif [ -d /tmpmnt/halium-rootfs ]; then
|
||||
imagefile=/tmpmnt/halium-rootfs
|
||||
file_layout="subdir"
|
||||
else
|
||||
file_layout="partition"
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
process_bind_mounts() {
|
||||
# Goes over /etc/system-image/writable-paths to create the correct fstab for
|
||||
# the bind-mounts. Writes them into ${rootmnt}/run/image.fstab which is
|
||||
# bind-mounted to /etc/fstab
|
||||
|
||||
if [ ! -e ${rootmnt}/etc/system-image/writable-paths ]; then
|
||||
tell_kmsg "This rootfs does not have any writable-paths defined"
|
||||
return 0
|
||||
fi
|
||||
|
||||
# Mount a tmpfs in /run of rootfs to put the future image.fstab
|
||||
mount -o rw,nosuid,noexec,relatime,mode=755 -t tmpfs tmpfs ${rootmnt}/run
|
||||
# Prepare the fstab
|
||||
FSTAB=${rootmnt}/etc/fstab
|
||||
touch ${rootmnt}/run/image.fstab
|
||||
mount -o bind ${rootmnt}/run/image.fstab $FSTAB ||halium_panic "Could not bind-mount fstab"
|
||||
echo "/dev/root / rootfs defaults,ro 0 0" >>$FSTAB
|
||||
|
||||
tell_kmsg "Adding bind-mounts to $FSTAB"
|
||||
# Process the list of bind-mounts
|
||||
# (but don't mount them, mountall will do it)
|
||||
cat ${rootmnt}/etc/system-image/writable-paths | while read line; do
|
||||
set -- $line
|
||||
# Skip invalid/commented entries
|
||||
([ -z "$1" ] || [ -z "$2" ] || [ -z "$3" ] || [ -z "$4" ] || [ -z "$5" ]) && continue
|
||||
[ "$1" = "#" ] && continue
|
||||
|
||||
# Skip invalid mount points
|
||||
dstpath="${rootmnt}/$1"
|
||||
[ ! -e "$dstpath" ] && continue
|
||||
|
||||
if [ "$3" = "temporary" ]; then
|
||||
# Temporary entries are simple, just mount a tmpfs
|
||||
echo "tmpfs $1 tmpfs $5 0 0" >>$FSTAB
|
||||
elif [ "$3" = "persistent" ] || [ "$3" = "synced" ]; then
|
||||
# Figure out the source path
|
||||
if [ "$2" = "auto" ]; then
|
||||
srcpath="${rootmnt}/userdata/system-data/$1"
|
||||
path="/userdata/system-data/$1"
|
||||
else
|
||||
srcpath="${rootmnt}/userdata/$2"
|
||||
path="/userdata/$2"
|
||||
fi
|
||||
|
||||
if [ ! -e "$srcpath" ]; then
|
||||
# Process new persistent or synced paths
|
||||
dstown=$(stat -c "%u:%g" $dstpath)
|
||||
dstmode=$(stat -c "%a" $dstpath)
|
||||
mkdir -p ${srcpath%/*}
|
||||
if [ ! -d "$dstpath" ]; then
|
||||
# Deal with redirected files
|
||||
if [ "$4" = "transition" ]; then
|
||||
cp -a $dstpath $srcpath
|
||||
else
|
||||
touch $srcpath
|
||||
chown $dstown $srcpath
|
||||
chmod $dstmode $srcpath
|
||||
fi
|
||||
else
|
||||
# Deal with redirected directories
|
||||
if [ "$4" = "transition" ] || [ "$3" = "synced" ]; then
|
||||
cp -aR $dstpath $srcpath
|
||||
else
|
||||
mkdir $srcpath
|
||||
chown $dstown $srcpath
|
||||
chmod $dstmode $srcpath
|
||||
fi
|
||||
fi
|
||||
elif [ "$3" = "synced" ]; then
|
||||
# Process existing synced paths
|
||||
sync_dirs $dstpath . $srcpath
|
||||
fi
|
||||
|
||||
if [ "$5" = "none" ]; then
|
||||
mount_opts="bind"
|
||||
else
|
||||
mount_opts="bind,$5"
|
||||
fi
|
||||
|
||||
# mount all /etc dirs right now, not later when fstab is
|
||||
# processed, as it will cause races (e.g. /etc/machine-id).
|
||||
case "$1" in
|
||||
/etc/*)
|
||||
mount -o "$mount_opts" "$srcpath" "$dstpath"
|
||||
;;
|
||||
*)
|
||||
echo "$path $1 none $mount_opts 0 0" >>$FSTAB
|
||||
;;
|
||||
esac
|
||||
else
|
||||
continue
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
extract_android_ramdisk() {
|
||||
# Extracts the ramdisk from /android-system/boot/android-ramdisk.img to
|
||||
# /android-rootfs
|
||||
|
||||
# NOTE: we should find a faster way of doing that or cache it
|
||||
tell_kmsg "extracting android ramdisk"
|
||||
OLD_CWD=$(pwd)
|
||||
mount -n -t tmpfs tmpfs /android-rootfs
|
||||
cd /android-rootfs
|
||||
cat /android-system/boot/android-ramdisk.img | gzip -d | cpio -i
|
||||
cd $OLD_CWD
|
||||
}
|
||||
|
||||
mount_kernel_modules() {
|
||||
# Bind-mount /lib/modules from Android
|
||||
[ -e ${rootmnt}/android/system/lib/modules ] && mount --bind ${rootmnt}/android/system/lib/modules ${rootmnt}/lib/modules
|
||||
}
|
||||
|
||||
load_kernel_modules() {
|
||||
mkdir -p /lib/modules
|
||||
cd /lib/modules
|
||||
ln -sf /lib/modules "/lib/modules/$(uname -r)"
|
||||
|
||||
tell_kmsg "Loading kernel modules from $(pwd)"
|
||||
|
||||
cat modules.load | while read line; do
|
||||
set -- $line
|
||||
# Skip commented entries
|
||||
[ "$1" = "#" ] && continue
|
||||
modprobe -a "$1"
|
||||
done
|
||||
|
||||
cd -
|
||||
}
|
||||
|
||||
mountroot() {
|
||||
# list of possible userdata partition names
|
||||
partlist="userdata UDA DATAFS USERDATA"
|
||||
|
||||
pre_mountroot
|
||||
|
||||
[ "$quiet" != "y" ] && log_begin_msg "Running /scripts/local-premount"
|
||||
run_scripts /scripts/local-premount
|
||||
[ "$quiet" != "y" ] && log_end_msg
|
||||
|
||||
# Put all of this script's output into /dev/kmsg
|
||||
exec &>/dev/kmsg
|
||||
|
||||
load_kernel_modules
|
||||
tell_kmsg "Finished loading kernel modules"
|
||||
sleep 1
|
||||
|
||||
# busybox mdev -s
|
||||
# udevadm trigger
|
||||
|
||||
# Mount root
|
||||
#
|
||||
# Create a temporary mountpoint for the bindmount
|
||||
mkdir -p /tmpmnt
|
||||
|
||||
# Make sure the device has been created by udev before we try to mount
|
||||
udevadm settle
|
||||
|
||||
# find the right partition
|
||||
for partname in $partlist; do
|
||||
part=$(find /dev -name $partname | tail -1)
|
||||
[ -z "$part" ] && continue
|
||||
path=$(readlink -f $part)
|
||||
[ -n "$path" ] && break
|
||||
done
|
||||
|
||||
# On systems with A/B partition layout, current slot is provided via cmdline parameter.
|
||||
ab_slot_suffix=$(grep -o 'androidboot\.slot_suffix=..' /proc/cmdline | tail -1 | cut -d "=" -f2)
|
||||
if [ -z "$path" ] && [ ! -z "$ab_slot_suffix" ] ; then
|
||||
tell_kmsg "Searching for A/B data partition on slot $ab_slot_suffix."
|
||||
|
||||
for partname in $partlist; do
|
||||
part=$(find /dev -name "$partname$ab_slot_suffix" | tail -1)
|
||||
[ -z "$part" ] && continue
|
||||
path=$(readlink -f $part)
|
||||
[ -n "$path" ] && break
|
||||
done
|
||||
fi
|
||||
|
||||
# override with a possible cmdline parameter
|
||||
if grep -q datapart= /proc/cmdline; then
|
||||
for x in $(cat /proc/cmdline); do
|
||||
case ${x} in
|
||||
datapart=*)
|
||||
path=${x#*=}
|
||||
;;
|
||||
esac
|
||||
done
|
||||
fi
|
||||
|
||||
if [ -z "$path" ]; then
|
||||
halium_panic "Couldn't find data partition."
|
||||
fi
|
||||
|
||||
tell_kmsg "checking filesystem integrity for the userdata partition"
|
||||
# Mounting and umounting first, let the kernel handle the journal and
|
||||
# orphaned inodes (faster than e2fsck). Then, just run e2fsck forcing -y.
|
||||
# Also check the amount of time used by to check the filesystem.
|
||||
fsck_start=$(date +%s)
|
||||
mount -o errors=remount-ro $path /tmpmnt
|
||||
umount /tmpmnt
|
||||
e2fsck -y $path >/run/e2fsck.out 2>&1
|
||||
fsck_end=$(date +%s)
|
||||
tell_kmsg "checking filesystem for userdata took (including e2fsck) $((fsck_end - fsck_start)) seconds"
|
||||
|
||||
resize_userdata_if_needed ${path}
|
||||
|
||||
tell_kmsg "mounting $path"
|
||||
|
||||
# Mount the data partition to a temporary mount point
|
||||
# FIXME: data=journal used on ext4 as a workaround for bug 1387214
|
||||
[ `blkid $path -o value -s TYPE` = "ext4" ] && OPTIONS="data=journal,"
|
||||
mount -o discard,$OPTIONS $path /tmpmnt
|
||||
|
||||
# setup super partition if exists
|
||||
if [ -n "/dev/disk/by-partlabel/super" ]; then
|
||||
tell_kmsg "trying to parse and dmsetup subpartitions from super partition"
|
||||
/sbin/parse-android-dynparts /dev/disk/by-partlabel/super | sh
|
||||
dmsetup mknodes
|
||||
fi
|
||||
|
||||
# Set $_syspart if it is specified as systempart= on the command line
|
||||
if grep -q systempart= /proc/cmdline; then
|
||||
for x in $(cat /proc/cmdline); do
|
||||
case ${x} in
|
||||
systempart=*)
|
||||
_syspart=${x#*=}
|
||||
if [ -z ${_syspart##*:*} ]; then
|
||||
_syspart_options=${_syspart##*:}
|
||||
_syspart=${_syspart%%:*}
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ -z "$_syspart_options" ]; then
|
||||
_syspart_options=rw
|
||||
fi
|
||||
fi
|
||||
|
||||
identify_file_layout
|
||||
|
||||
# Default to /dev/mapper/system if no image file is found
|
||||
[ -z "$imagefile" ] && [ -z "$_syspart" ] && _syspart=/dev/mapper/system
|
||||
|
||||
# We need to add the slot suffix to $_syspart for A/B devices
|
||||
if [ -n "$_syspart" ] && [ ! -e "$_syspart" ]; then
|
||||
[ -z "$ab_slot_suffix" ] && ab_slot_suffix=_a
|
||||
tell_kmsg "A/B slot system detected! Slot suffix is $ab_slot_suffix"
|
||||
_syspart="${_syspart}${ab_slot_suffix}"
|
||||
tell_kmsg "system partition is at $_syspart"
|
||||
fi
|
||||
|
||||
# If both $imagefile and $_syspart are set, something is wrong. The strange
|
||||
# output from this could be a clue in that situation.
|
||||
tell_kmsg "Halium rootfs is $imagefile $_syspart"
|
||||
|
||||
# Prepare the root filesystem
|
||||
# NOTE: We mount it read-write in all cases, then remount read-only.
|
||||
# This is to workaround a behaviour change in busybox which now
|
||||
# uses read-only loops if the fs is initially mounted read-only.
|
||||
# An alternative implementation would be to add losetup support
|
||||
# to busybox and do the mount in two steps (rw loop, ro fs).
|
||||
|
||||
mkdir -p /halium-system
|
||||
|
||||
tell_kmsg "mounting system rootfs at /halium-system"
|
||||
if [ -n "$_syspart" ]; then
|
||||
mount -o "$_syspart_options" $_syspart /halium-system
|
||||
elif [ -f "$imagefile" ]; then
|
||||
# Rootfs is an image file
|
||||
mount -o loop,rw $imagefile /halium-system
|
||||
elif [ -d "$imagefile" ]; then
|
||||
# Rootfs is a directory
|
||||
mount -o bind /tmpmnt/halium-rootfs /halium-system
|
||||
fi
|
||||
|
||||
# Identify image mode: either "rootfs" or "system"
|
||||
mkdir -p /android-rootfs
|
||||
mkdir -p /android-system
|
||||
|
||||
identify_android_image
|
||||
[ $ANDROID_IMAGE_MODE = "unknown" ] && tell_kmsg "WARNING: Android system image not found."
|
||||
|
||||
if { [ -n "$_syspart_options" ] && [ -z "${_syspart_options##*ro*}" ]; } || [ -e /tmpmnt/.writable_image_overlay ] || [ -e /halium-system/.writable_image_overlay ]; then
|
||||
# If systempart had to be mounted ro, mount rw overlayfs on top
|
||||
mkdir -p /tmpmnt/rootfs-overlay /tmpmnt/rootfs-overlay-workdir
|
||||
mount -t overlay rootfs -o lowerdir=/halium-system,upperdir=/tmpmnt/rootfs-overlay,workdir=/tmpmnt/rootfs-overlay-workdir /halium-system
|
||||
fi
|
||||
|
||||
# If either (android) /data/.writable_image or (on rootfs)
|
||||
# /.writable_image exist, mount the rootfs as rw
|
||||
if [ -e /tmpmnt/.writable_image ] || [ -e /halium-system/.writable_image ]; then
|
||||
tell_kmsg "mounting $_syspart $imagefile (image developer mode)"
|
||||
mountroot_status="$?"
|
||||
else
|
||||
# Neither of those exist, remount read-only
|
||||
tell_kmsg "mounting $_syspart $imagefile (user mode)"
|
||||
mount -o remount,ro /halium-system
|
||||
mountroot_status="$?"
|
||||
fi
|
||||
|
||||
# Mount the android system partition to a temporary location
|
||||
MOUNT="ro"
|
||||
MOUNT_LOCATION="/android-$ANDROID_IMAGE_MODE"
|
||||
[ $ANDROID_IMAGE_MODE = "system" ] && ANDROID_IMAGE="system.img" || ANDROID_IMAGE="android-rootfs.img"
|
||||
[ -e /tmpmnt/.writable_device_image -o -e /halium-system/.writable_device_image ] && MOUNT="rw"
|
||||
tell_kmsg "mounting android system image (/tmpmnt/$ANDROID_IMAGE) $MOUNT, in $MOUNT_LOCATION ($ANDROID_IMAGE_MODE mode)"
|
||||
if [ $file_layout = "halium" ]; then
|
||||
# rootfs.img and Android system.img are separate
|
||||
tell_kmsg "mounting android system image from userdata partition"
|
||||
mount -o loop,$MOUNT "/tmpmnt/$ANDROID_IMAGE" $MOUNT_LOCATION
|
||||
else
|
||||
# Android system.img is inside rootfs
|
||||
tell_kmsg "mounting android system image from system rootfs"
|
||||
mount -o loop,$MOUNT "/halium-system/var/lib/lxc/android/$ANDROID_IMAGE" $MOUNT_LOCATION
|
||||
fi
|
||||
|
||||
[ $? -eq 0 ] || tell_kmsg "WARNING: Failed to mount Android system.img."
|
||||
|
||||
[ $ANDROID_IMAGE_MODE = "rootfs" ] && mount -o bind $MOUNT_LOCATION/system /android-system
|
||||
[ $ANDROID_IMAGE_MODE = "system" ] && extract_android_ramdisk
|
||||
|
||||
identify_boot_mode
|
||||
|
||||
# Determine whether we should boot to rootfs or Android
|
||||
if [ "$BOOT_MODE" = "recovery" ]; then
|
||||
tell_kmsg "Recovery boot mode for system-as-root devices"
|
||||
|
||||
# Clean up mounted partitions so recovery can manage them
|
||||
umount -d /android-system /android-rootfs /halium-system /tmpmnt
|
||||
dmsetup remove_all
|
||||
|
||||
mount -n -t tmpfs tmpfs ${rootmnt}
|
||||
cd ${rootmnt}
|
||||
if [ -d /lib/modules ]; then
|
||||
mkdir -p lib/modules
|
||||
mv /lib/modules/* lib/modules/
|
||||
fi
|
||||
cat /ramdisk-recovery.img | gzip -d | cpio -i
|
||||
cd -
|
||||
mkdir -p ${rootmnt}/sbin
|
||||
ln -s ../init ${rootmnt}/sbin/init
|
||||
elif ([ -e $imagefile ] || [ -n "$_syspart" ]) && [ "$BOOT_MODE" = "android" ]; then
|
||||
# Bootloader says this is factory or charger mode, boot into Android.
|
||||
tell_kmsg "Android boot mode for factory or charger mode"
|
||||
|
||||
mount --move /android-rootfs ${rootmnt}
|
||||
[ $ANDROID_IMAGE_MODE = "system" ] && mount --move /android-system ${rootmnt}/system
|
||||
|
||||
# Mount all the Android partitions
|
||||
mount_android_partitions "${rootmnt}/fstab*" ${rootmnt} /tmpmnt
|
||||
|
||||
mkdir -p ${rootmnt}/halium-system
|
||||
mount --move /halium-system ${rootmnt}/halium-system
|
||||
|
||||
# Mounting userdata
|
||||
mkdir -p ${rootmnt}/data
|
||||
mkdir -p /tmpmnt/android-data
|
||||
mount -o bind /tmpmnt/android-data ${rootmnt}/data
|
||||
|
||||
# Set halium version properties
|
||||
set_halium_version_properties ${rootmnt}/halium-system ${rootmnt}/data
|
||||
|
||||
# Make sure we're booting into android's init
|
||||
ln -s ../init ${rootmnt}/sbin/init
|
||||
ln -s ../init ${rootmnt}/sbin/recovery
|
||||
tell_kmsg "booting android..."
|
||||
elif [ -e $imagefile ] || [ -n "$_syspart" ]; then
|
||||
# Regular image boot
|
||||
tell_kmsg "Normal boot"
|
||||
|
||||
mount --move /halium-system ${rootmnt}
|
||||
mkdir -p ${rootmnt}/android
|
||||
|
||||
# Mounting userdata outside of /android, to avoid having LXC container access it
|
||||
mkdir -p ${rootmnt}/userdata
|
||||
mount --move /tmpmnt ${rootmnt}/userdata
|
||||
|
||||
mount --move /android-rootfs ${rootmnt}/var/lib/lxc/android/rootfs
|
||||
[ $ANDROID_IMAGE_MODE = "system" ] && mount -o rw,size=4096 -t tmpfs none ${rootmnt}/android
|
||||
[ $ANDROID_IMAGE_MODE = "rootfs" ] && mount -o bind ${rootmnt}/var/lib/lxc/android/rootfs ${rootmnt}/android
|
||||
|
||||
mkdir -p ${rootmnt}/android/data ${rootmnt}/android/system
|
||||
|
||||
# Create a fake android data, shared by rootfs and LXC container
|
||||
mkdir -p ${rootmnt}/userdata/android-data
|
||||
mount -o bind ${rootmnt}/userdata/android-data ${rootmnt}/android/data
|
||||
[ ! -h ${rootmnt}/data ] && ln -sf /android/data ${rootmnt}/data
|
||||
|
||||
set_halium_version_properties ${rootmnt} ${rootmnt}/userdata/android-data
|
||||
|
||||
# Get device information
|
||||
device=$(grep ^ro.product.device= /android-system/build.prop | sed -e 's/.*=//')
|
||||
[ -z "$device" ] && device="unknown" && tell_kmsg "WARNING: Didn't find a device name. Is the Android system image mounted correctly?"
|
||||
tell_kmsg "device is $device"
|
||||
|
||||
process_bind_mounts
|
||||
|
||||
# Mount all the Android partitions
|
||||
mount_android_partitions "${rootmnt}/var/lib/lxc/android/rootfs/fstab*" ${rootmnt}/android ${rootmnt}/userdata
|
||||
|
||||
# system is a special case
|
||||
tell_kmsg "moving Android system to /android/system"
|
||||
mount --move /android-system ${rootmnt}/android/system
|
||||
|
||||
# halium overlay available in the Android system image (hardware specific configs)
|
||||
if [ -e ${rootmnt}/android/system/halium ]; then
|
||||
mount_halium_overlay ${rootmnt}/android/system/halium ${rootmnt}
|
||||
fi
|
||||
|
||||
# Apply device-specific udev rules
|
||||
if [ -e ${rootmnt}/usr/lib/lxc-android-config/70-$device.rules ] &&
|
||||
[ ! -f ${rootmnt}/android/system/halium/lib/udev/rules.d/70-android.rules ] &&
|
||||
[ "$device" != "unknown" ]; then
|
||||
mount --bind ${rootmnt}/usr/lib/lxc-android-config/70-$device.rules ${rootmnt}/lib/udev/rules.d/70-android.rules
|
||||
fi
|
||||
|
||||
# Bind-mount /lib/modules from Android
|
||||
mount_kernel_modules
|
||||
|
||||
# Bind-mount /var/lib/ureadahead if available on persistent storage
|
||||
# this is required because ureadahead runs before mountall
|
||||
if [ -e ${rootmnt}/userdata/system-data/var/lib/ureadahead ] &&
|
||||
[ -e ${rootmnt}/var/lib/ureadahead ]; then
|
||||
mount --bind ${rootmnt}/userdata/system-data/var/lib/ureadahead ${rootmnt}/var/lib/ureadahead
|
||||
fi
|
||||
|
||||
# Setup the swap device
|
||||
[ -e ${rootmnt}/userdata/SWAP.img ] && swapon ${rootmnt}/userdata/SWAP.img
|
||||
|
||||
# Apply customized content
|
||||
for user in ${rootmnt}/userdata/user-data/*; do
|
||||
if [ -d ${rootmnt}/custom/home ] && [ ! -e "$user/.customized" ]; then
|
||||
tell_kmsg "copying custom content tp "
|
||||
cp -Rap ${rootmnt}/custom/home/* "$user/"
|
||||
cp -Rap ${rootmnt}/custom/home/.[a-zA-Z0-9]* "$user/"
|
||||
touch "$user/.customized"
|
||||
dstown=$(stat -c "%u:%g" "$user")
|
||||
chown -R $dstown "$user/"
|
||||
fi
|
||||
done
|
||||
|
||||
else
|
||||
# Possibly a re-partitioned device
|
||||
halium_panic "Couldn't find a system partition."
|
||||
fi
|
||||
|
||||
[ "$quiet" != "y" ] && log_begin_msg "Running /scripts/local-bottom"
|
||||
run_scripts /scripts/local-bottom
|
||||
[ "$quiet" != "y" ] && log_end_msg
|
||||
}
|
167
ramdisk-overlay/scripts/panic/telnet
Executable file
167
ramdisk-overlay/scripts/panic/telnet
Executable file
|
@ -0,0 +1,167 @@
|
|||
#!/bin/sh
|
||||
|
||||
PREREQ=""
|
||||
prereqs() {
|
||||
echo "$PREREQ"
|
||||
}
|
||||
case $1 in
|
||||
# get pre-requisites
|
||||
prereqs)
|
||||
prereqs
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
|
||||
USB_FUNCTIONS=rndis
|
||||
ANDROID_USB=/sys/class/android_usb/android0
|
||||
GADGET_DIR=/config/usb_gadget
|
||||
LOCAL_IP=192.168.2.15
|
||||
EXPLICIT_BUSYBOX="/bin/busybox"
|
||||
TELNET_DEBUG_PORT=23
|
||||
|
||||
write() {
|
||||
echo -n "$2" >"$1"
|
||||
}
|
||||
|
||||
# This sets up the USB with whatever USB_FUNCTIONS are set to via configfs
|
||||
usb_setup_configfs() {
|
||||
G_USB_ISERIAL=$GADGET_DIR/g1/strings/0x409/serialnumber
|
||||
|
||||
mkdir $GADGET_DIR/g1
|
||||
write $GADGET_DIR/g1/idVendor "0x18D1"
|
||||
write $GADGET_DIR/g1/idProduct "0xD001"
|
||||
mkdir $GADGET_DIR/g1/strings/0x409
|
||||
write $GADGET_DIR/g1/strings/0x409/serialnumber "$1"
|
||||
write $GADGET_DIR/g1/strings/0x409/manufacturer "Halium initrd"
|
||||
write $GADGET_DIR/g1/strings/0x409/product "Failed to boot"
|
||||
|
||||
if echo $USB_FUNCTIONS | grep -q "rndis"; then
|
||||
NETWORK_FUNCTION=""
|
||||
for function in ncm.usb0 rndis.usb0 rndis_bam.rndis; do
|
||||
if mkdir $GADGET_DIR/g1/functions/$function; then
|
||||
NETWORK_FUNCTION=$function
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if [ -z "$NETWORK_FUNCTION" ]; then
|
||||
echo "Error: No USB network gadget function available" >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
echo $USB_FUNCTIONS | grep -q "mass_storage" && mkdir $GADGET_DIR/g1/functions/storage.0
|
||||
|
||||
mkdir $GADGET_DIR/g1/configs/c.1
|
||||
mkdir $GADGET_DIR/g1/configs/c.1/strings/0x409
|
||||
write $GADGET_DIR/g1/configs/c.1/strings/0x409/configuration "$USB_FUNCTIONS"
|
||||
|
||||
if echo $USB_FUNCTIONS | grep -q "rndis"; then
|
||||
ln -s $GADGET_DIR/g1/functions/$NETWORK_FUNCTION $GADGET_DIR/g1/configs/c.1
|
||||
fi
|
||||
echo $USB_FUNCTIONS | grep -q "mass_storage" && ln -s $GADGET_DIR/g1/functions/storage.0 $GADGET_DIR/g1/configs/c.1
|
||||
|
||||
echo "$(ls /sys/class/udc | grep -v dummy | head -1)" > $GADGET_DIR/g1/UDC
|
||||
}
|
||||
|
||||
# This sets up the USB with whatever USB_FUNCTIONS are set to via android_usb
|
||||
usb_setup_android_usb() {
|
||||
G_USB_ISERIAL=$ANDROID_USB/iSerial
|
||||
write $ANDROID_USB/enable 0
|
||||
write $ANDROID_USB/functions ""
|
||||
write $ANDROID_USB/enable 1
|
||||
usleep 500000 # 0.5 delay to attempt to remove rndis function
|
||||
write $ANDROID_USB/enable 0
|
||||
write $ANDROID_USB/idVendor 18D1
|
||||
write $ANDROID_USB/idProduct D001
|
||||
write $ANDROID_USB/iManufacturer "Halium initrd"
|
||||
write $ANDROID_USB/iProduct "Failed to boot"
|
||||
write $ANDROID_USB/iSerial "$1"
|
||||
write $ANDROID_USB/functions $USB_FUNCTIONS
|
||||
write $ANDROID_USB/enable 1
|
||||
}
|
||||
|
||||
# This determines which USB setup method is going to be used
|
||||
usb_setup() {
|
||||
mkdir /config || true
|
||||
mount -t configfs none /config || true
|
||||
|
||||
if [ -d $ANDROID_USB ]; then
|
||||
usb_setup_android_usb $1
|
||||
elif [ -d $GADGET_DIR ]; then
|
||||
usb_setup_configfs $1
|
||||
fi
|
||||
}
|
||||
|
||||
usb_info() {
|
||||
# make sure USB is settled
|
||||
echo "########################## usb_info: $1"
|
||||
sleep 1
|
||||
write $G_USB_ISERIAL "$1"
|
||||
}
|
||||
|
||||
inject_loop() {
|
||||
INJ_DIR=/init-ctl
|
||||
INJ_STDIN=$INJ_DIR/stdin
|
||||
|
||||
mkdir $INJ_DIR
|
||||
mkfifo $INJ_STDIN
|
||||
echo "This entire directory is for debugging init - it can safely be removed" >$INJ_DIR/README
|
||||
|
||||
echo "########################## Beginning inject loop"
|
||||
while :; do
|
||||
while read IN; do
|
||||
if [ "$IN" = "continue" ]; then break 2; fi
|
||||
$IN
|
||||
done <$INJ_STDIN
|
||||
done
|
||||
rm -rf $INJ_DIR # Clean up if we exited nicely
|
||||
echo "########################## inject loop done"
|
||||
}
|
||||
|
||||
usb_setup "halium-initrd telnet 192.168.2.15"
|
||||
|
||||
USB_IFACE=notfound
|
||||
/sbin/ifconfig rndis0 $LOCAL_IP && USB_IFACE=rndis0
|
||||
if [ x$USB_IFACE = xnotfound ]; then
|
||||
/sbin/ifconfig usb0 $LOCAL_IP && USB_IFACE=usb0
|
||||
fi
|
||||
# Report for the logs
|
||||
/sbin/ifconfig -a
|
||||
|
||||
# Unable to set up USB interface? Reboot.
|
||||
if [ x$USB_IFACE = xnotfound ]; then
|
||||
usb_info "Halium initrd Debug: ERROR: could not setup USB as usb0 or rndis0"
|
||||
dmesg
|
||||
sleep 60 # plenty long enough to check usb on host
|
||||
reboot -f
|
||||
fi
|
||||
|
||||
# Create /etc/udhcpd.conf file.
|
||||
echo "start 192.168.2.20" >/etc/udhcpd.conf
|
||||
echo "end 192.168.2.90" >>/etc/udhcpd.conf
|
||||
echo "lease_file /var/udhcpd.leases" >>/etc/udhcpd.conf
|
||||
echo "interface $USB_IFACE" >>/etc/udhcpd.conf
|
||||
echo "option subnet 255.255.255.0" >>/etc/udhcpd.conf
|
||||
|
||||
# Be explicit about busybox so this works in a rootfs too
|
||||
echo "########################## starting dhcpd"
|
||||
$EXPLICIT_BUSYBOX udhcpd
|
||||
|
||||
# Non-blocking telnetd
|
||||
echo "########################## starting telnetd"
|
||||
# We run telnetd on different ports pre/post-switch_root This
|
||||
# avoids problems with an unterminated pre-switch_root telnetd
|
||||
# hogging the port
|
||||
$EXPLICIT_BUSYBOX telnetd -b ${LOCAL_IP}:${TELNET_DEBUG_PORT} -l /bin/sh
|
||||
|
||||
# For some reason this does not work in rootfs
|
||||
usb_info "Halium initrd Debug telnet on port $TELNET_DEBUG_PORT on $USB_IFACE $LOCAL_IP - also running udhcpd"
|
||||
|
||||
ps -wlT
|
||||
ps -ef
|
||||
netstat -lnp
|
||||
cat /proc/mounts
|
||||
sync
|
||||
|
||||
# Run command injection loop = can be exited via 'continue'
|
||||
inject_loop
|
Loading…
Add table
Add a link
Reference in a new issue