slitaz-arm annotate rpi/piboot @ rev 215
tazbian, piboot: add berryboot modules path
author | Pascal Bellard <pascal.bellard@slitaz.org> |
---|---|
date | Fri Jan 27 11:50:44 2017 +0100 (2017-01-27) |
parents | 13ae9c5318cd |
children | 9cc2b9f885de |
rev | line source |
---|---|
pankso@118 | 1 #!/bin/sh |
pankso@118 | 2 # |
pankso@118 | 3 # /sbin/piboot: SliTaz Raspberry Pi bootloader and web boot! |
pankso@118 | 4 # |
pascal@208 | 5 # (C) 2014-2016 SliTaz GNU/Linux - ... |
pankso@118 | 6 # |
pascal@123 | 7 # usage: insert 'rdinit=/sbin/piboot' (if you load an initramfs) |
pascal@123 | 8 # or 'init=/sbin/piboot' in the kernel command line /boot/cmdline.txt |
pascal@123 | 9 # |
pankso@118 | 10 # AUTHORS: Pascal Bellard <pascal.bellard@slitaz.org> |
pankso@118 | 11 # |
pankso@118 | 12 |
pascal@209 | 13 [ -z "$(which dialog)" ] && echo "Please install dialog." && exec /init |
pankso@118 | 14 |
pankso@118 | 15 cmdlinearg() |
pankso@118 | 16 { |
pascal@209 | 17 sed "/$1=/!d;s/.*$1=\([^ ]*\).*/\1/" < /proc/cmdline |
pascal@209 | 18 } |
pascal@209 | 19 |
pascal@209 | 20 cmdvararg() |
pascal@209 | 21 { |
pascal@209 | 22 echo " $CMDLINE" | sed "/ $1=/!d;s/.* $1=\([^ ]*\).*/\1/" |
pankso@118 | 23 } |
pankso@118 | 24 |
pankso@118 | 25 get() |
pankso@118 | 26 { |
pankso@118 | 27 grep -sq ^$1 $2 && sed "/^$1/!d;s/$1[ :=]*//" $2 |
pankso@118 | 28 } |
pankso@118 | 29 |
pankso@118 | 30 list_entry() |
pankso@118 | 31 { |
pankso@118 | 32 n=0 |
pankso@118 | 33 while true ; do |
pankso@118 | 34 n=$(($n+1)) |
pankso@118 | 35 eval KEYWORD="\$KEYWORD_$n" |
pankso@118 | 36 eval ENTRY="\$ENTRY_$n" |
pankso@118 | 37 [ "$KEYWORD" ] || break |
pankso@118 | 38 [ "$KEYWORD" == "$default" ] && ENTRY="$ENTRY (default)" |
pankso@118 | 39 echo -n "$KEYWORD \"$ENTRY\" " |
pankso@118 | 40 done |
pankso@118 | 41 } |
pankso@118 | 42 |
pankso@118 | 43 edit_menu() |
pankso@118 | 44 { |
pankso@118 | 45 while true; do |
pankso@118 | 46 |
pankso@118 | 47 eval KERNEL="\$KERNEL_$1" |
pankso@118 | 48 eval INITRD="\$INITRD_$1" |
pankso@118 | 49 eval CMDLINE="\$CMDLINE_$1" |
pascal@195 | 50 extra="--extra-button --extra-label ${msgsave:-Save}" |
pascal@195 | 51 [ "$READONLY" ] && extra='' |
pankso@118 | 52 |
pankso@118 | 53 exec 3>&1 |
pankso@118 | 54 value=$($DIALOG --clear \ |
pankso@118 | 55 --title "${edittitle:-Edit menu}" \ |
pascal@195 | 56 --ok-label "${msgedit:-Edit}" \ |
pascal@195 | 57 --cancel-label "${msgdone:-Done}" \ |
pascal@197 | 58 $extra \ |
pascal@209 | 59 --menu "$msgmenu" 20 72 14 \ |
pankso@118 | 60 Kernel "$KERNEL" \ |
pankso@118 | 61 Initramfs "$INITRD" \ |
pankso@118 | 62 Cmdline "$CMDLINE" 2>&1 1>&3 ) |
pankso@118 | 63 retval=$? |
pankso@118 | 64 exec 3>&- |
pankso@118 | 65 |
pankso@118 | 66 case $retval in |
pankso@118 | 67 1|255) return ;; |
pascal@195 | 68 3) cp $mnt/$KEYWORD/config.txt /tmp/config.txt |
pascal@209 | 69 sed -i '/^kernel\|^initrd/d' /tmp/config.txt |
pascal@195 | 70 echo "kernel=$KERNEL" >> /tmp/config.txt |
pascal@195 | 71 [ "$INITRD" ] && echo "initrd $INITRD" >> /tmp/config.txt |
pascal@195 | 72 mount -o remount,rw $mnt |
pascal@209 | 73 [ "$CMDLINE" ] && echo "$CMDLINE" > $mnt/$KEYWORD/cmdline.txt || |
pascal@209 | 74 rm -f $mnt/$KEYWORD/cmdline.txt |
pascal@195 | 75 cp /tmp/config.txt $mnt/$KEYWORD/config.txt |
pascal@195 | 76 mount -o remount,ro $mnt ;; |
pankso@118 | 77 esac |
pankso@118 | 78 |
pankso@118 | 79 exec 3>&1 |
pankso@118 | 80 case $value in |
pankso@118 | 81 Kernel) |
pascal@195 | 82 data=$($DIALOG --clear --title "${msgselectkernel:-Select the kernel}" \ |
pankso@118 | 83 --fselect "$mnt/$KEYWORD/$KERNEL" 10 72 2>&1 1>&3) ;; |
pankso@118 | 84 Initramfs) |
pascal@195 | 85 data=$($DIALOG --clear --title "${msgselectinitrd:-Select the initramfs}" \ |
pankso@118 | 86 --fselect "$mnt/$KEYWORD/$INITRD" 10 72 2>&1 1>&3) ;; |
pankso@118 | 87 Cmdline) |
pascal@195 | 88 data=$($DIALOG --clear --title "${msgeditcmdline:-Edit cmdline}" \ |
pankso@118 | 89 --inputbox "Cmdline" 20 72 2>&1 "$CMDLINE" 1>&3) ;; |
pankso@118 | 90 esac |
pankso@118 | 91 retval=$? |
pankso@118 | 92 exec 3>&- |
pankso@118 | 93 |
pankso@118 | 94 case $retval in |
pankso@118 | 95 1|255) continue ;; |
pankso@118 | 96 esac |
pankso@118 | 97 |
pankso@118 | 98 case $value in |
pankso@118 | 99 Kernel) [ -f $data ] && eval KERNEL_$1=\$data ;; |
pankso@118 | 100 Initramfs) [ -f $data ] && eval INITRD_$1=\$data ;; |
pankso@118 | 101 Cmdline) eval CMDLINE_$1=\$data ;; |
pankso@118 | 102 esac |
pankso@118 | 103 done |
pankso@118 | 104 } |
pankso@118 | 105 |
pankso@118 | 106 web_boot_entry() |
pankso@118 | 107 { |
pankso@118 | 108 [ "$USING_WEBBOOT" == "1" ] || |
pankso@118 | 109 echo -n 'WebBoot "boot from Internet"' |
pankso@118 | 110 } |
pankso@118 | 111 |
pankso@118 | 112 web_boot() |
pankso@118 | 113 { |
pankso@118 | 114 USING_WEBBOOT=1 |
pankso@118 | 115 [ -s $mnt/network.conf ] && cp $mnt/network.conf /etc |
pankso@118 | 116 /etc/init.d/network.sh start |
pankso@118 | 117 webpath=$(get webpath $mnt/menu.txt) |
pankso@118 | 118 [ "$webpath" ] || webpath=http://mirror.slitaz.org/pxe/arm/boot.php |
pascal@192 | 119 for url in ${webpath//,/ }; do |
pascal@208 | 120 wget -O /root/webboot.sh "$url?mac=$(cat \ |
pascal@208 | 121 /sys/class/net/eth0/address /sys/class/net/*/address \ |
pascal@208 | 122 | sed q)" 2>&1 > /dev/null |
pascal@192 | 123 [ -s /root/webboot.sh ] || continue |
pascal@192 | 124 . /root/webboot.sh |
pascal@192 | 125 webprefix=$(dirname $url) |
pascal@192 | 126 editbutton="" |
pascal@192 | 127 break |
pascal@192 | 128 done |
pankso@118 | 129 } |
pankso@118 | 130 |
pascal@191 | 131 web_get() |
pascal@191 | 132 { |
pascal@209 | 133 if [ -z "$webprefix" ]; then |
pascal@209 | 134 cat $mnt/$1 >> $2 |
pascal@209 | 135 return |
pascal@209 | 136 fi |
pascal@191 | 137 case "$1" in |
pascal@191 | 138 *torrent) # See http://sl-lab.it/dokuwiki/doku.php/tesi:boottorrent_en |
pascal@191 | 139 [ -z "$(which aria2)" ] && |
pascal@191 | 140 echo "Can't find aria2." >> $LOG && |
pascal@191 | 141 exec /init |
pascal@191 | 142 |
pascal@209 | 143 wget -O /root/webboot.torrent "$webprefix/$1" |
pascal@191 | 144 aria2c --enable-dht=false --disable-ipv6=true --seed-time=0 \ |
pascal@191 | 145 --file-allocation=none -j5 /root/webboot.torrent |
pascal@191 | 146 |
pascal@191 | 147 if ls | grep -q rootfs; then |
pascal@191 | 148 file=$(ls | grep -q rootfs) |
pascal@191 | 149 cat $file >> $2 |
pascal@191 | 150 rm -f $file |
pascal@191 | 151 else |
pascal@191 | 152 mv $(ls *mage* *linu* 2> /dev/null) $2 |
pascal@191 | 153 fi |
pascal@191 | 154 rm -f /root/webboot.torrent ;; |
pascal@191 | 155 *) |
pascal@209 | 156 wget -O - "$webprefix/$1" >> $2 |
pascal@191 | 157 esac |
pascal@191 | 158 } |
pascal@191 | 159 |
pankso@118 | 160 : ${DIALOG=dialog} |
pankso@118 | 161 |
pankso@118 | 162 mount -t proc proc /proc |
pascal@191 | 163 mount -t sysfs sys /sys |
pankso@118 | 164 BOOTDEV=$(cmdlinearg bootdev) |
pankso@118 | 165 mnt=/mnt |
pankso@118 | 166 mount -t devtmpfs /dev /dev |
pankso@118 | 167 mount -r /dev/${BOOTDEV:-mmcblk0p1} $mnt |
pankso@118 | 168 umount /dev |
pankso@118 | 169 |
pankso@118 | 170 |
pankso@118 | 171 # Get global variables |
pankso@118 | 172 |
pascal@199 | 173 title="$(get title $mnt/menu.txt)" |
pascal@199 | 174 subtitle="$(get subtitle $mnt/menu.txt)" |
pankso@118 | 175 |
pascal@199 | 176 timeout="$(get timeout $mnt/menu.txt)" |
pascal@199 | 177 timeout="${timeout:-30}" |
pankso@118 | 178 |
pascal@199 | 179 default="$(get default $mnt/menu.txt)" |
pankso@118 | 180 |
pankso@118 | 181 editbutton='--extra-button --extra-label "Edit"' |
pascal@199 | 182 grep -qs ^noedit $mnt/menu.txt && editbutton= |
pankso@118 | 183 |
pascal@195 | 184 READONLY= |
pascal@199 | 185 grep -qs ^readonly $mnt/menu.txt && READONLY=ON |
pascal@195 | 186 |
pascal@195 | 187 USING_WEBBOOT= |
pascal@199 | 188 grep -qs ^nowebboot $mnt/menu.txt && USING_WEBBOOT=1 |
pascal@195 | 189 |
pascal@199 | 190 kmap="$(get kmap $mnt/menu.txt)" |
pankso@118 | 191 [ "$kmap" ] && ! loadkeys $kmap && loadkmap < /usr/share/kmap/$kmap.kmap |
pankso@118 | 192 |
pascal@199 | 193 edittitle="$(get edittitle $mnt/menu.txt)" |
pankso@118 | 194 |
pascal@195 | 195 # Get locale |
pascal@195 | 196 |
pascal@199 | 197 msgsave="$(get msgsave $mnt/menu.txt)" |
pascal@199 | 198 msgedit="$(get msgedit $mnt/menu.txt)" |
pascal@209 | 199 msgmenu="$(get msgmenu $mnt/menu.txt)" |
pascal@199 | 200 msgdone="$(get msgdone $mnt/menu.txt)" |
pascal@199 | 201 msgboot="$(get msgboot $mnt/menu.txt)" |
pascal@199 | 202 msghalt="$(get msghalt $mnt/menu.txt)" |
pascal@199 | 203 msgselectkernel="$(get msgselectkernel $mnt/menu.txt)" |
pascal@199 | 204 msgselectinitrd="$(get msgselectinitrd $mnt/menu.txt)" |
pascal@199 | 205 msgeditcmdline="$(get msgeditcmdline $mnt/menu.txt)" |
pascal@199 | 206 msgkexec="$(get msgkexec $mnt/menu.txt)" |
pankso@118 | 207 |
pankso@118 | 208 # Get OS variables |
pankso@118 | 209 |
pankso@118 | 210 n=0 |
pankso@118 | 211 for i in $mnt/*/ ; do |
pascal@209 | 212 [ -s "$i/menu.txt" ] || continue |
pascal@199 | 213 KERNEL="$(get kernel $i/config.txt)" |
pascal@209 | 214 [ -z "$KERNEL" ] && [ -s "$i/kernel.img" ] && KERNEL="kernel.img" |
pascal@209 | 215 [ -z "$KERNEL" ] && [ -s "$i/cmdline.txt" ] && KERNEL="../kernel.img" |
pankso@118 | 216 n=$(($n+1)) |
pascal@199 | 217 eval KERNEL_$n="\$KERNEL" |
pankso@118 | 218 eval INITRD_$n="\$(get initramfs \$i/config.txt)" |
pascal@209 | 219 eval CMDLINE_$n="\$(cat \$i/cmdline.txt 2> /dev/null)" |
pascal@195 | 220 eval SAVEDEFAULT_$n="\$(get savedefault \$i/config.txt)" |
pankso@118 | 221 eval KEYWORD_$n="\$(basename \$i)" |
pankso@118 | 222 eval ENTRY_$n="\$(get entry \$i/menu.txt)" |
pankso@118 | 223 done |
pankso@118 | 224 |
pankso@118 | 225 |
pankso@118 | 226 # Main loop |
pankso@118 | 227 |
pankso@118 | 228 while true; do |
pankso@118 | 229 |
pankso@118 | 230 exec 3>&1 |
pankso@118 | 231 value=$(sh 2>&1 1>&3 <<EOT |
pankso@118 | 232 $DIALOG --clear \ |
pankso@118 | 233 --title "${title:-Boot menu}" \ |
pankso@118 | 234 $editbutton \ |
pascal@195 | 235 --ok-label "${msgboot:-Boot}" \ |
pascal@195 | 236 --cancel-label "${msghalt:-Halt}" \ |
pankso@118 | 237 --timeout $timeout \ |
pascal@203 | 238 --default-item ${default:-$KEYWORD_1} \ |
pankso@118 | 239 --menu "${subtitle:-Default boot in $timeout seconds}" 20 72 14 \ |
pankso@118 | 240 $(list_entry) $(web_boot_entry) \ |
pascal@195 | 241 Continue "${msgkexec:-Execute SliTaz boot sequence}" |
pankso@118 | 242 EOT |
pankso@118 | 243 ) |
pankso@118 | 244 retval=$? |
pankso@118 | 245 exec 3>&- |
pankso@118 | 246 |
pankso@118 | 247 n=0 |
pankso@118 | 248 while true; do |
pankso@118 | 249 n=$(($n+1)) |
pankso@118 | 250 eval KEYWORD="\$KEYWORD_$n" |
pankso@118 | 251 [ "$KEYWORD" ] || break |
pankso@118 | 252 [ "$KEYWORD" == "$value" ] && break |
pankso@118 | 253 case $value in |
pascal@209 | 254 *timeout) [ "$KEYWORD" == "${default:-$KEYWORD}" ] && break ;; |
pankso@118 | 255 esac |
pankso@118 | 256 done |
pankso@118 | 257 |
pankso@118 | 258 case $retval in |
pankso@118 | 259 0) |
pankso@118 | 260 case "$value" in |
pankso@118 | 261 *WebBoot) web_boot ;; |
pankso@118 | 262 *) break ;; |
pankso@118 | 263 esac ;; |
pankso@118 | 264 1|255) |
pankso@118 | 265 case "$value" in |
pankso@118 | 266 *timeout) break ;; |
pankso@118 | 267 esac |
pankso@118 | 268 umount $mnt |
pascal@191 | 269 umount /sys |
pankso@118 | 270 umount /proc |
pankso@118 | 271 poweroff -f ;; |
pankso@118 | 272 3) |
pankso@118 | 273 [ "$KEYWORD" ] && edit_menu $n ;; |
pankso@118 | 274 esac |
pankso@118 | 275 done |
pankso@118 | 276 |
pankso@118 | 277 |
pankso@118 | 278 # Start OS |
pankso@118 | 279 |
pascal@209 | 280 KEXEC= |
pankso@118 | 281 case "$KEYWORD" in |
pankso@118 | 282 |
pascal@209 | 283 ''|Continue) ;; |
pankso@118 | 284 *) |
pankso@118 | 285 eval KERNEL="\$KERNEL_$n" |
pankso@118 | 286 eval INITRD="\$INITRD_$n" |
pankso@118 | 287 eval CMDLINE="\$CMDLINE_$n" |
pascal@195 | 288 eval SAVEDEFAULT="\$SAVEDEFAULT_$n" |
pankso@118 | 289 |
pascal@208 | 290 grep -qs ARMv6 /proc/cpuinfo || case "$KERNEL" in |
pascal@208 | 291 *BCM*|*7*) ;; |
pascal@208 | 292 *) KERNEL=${KERNEL/.img/7.img} |
pascal@208 | 293 esac |
pascal@208 | 294 |
pascal@195 | 295 if [ -z "$READONLY" ] && [ "$SAVEDEFAULT" ] && |
pascal@195 | 296 [ -s $mnt/$SAVEDEFAULT/config.txt ]; then |
pascal@195 | 297 cp $mnt/menu.txt /tmp |
pascal@195 | 298 sed -i '/^default/d' /tmp/menu.txt |
pascal@195 | 299 echo "default=$SAVEDEFAULT" >> /tmp/menu.txt |
pascal@195 | 300 mount -o remount,rw $mnt |
pascal@195 | 301 cp /tmp/menu.txt $mnt/menu.txt |
pascal@195 | 302 fi |
pankso@118 | 303 |
pascal@211 | 304 [ "$INITRD" ] && ! kexec -u 2> /dev/null && mount -t tmpfs tmpfs /media |
pascal@211 | 305 |
pascal@209 | 306 for i in ${INITRD//,/ }; do |
pascal@211 | 307 echo "Loading $(basename $i)" |
pascal@209 | 308 web_get $KEYWORD/$i /rootfs |
pascal@209 | 309 if ! kexec -u; then |
pascal@211 | 310 ( zcat /rootfs || unlzma < /rootfs ) | \ |
pascal@211 | 311 ( cd /media ; cpio -idmu ) |
pascal@209 | 312 rm -f /rootfs |
pascal@209 | 313 else |
pascal@209 | 314 n=$(stat -c %s /rootfs) |
pascal@209 | 315 n=$(($n % 4)) |
pascal@209 | 316 [ $n -ne 0 ] && |
pascal@209 | 317 dd if=/dev/zero bs=1 count=$((4 - $n)) >> /rootfs |
pascal@209 | 318 fi 2> /dev/null |
pascal@209 | 319 done |
pankso@118 | 320 |
pascal@209 | 321 if ! kexec -u 2> /dev/null; then |
pascal@211 | 322 umount $mnt |
pascal@209 | 323 ROOTDIR=$(cmdvararg "subroot") |
pascal@209 | 324 TMPDIR=$ROOTDIR/dev/shm |
pascal@209 | 325 TMPDIR=${TMPDIR#/} |
pascal@209 | 326 ROOTDEV=$(cmdvararg "root") |
pascal@209 | 327 [ "$ROOTDEV" == "/dev/null" ] && ROOTDEV=$(cmdvararg "mount") |
pascal@209 | 328 K=$(cmdvararg "kmap") |
pascal@209 | 329 [ "$K" ] && echo $K > /etc/keymap.conf |
pascal@209 | 330 L=$(cmdvararg "lang") |
pascal@209 | 331 [ "$L" ] && echo -e "LANG=$L\nLC_ALL=$L" > /etc/locale.conf |
pascal@209 | 332 TZ=$(cmdvararg "tz") |
pascal@209 | 333 [ "$TZ" ] && echo $TZ > /etc/TZ |
pascal@211 | 334 RDINIT=$(cmdvararg "rdinit") |
pascal@211 | 335 INIT=$(cmdvararg "init") |
pascal@211 | 336 INIT=${INIT:-/sbin/init} |
pascal@211 | 337 if [ -z "$ROOTDEV" ] || ! mount $ROOTDEV $mnt; then |
pascal@211 | 338 INIT=${RDINIT:-/init} |
pascal@211 | 339 mnt=/media |
pascal@211 | 340 for i in $(seq 2 5); do |
pascal@211 | 341 mount -r /dev/mmcblk0p$i /tmp || continue |
pascal@211 | 342 echo "Get modules from /dev/mmcblk0p$i" |
pascal@211 | 343 cp -a /tmp/lib/modules /tmp/lib/firmware \ |
pascal@215 | 344 $mnt/$ROOTDIR/lib || |
pascal@215 | 345 cp -a /tmp/shared/lib/modules \ |
pascal@215 | 346 /tmp/shared/lib/firmware \ |
pascal@211 | 347 $mnt/$ROOTDIR/lib |
pascal@211 | 348 umount /tmp |
pascal@211 | 349 break |
pascal@211 | 350 done |
pascal@211 | 351 fi |
pascal@211 | 352 KEXEC="exec /sbin/switch_root $mnt $INIT" |
pascal@211 | 353 if [ "$ROOTDIR" ] && mount -t tmpfs tmpfs $mnt/$TMPDIR ; then |
pascal@209 | 354 CHROOT=/usr/sbin/chroot |
pascal@209 | 355 cp $(LD_TRACE_LOADED_OBJECTS=1 /lib/ld*.so $CHROOT \ |
pascal@209 | 356 | sed 's|.*=> \(/lib/l[^ ]*\).*|\1|;/^\//!d') \ |
pascal@209 | 357 $CHROOT $mnt/$TMPDIR |
pascal@209 | 358 CHROOT="$(cd $mnt ; ls $TMPDIR/ld-*so) $TMPDIR/chroot" |
pascal@209 | 359 export LD_LIBRARY_PATH=/$TMPDIR:/lib |
pascal@211 | 360 KEXEC="exec /sbin/switch_root $mnt $CHROOT $ROOTDIR/ $INIT" |
pascal@209 | 361 fi |
pascal@211 | 362 stat $mnt/$ROOTDIR/$INIT > /dev/null || KEXEC="echo 'No $ROOTDIR/$INIT'" |
pascal@209 | 363 else |
pascal@211 | 364 echo "Loading $(basename $KERNEL)" |
pascal@209 | 365 web_get $KEYWORD/$KERNEL /vmlinuz |
pascal@209 | 366 umount $mnt |
pascal@209 | 367 kexec -l /vmlinuz ${INITRD+=--initrd /rootfs} --command-line \ |
pascal@209 | 368 "$(sed 's| .*||' /proc/cmdline) $CMDLINE" --atags |
pascal@209 | 369 KEXEC="kexec -e" |
pascal@209 | 370 fi ;; |
pankso@118 | 371 esac |
pascal@191 | 372 |
pascal@191 | 373 umount /sys |
pascal@191 | 374 umount /proc |
pascal@191 | 375 $KEXEC |
pascal@191 | 376 exec /init |