slitaz-arm view rpi/piboot @ rev 199
tazbian, piboot: misc fixes
author | Pascal Bellard <pascal.bellard@slitaz.org> |
---|---|
date | Tue Nov 18 10:50:30 2014 +0100 (2014-11-18) |
parents | 635fc61b4e63 |
children | ad63b28ec484 |
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 --menu "${subtitle:-Default boot in $timeout seconds}" 20 72 14 \
241 $(list_entry) $(web_boot_entry) \
242 Continue "${msgkexec:-Execute SliTaz boot sequence}"
243 EOT
244 )
245 retval=$?
246 exec 3>&-
248 n=0
249 while true; do
250 n=$(($n+1))
251 eval KEYWORD="\$KEYWORD_$n"
252 [ "$KEYWORD" ] || break
253 [ "$KEYWORD" == "$value" ] && break
254 case $value in
255 *timeout) [ "$KEYWORD" == "$default" ] && break ;;
256 esac
257 done
259 case $retval in
260 0)
261 case "$value" in
262 *WebBoot) web_boot ;;
263 *) break ;;
264 esac ;;
265 1|255)
266 case "$value" in
267 *timeout) break ;;
268 esac
269 umount $mnt
270 umount /sys
271 umount /proc
272 poweroff -f ;;
273 3)
274 [ "$KEYWORD" ] && edit_menu $n ;;
275 esac
276 done
279 # Start OS
281 case "$KEYWORD" in
283 ''|Continue)
284 KEXEC= ;;
286 *)
287 eval KERNEL="\$KERNEL_$n"
288 eval INITRD="\$INITRD_$n"
289 eval CMDLINE="\$CMDLINE_$n"
290 eval SAVEDEFAULT="\$SAVEDEFAULT_$n"
292 if [ "$webprefix" ]; then
293 cd /root
294 web_get $webprefix/$KEYWORD/$KERNEL vmlinuz
295 KERNEL=vmlinuz
296 for i in ${INITRD//,/ }; do
297 web_get $webprefix/$KEYWORD/$i rootfs.gz
298 n=$(stat -c %s rootfs.gz)
299 n=$(($n % 4))
300 [ $n -eq 0 ] && continue
301 dd if=/dev/zero bs=1 count=$((4 - $n)) >> rootfs.gz
302 done
303 else
304 cd $mnt/$KEYWORD
305 cp $KERNEL /root
306 for i in ${INITRD//,/ }; do
307 cat $i >> /root/rootfs.gz
308 n=$(stat -c %s /root/rootfs.gz)
309 n=$(($n % 4))
310 [ $n -eq 0 ] && continue
311 dd if=/dev/zero bs=1 count=$((4 - $n)) >> /root/rootfs.gz
312 done
313 cd /root
314 fi
315 if [ -z "$READONLY" ] && [ "$SAVEDEFAULT" ] &&
316 [ -s $mnt/$SAVEDEFAULT/config.txt ]; then
317 cp $mnt/menu.txt /tmp
318 sed -i '/^default/d' /tmp/menu.txt
319 echo "default=$SAVEDEFAULT" >> /tmp/menu.txt
320 mount -o remount,rw $mnt
321 cp /tmp/menu.txt $mnt/menu.txt
322 fi
323 [ "$INITRD" ] && INITRD="--initrd rootfs.gz"
325 kexec -l $(basename $KERNEL) $INITRD --command-line \
326 "$(sed 's| .*||' /proc/cmdline) $CMDLINE" --atags
327 KEXEC="kexec -e" ;;
329 esac
331 umount $mnt
332 umount /sys
333 umount /proc
334 $KEXEC
335 exec /init