slitaz-arm annotate rpi/piboot @ rev 203
piboot: fix default
author | Pascal Bellard <pascal.bellard@slitaz.org> |
---|---|
date | Sun Nov 23 09:30:36 2014 +0100 (2014-11-23) |
parents | e04e276de7ec |
children | 23f85a7e62b1 |
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 # |
pankso@118 | 5 # (C) 2014 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 |
pankso@118 | 13 # Check for depends ... |
pascal@123 | 14 LOG=/var/log/$(basename $0).log |
pascal@199 | 15 mv -f $LOG $LOG.0 2>/dev/null |
pankso@118 | 16 while read file pkg ; do |
pankso@118 | 17 [ "$(which $file)" ] && continue |
pascal@123 | 18 echo "Can't find $file. Please install $pkg." >> $LOG |
pankso@118 | 19 done <<EOT |
pankso@118 | 20 kexec kexec-tools |
pankso@118 | 21 dialog dialog |
pankso@118 | 22 EOT |
pascal@123 | 23 [ -s $LOG ] && exec /init |
pankso@118 | 24 |
pankso@118 | 25 cmdlinearg() |
pankso@118 | 26 { |
pankso@118 | 27 grep -q $1= /proc/cmdline && sed "s/.*$1=\([^ ]*\).*/\1/" </proc/cmdline |
pankso@118 | 28 } |
pankso@118 | 29 |
pankso@118 | 30 get() |
pankso@118 | 31 { |
pankso@118 | 32 grep -sq ^$1 $2 && sed "/^$1/!d;s/$1[ :=]*//" $2 |
pankso@118 | 33 } |
pankso@118 | 34 |
pankso@118 | 35 list_entry() |
pankso@118 | 36 { |
pankso@118 | 37 n=0 |
pankso@118 | 38 while true ; do |
pankso@118 | 39 n=$(($n+1)) |
pankso@118 | 40 eval KEYWORD="\$KEYWORD_$n" |
pankso@118 | 41 eval ENTRY="\$ENTRY_$n" |
pankso@118 | 42 [ "$KEYWORD" ] || break |
pankso@118 | 43 [ "$KEYWORD" == "$default" ] && ENTRY="$ENTRY (default)" |
pankso@118 | 44 echo -n "$KEYWORD \"$ENTRY\" " |
pankso@118 | 45 done |
pankso@118 | 46 } |
pankso@118 | 47 |
pankso@118 | 48 edit_menu() |
pankso@118 | 49 { |
pankso@118 | 50 while true; do |
pankso@118 | 51 |
pankso@118 | 52 eval KERNEL="\$KERNEL_$1" |
pankso@118 | 53 eval INITRD="\$INITRD_$1" |
pankso@118 | 54 eval CMDLINE="\$CMDLINE_$1" |
pascal@195 | 55 extra="--extra-button --extra-label ${msgsave:-Save}" |
pascal@195 | 56 [ "$READONLY" ] && extra='' |
pankso@118 | 57 |
pankso@118 | 58 exec 3>&1 |
pankso@118 | 59 value=$($DIALOG --clear \ |
pankso@118 | 60 --title "${edittitle:-Edit menu}" \ |
pascal@195 | 61 --ok-label "${msgedit:-Edit}" \ |
pascal@195 | 62 --cancel-label "${msgdone:-Done}" \ |
pascal@197 | 63 $extra \ |
pankso@118 | 64 --menu "" 20 72 14 \ |
pankso@118 | 65 Kernel "$KERNEL" \ |
pankso@118 | 66 Initramfs "$INITRD" \ |
pankso@118 | 67 Cmdline "$CMDLINE" 2>&1 1>&3 ) |
pankso@118 | 68 retval=$? |
pankso@118 | 69 exec 3>&- |
pankso@118 | 70 |
pankso@118 | 71 case $retval in |
pankso@118 | 72 1|255) return ;; |
pascal@195 | 73 3) cp $mnt/$KEYWORD/config.txt /tmp/config.txt |
pascal@195 | 74 sed -i '/^kernel/d;/^initrd/d;/^cmdline/d' /tmp/config.txt |
pascal@195 | 75 echo "kernel=$KERNEL" >> /tmp/config.txt |
pascal@195 | 76 [ "$INITRD" ] && echo "initrd $INITRD" >> /tmp/config.txt |
pascal@195 | 77 [ "$CMDLINE" ] && echo "cmdline=$CMDLINE" >> /tmp/config.txt |
pascal@195 | 78 mount -o remount,rw $mnt |
pascal@195 | 79 cp /tmp/config.txt $mnt/$KEYWORD/config.txt |
pascal@195 | 80 mount -o remount,ro $mnt ;; |
pankso@118 | 81 esac |
pankso@118 | 82 |
pankso@118 | 83 exec 3>&1 |
pankso@118 | 84 case $value in |
pankso@118 | 85 Kernel) |
pascal@195 | 86 data=$($DIALOG --clear --title "${msgselectkernel:-Select the kernel}" \ |
pankso@118 | 87 --fselect "$mnt/$KEYWORD/$KERNEL" 10 72 2>&1 1>&3) ;; |
pankso@118 | 88 Initramfs) |
pascal@195 | 89 data=$($DIALOG --clear --title "${msgselectinitrd:-Select the initramfs}" \ |
pankso@118 | 90 --fselect "$mnt/$KEYWORD/$INITRD" 10 72 2>&1 1>&3) ;; |
pankso@118 | 91 Cmdline) |
pascal@195 | 92 data=$($DIALOG --clear --title "${msgeditcmdline:-Edit cmdline}" \ |
pankso@118 | 93 --inputbox "Cmdline" 20 72 2>&1 "$CMDLINE" 1>&3) ;; |
pankso@118 | 94 esac |
pankso@118 | 95 retval=$? |
pankso@118 | 96 exec 3>&- |
pankso@118 | 97 |
pankso@118 | 98 case $retval in |
pankso@118 | 99 1|255) continue ;; |
pankso@118 | 100 esac |
pankso@118 | 101 |
pankso@118 | 102 case $value in |
pankso@118 | 103 Kernel) [ -f $data ] && eval KERNEL_$1=\$data ;; |
pankso@118 | 104 Initramfs) [ -f $data ] && eval INITRD_$1=\$data ;; |
pankso@118 | 105 Cmdline) eval CMDLINE_$1=\$data ;; |
pankso@118 | 106 esac |
pankso@118 | 107 done |
pankso@118 | 108 } |
pankso@118 | 109 |
pankso@118 | 110 web_boot_entry() |
pankso@118 | 111 { |
pankso@118 | 112 [ "$USING_WEBBOOT" == "1" ] || |
pankso@118 | 113 echo -n 'WebBoot "boot from Internet"' |
pankso@118 | 114 } |
pankso@118 | 115 |
pankso@118 | 116 web_boot() |
pankso@118 | 117 { |
pankso@118 | 118 USING_WEBBOOT=1 |
pankso@118 | 119 [ -s $mnt/network.conf ] && cp $mnt/network.conf /etc |
pankso@118 | 120 /etc/init.d/network.sh start |
pankso@118 | 121 webpath=$(get webpath $mnt/menu.txt) |
pankso@118 | 122 [ "$webpath" ] || webpath=http://mirror.slitaz.org/pxe/arm/boot.php |
pascal@192 | 123 for url in ${webpath//,/ }; do |
pascal@192 | 124 wget -O /root/webboot.sh \ |
pascal@199 | 125 "$url?mac=$(cat /sys/class/net/eth0/address)" 2>&1 > /dev/null |
pascal@192 | 126 [ -s /root/webboot.sh ] || continue |
pascal@192 | 127 . /root/webboot.sh |
pascal@192 | 128 webprefix=$(dirname $url) |
pascal@192 | 129 editbutton="" |
pascal@192 | 130 break |
pascal@192 | 131 done |
pankso@118 | 132 } |
pankso@118 | 133 |
pascal@191 | 134 web_get() |
pascal@191 | 135 { |
pascal@191 | 136 case "$1" in |
pascal@191 | 137 *torrent) # See http://sl-lab.it/dokuwiki/doku.php/tesi:boottorrent_en |
pascal@191 | 138 [ -z "$(which aria2)" ] && |
pascal@191 | 139 echo "Can't find aria2." >> $LOG && |
pascal@191 | 140 exec /init |
pascal@191 | 141 |
pascal@199 | 142 wget -O /root/webboot.torrent "$1" |
pascal@191 | 143 aria2c --enable-dht=false --disable-ipv6=true --seed-time=0 \ |
pascal@191 | 144 --file-allocation=none -j5 /root/webboot.torrent |
pascal@191 | 145 |
pascal@191 | 146 if ls | grep -q rootfs; then |
pascal@191 | 147 file=$(ls | grep -q rootfs) |
pascal@191 | 148 cat $file >> $2 |
pascal@191 | 149 rm -f $file |
pascal@191 | 150 else |
pascal@191 | 151 mv $(ls *mage* *linu* 2> /dev/null) $2 |
pascal@191 | 152 fi |
pascal@191 | 153 rm -f /root/webboot.torrent ;; |
pascal@191 | 154 *) |
pascal@199 | 155 wget -O - "$1" >> $2 |
pascal@191 | 156 esac |
pascal@191 | 157 } |
pascal@191 | 158 |
pankso@118 | 159 : ${DIALOG=dialog} |
pankso@118 | 160 |
pankso@118 | 161 mount -t proc proc /proc |
pascal@191 | 162 mount -t sysfs sys /sys |
pankso@118 | 163 BOOTDEV=$(cmdlinearg bootdev) |
pankso@118 | 164 mnt=/mnt |
pankso@118 | 165 mount -t devtmpfs /dev /dev |
pankso@118 | 166 |
pankso@118 | 167 # A dirty hack: why devtmpfs does not mount ? |
pankso@118 | 168 # pankso@20140421: It mount fine on my side |
pankso@118 | 169 [ -b /dev/mmcblk0p1 ] || mknod -m 660 /dev/mmcblk0p1 b 179 1 |
pankso@118 | 170 |
pankso@118 | 171 mount -r /dev/${BOOTDEV:-mmcblk0p1} $mnt |
pankso@118 | 172 umount /dev |
pankso@118 | 173 |
pankso@118 | 174 |
pankso@118 | 175 # Get global variables |
pankso@118 | 176 |
pascal@199 | 177 title="$(get title $mnt/menu.txt)" |
pascal@199 | 178 subtitle="$(get subtitle $mnt/menu.txt)" |
pankso@118 | 179 |
pascal@199 | 180 timeout="$(get timeout $mnt/menu.txt)" |
pascal@199 | 181 timeout="${timeout:-30}" |
pankso@118 | 182 |
pascal@199 | 183 default="$(get default $mnt/menu.txt)" |
pankso@118 | 184 |
pankso@118 | 185 editbutton='--extra-button --extra-label "Edit"' |
pascal@199 | 186 grep -qs ^noedit $mnt/menu.txt && editbutton= |
pankso@118 | 187 |
pascal@195 | 188 READONLY= |
pascal@199 | 189 grep -qs ^readonly $mnt/menu.txt && READONLY=ON |
pascal@195 | 190 |
pascal@195 | 191 USING_WEBBOOT= |
pascal@199 | 192 grep -qs ^nowebboot $mnt/menu.txt && USING_WEBBOOT=1 |
pascal@195 | 193 |
pascal@199 | 194 kmap="$(get kmap $mnt/menu.txt)" |
pankso@118 | 195 [ "$kmap" ] && ! loadkeys $kmap && loadkmap < /usr/share/kmap/$kmap.kmap |
pankso@118 | 196 |
pascal@199 | 197 edittitle="$(get edittitle $mnt/menu.txt)" |
pankso@118 | 198 |
pascal@195 | 199 # Get locale |
pascal@195 | 200 |
pascal@199 | 201 msgsave="$(get msgsave $mnt/menu.txt)" |
pascal@199 | 202 msgedit="$(get msgedit $mnt/menu.txt)" |
pascal@199 | 203 msgdone="$(get msgdone $mnt/menu.txt)" |
pascal@199 | 204 msgboot="$(get msgboot $mnt/menu.txt)" |
pascal@199 | 205 msghalt="$(get msghalt $mnt/menu.txt)" |
pascal@199 | 206 msgselectkernel="$(get msgselectkernel $mnt/menu.txt)" |
pascal@199 | 207 msgselectinitrd="$(get msgselectinitrd $mnt/menu.txt)" |
pascal@199 | 208 msgeditcmdline="$(get msgeditcmdline $mnt/menu.txt)" |
pascal@199 | 209 msgkexec="$(get msgkexec $mnt/menu.txt)" |
pankso@118 | 210 |
pankso@118 | 211 # Get OS variables |
pankso@118 | 212 |
pankso@118 | 213 n=0 |
pankso@118 | 214 for i in $mnt/*/ ; do |
pascal@199 | 215 KERNEL="$(get kernel $i/config.txt)" |
pascal@199 | 216 [ -z "$KERNEL" ] && [ -s $i/kernel.img ] && KERNEL="kernel.img" |
pascal@199 | 217 [ "$KERNEL" ] || continue |
pankso@118 | 218 n=$(($n+1)) |
pascal@199 | 219 eval KERNEL_$n="\$KERNEL" |
pankso@118 | 220 eval INITRD_$n="\$(get initramfs \$i/config.txt)" |
pankso@118 | 221 eval CMDLINE_$n="\$(cat \$i/cmdline.txt)" |
pascal@195 | 222 eval SAVEDEFAULT_$n="\$(get savedefault \$i/config.txt)" |
pankso@118 | 223 eval KEYWORD_$n="\$(basename \$i)" |
pankso@118 | 224 eval ENTRY_$n="\$(get entry \$i/menu.txt)" |
pankso@118 | 225 done |
pankso@118 | 226 |
pankso@118 | 227 |
pankso@118 | 228 # Main loop |
pankso@118 | 229 |
pankso@118 | 230 while true; do |
pankso@118 | 231 |
pankso@118 | 232 exec 3>&1 |
pankso@118 | 233 value=$(sh 2>&1 1>&3 <<EOT |
pankso@118 | 234 $DIALOG --clear \ |
pankso@118 | 235 --title "${title:-Boot menu}" \ |
pankso@118 | 236 $editbutton \ |
pascal@195 | 237 --ok-label "${msgboot:-Boot}" \ |
pascal@195 | 238 --cancel-label "${msghalt:-Halt}" \ |
pankso@118 | 239 --timeout $timeout \ |
pascal@203 | 240 --default-item ${default:-$KEYWORD_1} \ |
pankso@118 | 241 --menu "${subtitle:-Default boot in $timeout seconds}" 20 72 14 \ |
pankso@118 | 242 $(list_entry) $(web_boot_entry) \ |
pascal@195 | 243 Continue "${msgkexec:-Execute SliTaz boot sequence}" |
pankso@118 | 244 EOT |
pankso@118 | 245 ) |
pankso@118 | 246 retval=$? |
pankso@118 | 247 exec 3>&- |
pankso@118 | 248 |
pankso@118 | 249 n=0 |
pankso@118 | 250 while true; do |
pankso@118 | 251 n=$(($n+1)) |
pankso@118 | 252 eval KEYWORD="\$KEYWORD_$n" |
pankso@118 | 253 [ "$KEYWORD" ] || break |
pankso@118 | 254 [ "$KEYWORD" == "$value" ] && break |
pankso@118 | 255 case $value in |
pankso@118 | 256 *timeout) [ "$KEYWORD" == "$default" ] && break ;; |
pankso@118 | 257 esac |
pankso@118 | 258 done |
pankso@118 | 259 |
pankso@118 | 260 case $retval in |
pankso@118 | 261 0) |
pankso@118 | 262 case "$value" in |
pankso@118 | 263 *WebBoot) web_boot ;; |
pankso@118 | 264 *) break ;; |
pankso@118 | 265 esac ;; |
pankso@118 | 266 1|255) |
pankso@118 | 267 case "$value" in |
pankso@118 | 268 *timeout) break ;; |
pankso@118 | 269 esac |
pankso@118 | 270 umount $mnt |
pascal@191 | 271 umount /sys |
pankso@118 | 272 umount /proc |
pankso@118 | 273 poweroff -f ;; |
pankso@118 | 274 3) |
pankso@118 | 275 [ "$KEYWORD" ] && edit_menu $n ;; |
pankso@118 | 276 esac |
pankso@118 | 277 done |
pankso@118 | 278 |
pankso@118 | 279 |
pankso@118 | 280 # Start OS |
pankso@118 | 281 |
pankso@118 | 282 case "$KEYWORD" in |
pankso@118 | 283 |
pankso@118 | 284 ''|Continue) |
pascal@191 | 285 KEXEC= ;; |
pankso@118 | 286 |
pankso@118 | 287 *) |
pankso@118 | 288 eval KERNEL="\$KERNEL_$n" |
pankso@118 | 289 eval INITRD="\$INITRD_$n" |
pankso@118 | 290 eval CMDLINE="\$CMDLINE_$n" |
pascal@195 | 291 eval SAVEDEFAULT="\$SAVEDEFAULT_$n" |
pankso@118 | 292 |
pankso@118 | 293 if [ "$webprefix" ]; then |
pankso@118 | 294 cd /root |
pascal@191 | 295 web_get $webprefix/$KEYWORD/$KERNEL vmlinuz |
pascal@191 | 296 KERNEL=vmlinuz |
pascal@124 | 297 for i in ${INITRD//,/ }; do |
pascal@191 | 298 web_get $webprefix/$KEYWORD/$i rootfs.gz |
pascal@191 | 299 n=$(stat -c %s rootfs.gz) |
pascal@124 | 300 n=$(($n % 4)) |
pascal@124 | 301 [ $n -eq 0 ] && continue |
pascal@191 | 302 dd if=/dev/zero bs=1 count=$((4 - $n)) >> rootfs.gz |
pascal@124 | 303 done |
pankso@118 | 304 else |
pankso@118 | 305 cd $mnt/$KEYWORD |
pascal@124 | 306 cp $KERNEL /root |
pascal@124 | 307 for i in ${INITRD//,/ }; do |
pascal@124 | 308 cat $i >> /root/rootfs.gz |
pascal@124 | 309 n=$(stat -c %s /root/rootfs.gz) |
pascal@124 | 310 n=$(($n % 4)) |
pascal@124 | 311 [ $n -eq 0 ] && continue |
pascal@124 | 312 dd if=/dev/zero bs=1 count=$((4 - $n)) >> /root/rootfs.gz |
pascal@124 | 313 done |
pankso@118 | 314 cd /root |
pankso@118 | 315 fi |
pascal@195 | 316 if [ -z "$READONLY" ] && [ "$SAVEDEFAULT" ] && |
pascal@195 | 317 [ -s $mnt/$SAVEDEFAULT/config.txt ]; then |
pascal@195 | 318 cp $mnt/menu.txt /tmp |
pascal@195 | 319 sed -i '/^default/d' /tmp/menu.txt |
pascal@195 | 320 echo "default=$SAVEDEFAULT" >> /tmp/menu.txt |
pascal@195 | 321 mount -o remount,rw $mnt |
pascal@195 | 322 cp /tmp/menu.txt $mnt/menu.txt |
pascal@195 | 323 fi |
pascal@124 | 324 [ "$INITRD" ] && INITRD="--initrd rootfs.gz" |
pankso@118 | 325 |
pascal@199 | 326 kexec -l $(basename $KERNEL) $INITRD --command-line \ |
pascal@199 | 327 "$(sed 's| .*||' /proc/cmdline) $CMDLINE" --atags |
pascal@191 | 328 KEXEC="kexec -e" ;; |
pankso@118 | 329 |
pankso@118 | 330 esac |
pascal@191 | 331 |
pascal@191 | 332 umount $mnt |
pascal@191 | 333 umount /sys |
pascal@191 | 334 umount /proc |
pascal@191 | 335 $KEXEC |
pascal@191 | 336 exec /init |