1
1
mirror of https://github.com/NixOS/mobile-nixos.git synced 2024-09-11 03:55:23 +03:00

WIP : boots and vibrates the device as expected

This commit is contained in:
Samuel Dionne-Riel 2018-06-10 03:03:24 +00:00
parent f7984ff752
commit 956e4399be
3 changed files with 227 additions and 0 deletions

View File

@ -6,6 +6,18 @@ An overlay for building stuff.
This is a work-in-progress.
WIP notes
---------
```
nix-build bootimg.nix
# Maybe `nix copy ./result --to ssh://another-host`
adb wait-for-device && adb reboot bootloader
fastboot boot result # or full path
# getting adb and fastboot working is left as an exercise to the reader.
```
Goals
-----

49
bootimg.nix Normal file
View File

@ -0,0 +1,49 @@
{
device_name ? "asus-z00t"
}:
with (import ./overlay);
let
# TODO : import this from device description
linux = pkgs."linux_${device_name}";
kernel = "${linux}/Image.gz-dtb";
dt = "${linux}/boot/dt.img";
cmdline = "androidboot.hardware=qcom ehci-hcd.park=3 androidboot.bootdevice=7824900.sdhci lpm_levels.sleep_disabled=1 androidboot.selinux=permissive";
ramdisk = callPackage ./rootfs.nix { inherit device_name; };
base = "0x10000000";
kernel_offset = "0x00008000";
second_offset = "0x00f00000";
ramdisk_offset = "0x02000000";
tags_offset = "0x00000100";
pagesize = "2048";
in
stdenv.mkDerivation {
name = "nixos-mobile_${device_name}_boot.img";
src = builtins.filterSource (path: type: false) ./.;
unpackPhase = "true";
buildInputs = [
mkbootimg
dtbTool
linux
];
installPhase = ''
mkbootimg \
--kernel ${kernel} \
--dt ${dt} \
--ramdisk ${ramdisk} \
--cmdline "${cmdline}" \
--base ${base } \
--kernel_offset ${kernel_offset } \
--second_offset ${second_offset } \
--ramdisk_offset ${ramdisk_offset} \
--tags_offset ${tags_offset } \
--pagesize ${pagesize } \
-o $out
'';
}

166
rootfs.nix Normal file
View File

@ -0,0 +1,166 @@
{
device_name,
stdenv,
makeInitrd,
runCommand,
writeScript,
nukeReferences,
runCommandCC,
busybox,
glibc,
...
}:
# TODO : configurable through receiving device-specific informations.
let
extraUtils = runCommandCC "extra-utils"
{
buildInputs = [ nukeReferences ];
allowedReferences = [ "out" ];
} ''
set +o pipefail
mkdir -p $out/bin $out/lib
ln -s $out/bin $out/sbin
copy_bin_and_libs() {
[ -f "$out/bin/$(basename $1)" ] && rm "$out/bin/$(basename $1)"
cp -pd $1 $out/bin
}
# Copy Busybox
for BIN in ${busybox}/{s,}bin/*; do
copy_bin_and_libs $BIN
done
# Copy ld manually since it isn't detected correctly
cp -pv ${glibc.out}/lib/ld*.so.? $out/lib
# Copy all of the needed libraries
find $out/bin $out/lib -type f | while read BIN; do
echo "Copying libs for executable $BIN"
LDD="$(ldd $BIN)" || continue
LIBS="$(echo "$LDD" | awk '{print $3}' | sed '/^$/d')"
for LIB in $LIBS; do
TGT="$out/lib/$(basename $LIB)"
if [ ! -f "$TGT" ]; then
SRC="$(readlink -e $LIB)"
cp -pdv "$SRC" "$TGT"
fi
done
done
# Strip binaries further than normal.
chmod -R u+w $out
stripDirs "lib bin" "-s"
# Run patchelf to make the programs refer to the copied libraries.
find $out/bin $out/lib -type f | while read i; do
if ! test -L $i; then
nuke-refs -e $out $i
fi
done
find $out/bin -type f | while read i; do
if ! test -L $i; then
echo "patching $i..."
patchelf --set-interpreter $out/lib/ld*.so.? --set-rpath $out/lib $i || true
fi
done
# Make sure that the patchelf'ed binaries still work.
echo "testing patched programs..."
$out/bin/ash -c 'echo hello world' | grep "hello world"
export LD_LIBRARY_PATH=$out/lib
$out/bin/mount --help 2>&1 | grep -q "BusyBox"
'';
shell = "${extraUtils}/bin/ash";
# TODO : make our own rootfs here!
# https://github.com/postmarketOS/pmbootstrap/blob/master/aports/main/postmarketos-mkinitfs-hook-maximum-attention/00-maximum-attention.sh
stage1 = writeScript "stage1" ''
#!${shell}
export PATH=${extraUtils}/bin/
mkdir -p /proc /sys /dev /etc/udev /tmp /run/ /lib/ /mnt/ /var/log /etc/plymouth /bin
mount -t devtmpfs devtmpfs /dev/
mount -t proc proc /proc
mount -t sysfs sysfs /sys
ln -sv ${shell} /bin/sh
#ln -s ''${modules}/lib/modules /lib/modules
#echo /sbin/mdev >/proc/sys/kernel/hotplug
#mdev -s
loop_forever() {
while true; do
sleep 1
done
}
BLINK_INTERVAL=2 # seconds
VIBRATION_DURATION=400 #ms
VIBRATION_INTERVAL=2 #s
find_leds() {
find /sys -name "max_brightness" | xargs -I{} dirname {}
}
find_vibrator() {
echo /sys/class/timed_output/vibrator
}
# blink_leds takes a list of LEDs as parameters,
# it iterates over every LED, and changes their value,
# alternating between max_brightness and 0 every BLINK_INTERVAL
blink_leds() {
state=false # false = off, true=on
while true; do
for led in $@; do
if [ "$state" = true ]; then
cat $led/max_brightness > $led/brightness
else
echo 0 > $led/brightness
fi
echo blinking LED: $led
done
sleep ''${BLINK_INTERVAL}s
if [ "$state" = true ]; then
state=false
else
state=true
fi
done
}
# vibrate_loop vibrates each VIBRATION_INTERVAL for VIBRATION_DURATION
# it takes a timed_device path to the vibrator as $1
vibrate_loop() {
if [ ! -f $1/enable ]; then
return;
fi
while true; do
echo $VIBRATION_DURATION > $1/enable
sleep ''${VIBRATION_INTERVAL}s
done
}
blink_leds $(find_leds) &
vibrate_loop $(find_vibrator) &
sleep 15
'';
ramdisk = makeInitrd {
contents = [
{ object = stage1; symlink = "/init"; }
];
};
in
stdenv.mkDerivation {
name = "initrd-${device_name}";
src = builtins.filterSource (path: type: false) ./.;
unpackPhase = "true";
installPhase = ''
cp ${ramdisk}/initrd $out
'';
}