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