slitaz-arm annotate rpi/piboot @ rev 195
piboot: add savedefault
author | Pascal Bellard <pascal.bellard@slitaz.org> |
---|---|
date | Sun Nov 16 10:42:30 2014 +0100 (2014-11-16) |
parents | e0ff291ac6e2 |
children | 635fc61b4e63 |
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 |
pankso@161 | 15 mv -f $LOG $LOG.0 >/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}" \ |
pankso@118 | 63 --menu "" 20 72 14 \ |
pascal@195 | 64 $extra \ |
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@192 | 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@191 | 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@191 | 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 |
pankso@118 | 177 title=$(get title $mnt/menu.txt) |
pankso@118 | 178 subtitle=$(get subtitle $mnt/menu.txt) |
pankso@118 | 179 |
pankso@118 | 180 timeout=$(get timeout $mnt/menu.txt) |
pankso@118 | 181 timeout=${timeout:-30} |
pankso@118 | 182 |
pankso@118 | 183 default=$(get default $mnt/menu.txt) |
pankso@118 | 184 |
pankso@118 | 185 editbutton='--extra-button --extra-label "Edit"' |
pankso@118 | 186 grep -qs ^noedit i$mnt/menu.txt && editbutton= |
pankso@118 | 187 |
pascal@195 | 188 READONLY= |
pascal@195 | 189 grep -qs ^readonly i$mnt/menu.txt && READONLY=ON |
pascal@195 | 190 |
pascal@195 | 191 USING_WEBBOOT= |
pascal@195 | 192 grep -qs ^nowebboot i$mnt/menu.txt && USING_WEBBOOT=1 |
pascal@195 | 193 |
pankso@118 | 194 kmap=$(get kmap $mnt/menu.txt) |
pankso@118 | 195 [ "$kmap" ] && ! loadkeys $kmap && loadkmap < /usr/share/kmap/$kmap.kmap |
pankso@118 | 196 |
pankso@118 | 197 edittitle=$(get edittitle $mnt/menu.txt) |
pankso@118 | 198 |
pascal@195 | 199 # Get locale |
pascal@195 | 200 |
pascal@195 | 201 msgsave=$(get msgsave $mnt/menu.txt) |
pascal@195 | 202 msgedit=$(get msgedit $mnt/menu.txt) |
pascal@195 | 203 msgdone=$(get msgdone $mnt/menu.txt) |
pascal@195 | 204 msgboot=$(get msgboot $mnt/menu.txt) |
pascal@195 | 205 msghalt=$(get msghalt $mnt/menu.txt) |
pascal@195 | 206 msgselectkernel=$(get msgselectkernel $mnt/menu.txt) |
pascal@195 | 207 msgselectinitrd=$(get msgselectinitrd $mnt/menu.txt) |
pascal@195 | 208 msgeditcmdline=$(get msgeditcmdline $mnt/menu.txt) |
pascal@195 | 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 |
pankso@118 | 215 grep -qs ^kernel $i/config.txt || continue |
pankso@118 | 216 n=$(($n+1)) |
pankso@118 | 217 eval KERNEL_$n="\$(get kernel \$i/config.txt)" |
pankso@118 | 218 eval INITRD_$n="\$(get initramfs \$i/config.txt)" |
pankso@118 | 219 eval CMDLINE_$n="\$(cat \$i/cmdline.txt)" |
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 \ |
pankso@118 | 238 --menu "${subtitle:-Default boot in $timeout seconds}" 20 72 14 \ |
pankso@118 | 239 $(list_entry) $(web_boot_entry) \ |
pascal@195 | 240 Continue "${msgkexec:-Execute SliTaz boot sequence}" |
pankso@118 | 241 EOT |
pankso@118 | 242 ) |
pankso@118 | 243 retval=$? |
pankso@118 | 244 exec 3>&- |
pankso@118 | 245 |
pankso@118 | 246 n=0 |
pankso@118 | 247 while true; do |
pankso@118 | 248 n=$(($n+1)) |
pankso@118 | 249 eval KEYWORD="\$KEYWORD_$n" |
pankso@118 | 250 [ "$KEYWORD" ] || break |
pankso@118 | 251 [ "$KEYWORD" == "$value" ] && break |
pankso@118 | 252 case $value in |
pankso@118 | 253 *timeout) [ "$KEYWORD" == "$default" ] && break ;; |
pankso@118 | 254 esac |
pankso@118 | 255 done |
pankso@118 | 256 |
pankso@118 | 257 case $retval in |
pankso@118 | 258 0) |
pankso@118 | 259 case "$value" in |
pankso@118 | 260 *WebBoot) web_boot ;; |
pankso@118 | 261 *) break ;; |
pankso@118 | 262 esac ;; |
pankso@118 | 263 1|255) |
pankso@118 | 264 case "$value" in |
pankso@118 | 265 *timeout) break ;; |
pankso@118 | 266 esac |
pankso@118 | 267 umount $mnt |
pascal@191 | 268 umount /sys |
pankso@118 | 269 umount /proc |
pankso@118 | 270 poweroff -f ;; |
pankso@118 | 271 3) |
pankso@118 | 272 [ "$KEYWORD" ] && edit_menu $n ;; |
pankso@118 | 273 esac |
pankso@118 | 274 done |
pankso@118 | 275 |
pankso@118 | 276 |
pankso@118 | 277 # Start OS |
pankso@118 | 278 |
pankso@118 | 279 case "$KEYWORD" in |
pankso@118 | 280 |
pankso@118 | 281 ''|Continue) |
pascal@191 | 282 KEXEC= ;; |
pankso@118 | 283 |
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 |
pankso@118 | 290 if [ "$webprefix" ]; then |
pankso@118 | 291 cd /root |
pascal@191 | 292 web_get $webprefix/$KEYWORD/$KERNEL vmlinuz |
pascal@191 | 293 KERNEL=vmlinuz |
pascal@124 | 294 for i in ${INITRD//,/ }; do |
pascal@191 | 295 web_get $webprefix/$KEYWORD/$i rootfs.gz |
pascal@191 | 296 n=$(stat -c %s rootfs.gz) |
pascal@124 | 297 n=$(($n % 4)) |
pascal@124 | 298 [ $n -eq 0 ] && continue |
pascal@191 | 299 dd if=/dev/zero bs=1 count=$((4 - $n)) >> rootfs.gz |
pascal@124 | 300 done |
pankso@118 | 301 else |
pankso@118 | 302 cd $mnt/$KEYWORD |
pascal@124 | 303 cp $KERNEL /root |
pascal@124 | 304 for i in ${INITRD//,/ }; do |
pascal@124 | 305 cat $i >> /root/rootfs.gz |
pascal@124 | 306 n=$(stat -c %s /root/rootfs.gz) |
pascal@124 | 307 n=$(($n % 4)) |
pascal@124 | 308 [ $n -eq 0 ] && continue |
pascal@124 | 309 dd if=/dev/zero bs=1 count=$((4 - $n)) >> /root/rootfs.gz |
pascal@124 | 310 done |
pankso@118 | 311 cd /root |
pankso@118 | 312 fi |
pascal@195 | 313 if [ -z "$READONLY" ] && [ "$SAVEDEFAULT" ] && |
pascal@195 | 314 [ -s $mnt/$SAVEDEFAULT/config.txt ]; then |
pascal@195 | 315 cp $mnt/menu.txt /tmp |
pascal@195 | 316 sed -i '/^default/d' /tmp/menu.txt |
pascal@195 | 317 echo "default=$SAVEDEFAULT" >> /tmp/menu.txt |
pascal@195 | 318 mount -o remount,rw $mnt |
pascal@195 | 319 cp /tmp/menu.txt $mnt/menu.txt |
pascal@195 | 320 fi |
pascal@124 | 321 [ "$INITRD" ] && INITRD="--initrd rootfs.gz" |
pankso@118 | 322 [ "$CMDLINE" ] && CMDLINE="--command-line \"$CMDLINE\"" |
pankso@118 | 323 |
pankso@118 | 324 kexec -l $(basename $KERNEL) $INITRD $CMDLINE --atags |
pascal@191 | 325 KEXEC="kexec -e" ;; |
pankso@118 | 326 |
pankso@118 | 327 esac |
pascal@191 | 328 |
pascal@191 | 329 umount $mnt |
pascal@191 | 330 umount /sys |
pascal@191 | 331 umount /proc |
pascal@191 | 332 $KEXEC |
pascal@191 | 333 exec /init |