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:
parent
f7984ff752
commit
956e4399be
12
README.md
12
README.md
@ -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
49
bootimg.nix
Normal 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
166
rootfs.nix
Normal 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
|
||||
'';
|
||||
}
|
Loading…
Reference in New Issue
Block a user