blob: 4f24246eb69529d2cf3c6b642a2a66af5e9e3293 [file] [log] [blame]
Milton D. Miller IId89d5e02016-01-20 14:57:54 -06001#!/bin/sh
2
Milton Miller54d882e2016-02-05 12:07:53 -06003fslist="proc sys dev run"
Milton D. Miller IId89d5e02016-01-20 14:57:54 -06004rodir=run/initramfs/ro
5rwdir=run/initramfs/rw
6upper=$rwdir/cow
7work=$rwdir/work
8
9cd /
Milton Miller54d882e2016-02-05 12:07:53 -060010mkdir -p $fslist
Milton D. Miller IId89d5e02016-01-20 14:57:54 -060011mount dev dev -tdevtmpfs
12mount sys sys -tsysfs
13mount proc proc -tproc
14if ! grep run proc/mounts
15then
16 mount tmpfs run -t tmpfs -o mode=755,nodev
17fi
18
19mkdir -p $rodir $rwdir
20
21cp -rp init shutdown update whitelist bin sbin usr lib etc var run/initramfs
22
23# To start a interactive shell with job control at this point, run
24# getty 38400 ttyS4
25
26findmtd() {
27 m=$(grep -xl "$1" /sys/class/mtd/*/name)
28 m=${m%/name}
29 m=${m##*/}
30 echo $m
31}
32
Andrew Jefferyacc2c852016-02-23 23:47:23 +103033blkid_fs_type() {
34 # Emulate util-linux's `blkid -s TYPE -o value $1`
35 # Example busybox blkid output:
36 # # blkid /dev/mtdblock5
37 # /dev/mtdblock5: TYPE="squashfs"
38 # Process output to extract TYPE value "squashfs".
39 blkid $1 | sed -e 's/^.*TYPE="//' -e 's/".*$//'
40}
41
42probe_fs_type() {
43 fst=$(blkid_fs_type $1)
44 echo ${fst:=jffs2}
45}
46
Milton D. Miller II04d2aff2016-03-02 15:23:22 -060047# This fw_get_env_var is a simple but slightly broken version of fw_printenv:
48# The u-boot environemnt starts with a crc32, followed by a flag byte
49# when a redundannt environment is configured, followed by var=value\0 sets.
50# The flag byte for nand is a 1 byte counter; for nor it is a 1 or 0 byte.
51# The crc and/or nand flag byte can contain printable characters and be
52# considered part of the first string and parsed as part of the variable
53# name. In addition a variable could have a "\n" embedded in it, this code
54# would split that variable. Ignore for now, the last set var is at the end.
55
56get_fw_env_var() {
57 strings /run/fw_env | sed -ne "s/^$1=//p"
58}
59
Milton D. Miller II9be688c2016-03-02 18:28:54 -060060setup_resolv() {
61 runresolv=/run/systemd/resolve/resolv.conf
62 etcresolv=/etc/resolv.conf
63
64 if test ! -e $etcresolv -a ! -L $etcresolv
65 then
66 mkdir -p ${runresolv%/*}
67 ln -s $runresolv $etcresolv
68 fi
69 if test ! -f $runresolv
70 then
71 cat /proc/net/pnp > $runresolv
72 fi
73
74 return 0
75}
76
77try_tftp() {
78 # split into tftp:// host:port/ path/on/remote
79 # then spilt off / and then :port from the end of host:port/
80 # and : from the beginning of port
81
82 rest="${1#tftp://}"
83 path=${rest#*/}
84 host=${rest%$path}
85 host="${host%/}"
86 port="${host#${host%:*}}"
87 host="${host%$port}"
88 port="${port#:}"
89
90 setup_resolv
91
92 if test -z "$host" -o -z "$path"
93 then
94 debug_takeover "Invalid tftp download url '$url'."
95 elif echo "Downloading '$url' from $host ..." &&
96 ! tftp -g -r "$path" -l /run/image-rofs "$host" ${port+"$port"}
97 then
98 debug_takeover "Download of '$url' failed."
99 fi
100}
101
102try_wget() {
103 setup_resolv
104
105 echo "Downloading '$1' ..."
106 if ! wget -O /run/image-rofs "$1"
107 then
108 debug_takeover "Download of '$url' failed."
109 fi
110}
111
Milton Miller06ccb1a2016-02-05 13:04:29 -0600112debug_takeover() {
113 echo "$@"
114 test -n "$@" && echo Enter password to try to manually fix.
115 cat << HERE
116After fixing run exit to continue this script, or reboot -f to retry, or
117touch /takeover and exit to become PID 1 allowing editing of this script.
118HERE
119
120 while ! sulogin && ! test -f /takeover
121 do
122 echo getty failed, retrying
123 done
124
125 # Touch /takeover in the above getty to become pid 1
126 if test -e /takeover
127 then
128 cat << HERE
129
130Takeover of init requested. Executing /bin/sh as PID 1.
131When finished exec new init or cleanup and run reboot -f.
132
133Warning: No job control! Shell exit will panic the system!
134HERE
135 export PS1=init#\
136 exec /bin/sh
137 fi
138}
139
Milton D. Miller IIbf7bfd42016-01-27 20:18:16 -0600140env=$(findmtd u-boot-env)
141if test -n $env
142then
143 ln -s /dev/$env /run/mtd:u-boot-env
144 cp /run/mtd:u-boot-env /run/fw_env
145fi
146
Milton D. Miller IId89d5e02016-01-20 14:57:54 -0600147rofs=$(findmtd rofs)
148rwfs=$(findmtd rwfs)
149
Milton Miller54d882e2016-02-05 12:07:53 -0600150rodev=/dev/mtdblock${rofs#mtd}
151rwdev=/dev/mtdblock${rwfs#mtd}
152
Milton Miller0b0d5fe2016-02-23 21:48:48 -0600153# Set to y for yes, anything else for no.
154force_rwfst_jffs2=y
155flash_images_before_init=n
Milton D. Miller II9be688c2016-03-02 18:28:54 -0600156consider_download_files=y
157consider_download_tftp=y
158consider_download_http=y
159consider_download_ftp=y
Milton Miller0b0d5fe2016-02-23 21:48:48 -0600160
Milton D. Miller IId89d5e02016-01-20 14:57:54 -0600161rofst=squashfs
Andrew Jefferyacc2c852016-02-23 23:47:23 +1030162rwfst=$(probe_fs_type $rwdev)
Milton Miller54d882e2016-02-05 12:07:53 -0600163roopts=ro
164rwopts=rw
165
Milton Miller0b0d5fe2016-02-23 21:48:48 -0600166image=/run/initramfs/image-
167trigger=${image}rwfs
168
Milton Miller54d882e2016-02-05 12:07:53 -0600169init=/sbin/init
Milton Miller0b0d5fe2016-02-23 21:48:48 -0600170fsckbase=/sbin/fsck.
171fsck=$fsckbase$rwfst
Milton Millerb72114c2016-02-06 16:05:06 -0600172fsckopts=-a
Milton D. Miller II1650db52016-02-27 15:48:52 -0600173optfile=/run/initramfs/init-options
Milton D. Miller II9be688c2016-03-02 18:28:54 -0600174urlfile=/run/initramfs/init-download-url
Milton D. Miller IIdbc11372016-02-29 11:35:14 -0600175update=/run/initramfs/update
Milton D. Miller II1650db52016-02-27 15:48:52 -0600176
Milton D. Miller IId2977202016-03-07 07:59:09 -0600177if test -e /${optfile##*/}
178then
179 cp /${optfile##*/} $optfile
180fi
181
Milton D. Miller II1650db52016-02-27 15:48:52 -0600182if test ! -f $optfile
183then
184 cat /proc/cmdline > $optfile
Milton D. Miller II04d2aff2016-03-02 15:23:22 -0600185 get_fw_env_var openbmcinit >> $optfile
186 get_fw_env_var openbmconce >> $optfile
Milton D. Miller II1650db52016-02-27 15:48:52 -0600187fi
Milton D. Miller IId89d5e02016-01-20 14:57:54 -0600188
189echo rofs = $rofs $rofst rwfs = $rwfs $rwfst
190
Milton D. Miller II1650db52016-02-27 15:48:52 -0600191if grep -w debug-init-sh $optfile
Milton D. Miller IId89d5e02016-01-20 14:57:54 -0600192then
Milton Miller06ccb1a2016-02-05 13:04:29 -0600193 debug_takeover "Debug initial shell requested by command line."
Milton D. Miller IId89d5e02016-01-20 14:57:54 -0600194fi
195
Milton D. Miller II9be688c2016-03-02 18:28:54 -0600196if test "x$consider_download_files" = xy &&
197 grep -w openbmc-init-download-files $optfile
198then
199 if test -f ${urlfile##*/}
200 then
201 cp ${urlfile##*/} $urlfile
202 fi
203 if test ! -f $urlfile
204 then
205 get_fw_env_var openbmcinitdownloadurl > $urlfile
206 fi
207 url="$(cat $urlfile)"
208 rest="${url#*://}"
209 proto="${url%$rest}"
210
211 if test -z "$url"
212 then
213 echo "Download url empty. Ignoring download request."
214 elif test -z "$proto"
215 then
216 echo "Download failed."
217 elif test "$proto" = tftp://
218 then
219 if test "x$consider_download_tftp" = xy
220 then
221 try_tftp "$url"
222 else
223 echo "Download failed."
224 fi
225 elif test "$proto" = http://
226 then
227 if test "x$consider_download_http" = xy
228 then
229 try_wget "$url"
230 else
231 echo "Download failed."
232 fi
233 elif test "$proto" = ftp://
234 then
235 if test "x$consider_download_ftp" = xy
236 then
237 try_wget "$url"
238 else
239 echo "Download failed."
240 fi
241 else
242 echo "Download failed."
243 fi
244fi
245
Milton D. Miller II1aaffe82016-02-27 17:01:13 -0600246# If there are images in root move them to /run/initramfs/ or /run/ now.
Milton Miller0b0d5fe2016-02-23 21:48:48 -0600247imagebasename=${image##*/}
Milton D. Miller II1aaffe82016-02-27 17:01:13 -0600248if test -n "${imagebasename}" && ls /${imagebasename}* > /dev/null 2>&1
Milton Miller0b0d5fe2016-02-23 21:48:48 -0600249then
Milton D. Miller II1aaffe82016-02-27 17:01:13 -0600250 if test "x$flash_images_before_init" = xy
251 then
252 echo "Flash images found, will update before starting init."
253 mv /${imagebasename}* ${image%$imagebasename}
254 else
255 echo "Flash images found, will use but deferring flash update."
256 mv /${imagebasename}* /run/
257 fi
Milton Miller0b0d5fe2016-02-23 21:48:48 -0600258fi
259
Milton D. Miller II1650db52016-02-27 15:48:52 -0600260if grep -w clean-rwfs-filesystem $optfile
Milton Miller0b0d5fe2016-02-23 21:48:48 -0600261then
262 echo "Cleaning of read-write overlay filesystem requested."
263 touch $trigger
264fi
265
266if test "x$force_rwfst_jffs2" = xy -a $rwfst != jffs2 -a ! -f $trigger
267then
268 echo "Converting read-write overlay filesystem to jffs2 forced."
269 touch $trigger
270fi
271
272if ls $image* > /dev/null 2>&1
273then
Milton D. Miller IIdbc11372016-02-29 11:35:14 -0600274 if ! test -x $update
Milton Miller0b0d5fe2016-02-23 21:48:48 -0600275 then
Milton D. Miller IIdbc11372016-02-29 11:35:14 -0600276 debug_takeover "Flash update requested but $update missing!"
Milton Miller0b0d5fe2016-02-23 21:48:48 -0600277 elif test -f $trigger -a ! -s $trigger
278 then
279 echo "Saving selected files from read-write overlay filesystem."
Milton D. Miller IIdbc11372016-02-29 11:35:14 -0600280 $update --no-restore-files
Milton Miller0b0d5fe2016-02-23 21:48:48 -0600281 echo "Clearing read-write overlay filesystem."
282 flash_eraseall /dev/$rwfs
283 echo "Restoring saved files to read-write overlay filesystem."
284 touch $trigger
Milton D. Miller IIdbc11372016-02-29 11:35:14 -0600285 $update --no-save-files --clean-saved-files
Milton Miller0b0d5fe2016-02-23 21:48:48 -0600286 else
Milton D. Miller IIdbc11372016-02-29 11:35:14 -0600287 $update --clean-saved-files
Milton Miller0b0d5fe2016-02-23 21:48:48 -0600288 fi
289
290 rwfst=$(probe_fs_type $rwdev)
291 fsck=$fsckbase$rwfst
292fi
293
Milton D. Miller IIedfd12c2016-02-27 17:31:39 -0600294if grep -w overlay-filesystem-in-ram $optfile
295then
296 rwfst=none
297fi
298
Milton D. Miller II2728b732016-02-29 12:10:34 -0600299copyfiles=
300if grep -w copy-files-to-ram $optfile
301then
302 rwfst=none
303 copyfiles=y
304fi
305
306# It would be nice to do this after fsck but that mean rofs is mounted
307# which triggers the mtd is mounted check
308if test "$rwfst$copyfiles" = noney
309then
310 touch $trigger
311 $update --copy-files --clean-saved-files --no-restore-files
312fi
313
Milton D. Miller IIc201b042016-02-27 17:31:39 -0600314if grep -w copy-base-filesystem-to-ram $optfile &&
315 test ! -e /run/image-rofs && ! cp $rodev /run/image-rofs
316then
317 # Remove any partial copy to avoid attempted usage later
318 if test -e /run/image-rofs
319 then
320 ls -l /run/image-rofs
321 rm -f /run/image-rofs
322 fi
323 debug_takeover "Copying $rodev to /run/image-rofs failed."
324fi
325
Milton D. Miller IIa36e99c2016-02-27 16:04:32 -0600326if test -s /run/image-rofs
327then
328 rodev=/run/image-rofs
329 roopts=$roopts,loop
330fi
331
Milton Millerb72114c2016-02-06 16:05:06 -0600332mount $rodev $rodir -t $rofst -o $roopts
333
334if test -x $rodir$fsck
335then
336 for fs in $fslist
337 do
338 mount --bind $fs $rodir/$fs
339 done
340 chroot $rodir $fsck $fsckopts $rwdev
341 rc=$?
342 for fs in $fslist
343 do
344 umount $rodir/$fs
345 done
346 if test $rc -gt 1
347 then
348 debug_takeover "fsck of read-write fs on $rwdev failed (rc=$rc)"
349 fi
Milton D. Miller II6dba31f2016-02-27 16:38:16 -0600350elif test "$rwfst" != jffs2 -a "$rwfst" != none
Milton Millerf81c1082016-02-23 21:00:06 -0600351then
Milton Millerb72114c2016-02-06 16:05:06 -0600352 echo "No '$fsck' in read only fs, skipping fsck."
353fi
354
Milton D. Miller II6dba31f2016-02-27 16:38:16 -0600355if test "$rwfst" = none
356then
357 echo "Running with read-write overlay in RAM for this boot."
358 echo "No state will be preserved unless flash update performed."
359elif ! mount $rwdev $rwdir -t $rwfst -o $rwopts
Milton D. Miller IId89d5e02016-01-20 14:57:54 -0600360then
Milton Miller06ccb1a2016-02-05 13:04:29 -0600361 msg="$(cat)" << HERE
362
363Mounting read-write $rwdev filesystem failed. Please fix and run
Andrew Jefferyed5fb272016-02-17 17:19:58 +1030364 mount $rwdev $rwdir -t $rwfst -o $rwopts
Milton Miller06ccb1a2016-02-05 13:04:29 -0600365to to continue, or do change nothing to run from RAM for this boot.
366HERE
367 debug_takeover "$msg"
Milton D. Miller IId89d5e02016-01-20 14:57:54 -0600368fi
369
Milton D. Miller IId89d5e02016-01-20 14:57:54 -0600370rm -rf $work
Milton Millerb72114c2016-02-06 16:05:06 -0600371mkdir -p $upper $work
Milton D. Miller IId89d5e02016-01-20 14:57:54 -0600372
373mount -t overlay -o lowerdir=$rodir,upperdir=$upper,workdir=$work cow /root
374
Milton Miller06ccb1a2016-02-05 13:04:29 -0600375while ! chroot /root /bin/sh -c "test -x '$init' -a -s '$init'"
376do
377 msg="$(cat)" << HERE
378
379Unable to confirm /sbin/init is an executable non-empty file
380in merged file system mounted at /root.
381
382Change Root test failed! Invoking emergency shell.
383HERE
384 debug_takeover "$msg"
385done
Milton D. Miller IId89d5e02016-01-20 14:57:54 -0600386
Milton Miller54d882e2016-02-05 12:07:53 -0600387for f in $fslist
Milton D. Miller IId89d5e02016-01-20 14:57:54 -0600388do
389 mount --move $f root/$f
390done
391
Milton Miller54d882e2016-02-05 12:07:53 -0600392# switch_root /root $init
393exec chroot /root $init
Milton D. Miller IId89d5e02016-01-20 14:57:54 -0600394