slitaz-arm view rpi/piboot @ rev 208

piboot: rpi2 support
author Pascal Bellard <pascal.bellard@slitaz.org>
date Wed Mar 23 10:38:14 2016 +0100 (2016-03-23)
parents ad63b28ec484
children fc34c01e1405
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 # 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 "$url?mac=$(cat \
125 /sys/class/net/eth0/address /sys/class/net/*/address \
126 | sed q)" 2>&1 > /dev/null
127 [ -s /root/webboot.sh ] || continue
128 . /root/webboot.sh
129 webprefix=$(dirname $url)
130 editbutton=""
131 break
132 done
133 }
135 web_get()
136 {
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 "$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 - "$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 msgdone="$(get msgdone $mnt/menu.txt)"
200 msgboot="$(get msgboot $mnt/menu.txt)"
201 msghalt="$(get msghalt $mnt/menu.txt)"
202 msgselectkernel="$(get msgselectkernel $mnt/menu.txt)"
203 msgselectinitrd="$(get msgselectinitrd $mnt/menu.txt)"
204 msgeditcmdline="$(get msgeditcmdline $mnt/menu.txt)"
205 msgkexec="$(get msgkexec $mnt/menu.txt)"
207 # Get OS variables
209 n=0
210 for i in $mnt/*/ ; do
211 KERNEL="$(get kernel $i/config.txt)"
212 [ -z "$KERNEL" ] && [ -s $i/kernel.img ] && KERNEL="kernel.img"
213 [ -z "$KERNEL" ] && [ -s $i/menu.txt ] && KERNEL="../kernel.img"
214 [ "$KERNEL" ] || continue
215 n=$(($n+1))
216 eval KERNEL_$n="\$KERNEL"
217 eval INITRD_$n="\$(get initramfs \$i/config.txt)"
218 eval CMDLINE_$n="\$(cat \$i/cmdline.txt)"
219 eval SAVEDEFAULT_$n="\$(get savedefault \$i/config.txt)"
220 eval KEYWORD_$n="\$(basename \$i)"
221 eval ENTRY_$n="\$(get entry \$i/menu.txt)"
222 done
225 # Main loop
227 while true; do
229 exec 3>&1
230 value=$(sh 2>&1 1>&3 <<EOT
231 $DIALOG --clear \
232 --title "${title:-Boot menu}" \
233 $editbutton \
234 --ok-label "${msgboot:-Boot}" \
235 --cancel-label "${msghalt:-Halt}" \
236 --timeout $timeout \
237 --default-item ${default:-$KEYWORD_1} \
238 --menu "${subtitle:-Default boot in $timeout seconds}" 20 72 14 \
239 $(list_entry) $(web_boot_entry) \
240 Continue "${msgkexec:-Execute SliTaz boot sequence}"
241 EOT
242 )
243 retval=$?
244 exec 3>&-
246 n=0
247 while true; do
248 n=$(($n+1))
249 eval KEYWORD="\$KEYWORD_$n"
250 [ "$KEYWORD" ] || break
251 [ "$KEYWORD" == "$value" ] && break
252 case $value in
253 *timeout) [ "$KEYWORD" == "$default" ] && break ;;
254 esac
255 done
257 case $retval in
258 0)
259 case "$value" in
260 *WebBoot) web_boot ;;
261 *) break ;;
262 esac ;;
263 1|255)
264 case "$value" in
265 *timeout) break ;;
266 esac
267 umount $mnt
268 umount /sys
269 umount /proc
270 poweroff -f ;;
271 3)
272 [ "$KEYWORD" ] && edit_menu $n ;;
273 esac
274 done
277 # Start OS
279 case "$KEYWORD" in
281 ''|Continue)
282 KEXEC= ;;
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 [ "$webprefix" ]; then
296 cd /root
297 web_get $webprefix/$KEYWORD/$KERNEL vmlinuz
298 KERNEL=vmlinuz
299 for i in ${INITRD//,/ }; do
300 web_get $webprefix/$KEYWORD/$i rootfs.gz
301 n=$(stat -c %s rootfs.gz)
302 n=$(($n % 4))
303 [ $n -eq 0 ] && continue
304 dd if=/dev/zero bs=1 count=$((4 - $n)) >> rootfs.gz
305 done
306 else
307 cd $mnt/$KEYWORD
308 cp $KERNEL /root
309 for i in ${INITRD//,/ }; do
310 cat $i >> /root/rootfs.gz
311 n=$(stat -c %s /root/rootfs.gz)
312 n=$(($n % 4))
313 [ $n -eq 0 ] && continue
314 dd if=/dev/zero bs=1 count=$((4 - $n)) >> /root/rootfs.gz
315 done
316 cd /root
317 fi
318 if [ -z "$READONLY" ] && [ "$SAVEDEFAULT" ] &&
319 [ -s $mnt/$SAVEDEFAULT/config.txt ]; then
320 cp $mnt/menu.txt /tmp
321 sed -i '/^default/d' /tmp/menu.txt
322 echo "default=$SAVEDEFAULT" >> /tmp/menu.txt
323 mount -o remount,rw $mnt
324 cp /tmp/menu.txt $mnt/menu.txt
325 fi
326 [ "$INITRD" ] && INITRD="--initrd rootfs.gz"
328 kexec -l $(basename $KERNEL) $INITRD --command-line \
329 "$(sed 's| .*||' /proc/cmdline) $CMDLINE" --atags
330 KEXEC="kexec -e" ;;
332 esac
334 umount $mnt
335 umount /sys
336 umount /proc
337 $KEXEC
338 exec /init