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