2018-06-10 06:03:24 +03:00
|
|
|
{
|
|
|
|
device_name,
|
|
|
|
|
|
|
|
stdenv,
|
|
|
|
makeInitrd,
|
|
|
|
runCommand,
|
|
|
|
writeScript,
|
|
|
|
|
|
|
|
nukeReferences,
|
|
|
|
runCommandCC,
|
|
|
|
busybox,
|
|
|
|
glibc,
|
2018-06-10 21:22:09 +03:00
|
|
|
|
2018-06-11 03:00:03 +03:00
|
|
|
strace,
|
2018-06-10 21:22:09 +03:00
|
|
|
msm-fb-refresher,
|
2018-06-11 03:00:03 +03:00
|
|
|
dropbear,
|
|
|
|
lib,
|
2018-06-10 21:22:09 +03:00
|
|
|
|
2018-06-10 06:03:24 +03:00
|
|
|
...
|
|
|
|
}:
|
|
|
|
|
|
|
|
# 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
|
2018-06-10 21:22:09 +03:00
|
|
|
# Copy msm-fb-refresher
|
|
|
|
for BIN in ${msm-fb-refresher}/{s,}bin/*; do
|
|
|
|
copy_bin_and_libs $BIN
|
|
|
|
done
|
2018-06-11 03:00:03 +03:00
|
|
|
# Copy dropbear
|
|
|
|
for BIN in ${dropbear}/{s,}bin/*; do
|
|
|
|
copy_bin_and_libs $BIN
|
|
|
|
done
|
|
|
|
# Needed for dropbear
|
|
|
|
cp -pv ${glibc.out}/lib/libnss_files.so.* $out/lib
|
|
|
|
# Copy strace
|
|
|
|
for BIN in ${strace}/{s,}bin/*; do
|
|
|
|
copy_bin_and_libs $BIN
|
|
|
|
done
|
2018-06-10 06:03:24 +03:00
|
|
|
# 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
|
2018-06-10 23:22:17 +03:00
|
|
|
|
2018-06-11 03:00:03 +03:00
|
|
|
# Some things will like having /etc/.
|
|
|
|
mkdir -p /etc
|
|
|
|
|
|
|
|
set_framebuffer_mode
|
|
|
|
|
|
|
|
echo 1 > /sys/class/leds/lcd-backlight/brightness
|
|
|
|
|
|
|
|
gzip -c -d /loading.ppm.gz | fbsplash -s -
|
|
|
|
|
|
|
|
msm-fb-refresher --loop &
|
|
|
|
|
2018-06-10 06:03:24 +03:00
|
|
|
ln -sv ${shell} /bin/sh
|
2018-06-10 23:22:17 +03:00
|
|
|
|
2018-06-10 06:03:24 +03:00
|
|
|
loop_forever() {
|
2018-06-10 23:22:17 +03:00
|
|
|
while true; do
|
|
|
|
sleep 3600
|
|
|
|
done
|
2018-06-10 06:03:24 +03:00
|
|
|
}
|
2018-06-10 23:22:17 +03:00
|
|
|
|
2018-06-11 03:00:03 +03:00
|
|
|
# /dev/pts (needed for telnet)
|
|
|
|
mkdir -p /dev/pts
|
|
|
|
mount -t devpts devpts /dev/pts
|
|
|
|
|
|
|
|
|
2018-06-10 23:22:17 +03:00
|
|
|
IP=172.16.42.1
|
2018-06-11 03:00:03 +03:00
|
|
|
TELNET_PORT=23
|
2018-06-10 23:22:17 +03:00
|
|
|
|
|
|
|
setup_usb_network_android() {
|
|
|
|
# Only run, when we have the android usb driver
|
|
|
|
SYS=/sys/class/android_usb/android0
|
|
|
|
[ -e "$SYS" ] || return
|
|
|
|
# Do the setup
|
|
|
|
printf "%s" "0" >"$SYS/enable"
|
|
|
|
printf "%s" "18D1" >"$SYS/idVendor"
|
|
|
|
printf "%s" "D001" >"$SYS/idProduct"
|
|
|
|
printf "%s" "rndis" >"$SYS/functions"
|
|
|
|
printf "%s" "1" >"$SYS/enable"
|
2018-06-10 06:03:24 +03:00
|
|
|
}
|
2018-06-10 23:22:17 +03:00
|
|
|
setup_usb_network_configfs() {
|
|
|
|
CONFIGFS=/config/usb_gadget
|
|
|
|
[ -e "$CONFIGFS" ] || return
|
|
|
|
mkdir $CONFIGFS/g1
|
|
|
|
printf "%s" "18D1" >"$CONFIGFS/g1/idVendor"
|
|
|
|
printf "%s" "D001" >"$CONFIGFS/g1/idProduct"
|
|
|
|
mkdir $CONFIGFS/g1/strings/0x409
|
|
|
|
mkdir $CONFIGFS/g1/functions/rndis.usb0
|
|
|
|
mkdir $CONFIGFS/g1/configs/c.1
|
|
|
|
mkdir $CONFIGFS/g1/configs/c.1/strings/0x409
|
|
|
|
printf "%s" "rndis" > $CONFIGFS/g1/configs/c.1/strings/0x409/configuration
|
|
|
|
ln -s $CONFIGFS/g1/functions/rndis.usb0 $CONFIGFS/g1/configs/c.1
|
|
|
|
# See also: #338
|
|
|
|
# shellcheck disable=SC2005
|
|
|
|
echo "$(ls /sys/class/udc)" > $CONFIGFS/g1/UDC
|
2018-06-10 06:03:24 +03:00
|
|
|
}
|
2018-06-10 23:22:17 +03:00
|
|
|
setup_usb_network() {
|
|
|
|
# Only run once
|
|
|
|
_marker="/tmp/_setup_usb_network"
|
|
|
|
[ -e "$_marker" ] && return
|
|
|
|
touch "$_marker"
|
|
|
|
echo "Setup usb network"
|
|
|
|
# Run all usb network setup functions (add more below!)
|
|
|
|
setup_usb_network_android
|
|
|
|
setup_usb_network_configfs
|
2018-06-10 06:03:24 +03:00
|
|
|
}
|
2018-06-10 23:22:17 +03:00
|
|
|
start_udhcpd() {
|
|
|
|
# Only run once
|
|
|
|
[ -e /etc/udhcpd.conf ] && return
|
2018-06-11 03:00:03 +03:00
|
|
|
|
2018-06-10 23:22:17 +03:00
|
|
|
# Get usb interface
|
|
|
|
INTERFACE=""
|
|
|
|
ifconfig rndis0 "$IP" && INTERFACE=rndis0
|
|
|
|
if [ -z $INTERFACE ]; then
|
|
|
|
ifconfig usb0 "$IP" && INTERFACE=usb0
|
|
|
|
fi
|
|
|
|
if [ -z $INTERFACE ]; then
|
|
|
|
ifconfig eth0 "$IP" && INTERFACE=eth0
|
|
|
|
fi
|
|
|
|
# Create /etc/udhcpd.conf
|
|
|
|
{
|
|
|
|
echo "start 172.16.42.2"
|
|
|
|
echo "end 172.16.42.2"
|
|
|
|
echo "auto_time 0"
|
|
|
|
echo "decline_time 0"
|
|
|
|
echo "conflict_time 0"
|
|
|
|
echo "lease_file /var/udhcpd.leases"
|
|
|
|
echo "interface $INTERFACE"
|
|
|
|
echo "option subnet 255.255.255.0"
|
|
|
|
} >/etc/udhcpd.conf
|
|
|
|
echo "Start the dhcpcd daemon (forks into background)"
|
|
|
|
udhcpd
|
2018-06-10 06:03:24 +03:00
|
|
|
}
|
2018-06-10 21:22:09 +03:00
|
|
|
|
2018-06-11 03:00:03 +03:00
|
|
|
# Hack~ish
|
|
|
|
echo -e '#!/bin/sh\necho b > /proc/sysrq-trigger' > /bin/reboot
|
|
|
|
chmod +x /bin/reboot
|
|
|
|
|
2018-06-10 23:22:17 +03:00
|
|
|
setup_usb_network
|
|
|
|
start_udhcpd
|
|
|
|
|
2018-06-11 03:00:03 +03:00
|
|
|
#sleep 5
|
|
|
|
|
|
|
|
#
|
|
|
|
# Oh boy, that's insecure!
|
|
|
|
#
|
|
|
|
echo '${shell}' > /etc/shells
|
|
|
|
echo 'root:x:0:0:root:/root:${shell}' > /etc/passwd
|
|
|
|
echo 'passwd: files' > /etc/nsswitch.conf
|
|
|
|
passwd -u root
|
|
|
|
passwd -d root
|
|
|
|
mkdir -p /root/.ssh
|
|
|
|
mkdir -p /etc/dropbear/
|
|
|
|
echo "From a mobile-nixos device ${device_name}" >> /etc/banner
|
|
|
|
|
|
|
|
mkdir -p /var/log
|
|
|
|
touch /var/log/lastlog
|
|
|
|
|
|
|
|
# This is the "everything is going wrong" way to debug.
|
|
|
|
# # ---- START nc
|
|
|
|
# # THIS IS HIGHLY INSECURE
|
|
|
|
# nc -lk -p 2323 -e ${shell} &
|
|
|
|
# # ---- END nc
|
|
|
|
|
|
|
|
# telnetd -p ''${TELNET_PORT} -l ${shell} &
|
|
|
|
|
|
|
|
# THIS IS HIGHLY INSECURE
|
|
|
|
# This allows blank login passwords.
|
|
|
|
LD_LIBRARY_PATH=$(echo /nix/store/*extra-utils/lib) \
|
|
|
|
dropbear -ERB -b /etc/banner
|
|
|
|
|
2018-06-10 21:22:09 +03:00
|
|
|
set_framebuffer_mode() {
|
|
|
|
[ -e "/sys/class/graphics/fb0/modes" ] || return
|
|
|
|
[ -z "$(cat /sys/class/graphics/fb0/mode)" ] || return
|
2018-06-10 23:22:17 +03:00
|
|
|
|
2018-06-10 21:22:09 +03:00
|
|
|
_mode="$(cat /sys/class/graphics/fb0/modes)"
|
|
|
|
echo "Setting framebuffer mode to: $_mode"
|
|
|
|
echo "$_mode" > /sys/class/graphics/fb0/mode
|
|
|
|
}
|
|
|
|
|
|
|
|
gzip -c -d /splash.ppm.gz | fbsplash -s -
|
|
|
|
|
2018-06-10 23:22:17 +03:00
|
|
|
loop_forever
|
2018-06-10 06:03:24 +03:00
|
|
|
'';
|
|
|
|
ramdisk = makeInitrd {
|
|
|
|
contents = [
|
|
|
|
{ object = stage1; symlink = "/init"; }
|
2018-06-10 21:22:09 +03:00
|
|
|
{ object = ./temp-splash.ppm.gz; symlink = "/splash.ppm.gz"; }
|
2018-06-11 03:00:03 +03:00
|
|
|
{ object = ./loading.ppm.gz; symlink = "/loading.ppm.gz"; }
|
2018-06-10 23:22:17 +03:00
|
|
|
#{ object = ./temp-splash.png; symlink = "/splash.png"; }
|
2018-06-10 06:03:24 +03:00
|
|
|
];
|
|
|
|
};
|
|
|
|
in
|
|
|
|
stdenv.mkDerivation {
|
|
|
|
name = "initrd-${device_name}";
|
|
|
|
src = builtins.filterSource (path: type: false) ./.;
|
|
|
|
unpackPhase = "true";
|
|
|
|
|
|
|
|
installPhase = ''
|
|
|
|
cp ${ramdisk}/initrd $out
|
|
|
|
'';
|
|
|
|
}
|