blob: e61ede91110abdfd7e1fa7c54991649c416873b4 [file] [log] [blame]
Milton D. Miller II0e775142016-01-20 14:57:54 -06001#!/bin/sh
2
Milton Millerba65b7b2016-02-05 12:07:53 -06003fslist="proc sys dev run"
Milton D. Miller II0e775142016-01-20 14:57:54 -06004rodir=run/initramfs/ro
5rwdir=run/initramfs/rw
6upper=$rwdir/cow
7work=$rwdir/work
8
9cd /
Milton Millerba65b7b2016-02-05 12:07:53 -060010mkdir -p $fslist
Milton D. Miller II0e775142016-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 Jeffery25a50222016-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 IIa81cb932016-03-07 17:46:28 -060047# This fw_get_env_var is a possibly broken version of fw_printenv that
48# does not check the crc or flag byte.
Gunnar Millse5b38602018-08-31 12:39:15 -050049# The u-boot environment starts with a crc32, followed by a flag byte
Milton D. Miller IIab618362016-03-02 15:23:22 -060050# when a redundannt environment is configured, followed by var=value\0 sets.
51# The flag byte for nand is a 1 byte counter; for nor it is a 1 or 0 byte.
Milton D. Miller IIab618362016-03-02 15:23:22 -060052
53get_fw_env_var() {
Milton D. Miller IIa81cb932016-03-07 17:46:28 -060054 # do we have 1 or 2 copies of the environment?
55 # count non-blank non-comment lines
56 # copies=$(grep -v ^# /etc/fw_env.config | grep -c [::alnum::])
57 # ... we could if we had the fw_env.config in the initramfs
Edward A. Jamesfd6f07c2017-08-15 14:18:12 -050058 copies=2
Milton D. Miller IIa81cb932016-03-07 17:46:28 -060059
60 # * Change \n to \r and \0 to \n
61 # * Skip to the 5th byte to skip over crc
62 # * then skip to the first or 2nd byte to skip over flag if it exists
63 # * stop parsing at first empty line corresponding to the
64 # double \0 at the end of the environment.
65 # * print the value of the variable name passed as argument
66
Edward A. Jameseb77a8f2017-07-14 12:32:44 -050067 envdev=$(findmtd u-boot-env)
68 if test -n $envdev
69 then
70 cat /dev/$envdev |
71 tr '\n\000' '\r\n' |
72 tail -c +5 | tail -c +${copies-1} |
73 sed -ne '/^$/,$d' -e "s/^$1=//p"
74 fi
Milton D. Miller IIab618362016-03-02 15:23:22 -060075}
76
Milton D. Miller II71e7ec12016-03-02 18:28:54 -060077setup_resolv() {
78 runresolv=/run/systemd/resolve/resolv.conf
79 etcresolv=/etc/resolv.conf
80
81 if test ! -e $etcresolv -a ! -L $etcresolv
82 then
83 mkdir -p ${runresolv%/*}
84 ln -s $runresolv $etcresolv
85 fi
86 if test ! -f $runresolv
87 then
88 cat /proc/net/pnp > $runresolv
89 fi
90
91 return 0
92}
93
94try_tftp() {
95 # split into tftp:// host:port/ path/on/remote
96 # then spilt off / and then :port from the end of host:port/
97 # and : from the beginning of port
98
99 rest="${1#tftp://}"
100 path=${rest#*/}
101 host=${rest%$path}
102 host="${host%/}"
103 port="${host#${host%:*}}"
104 host="${host%$port}"
105 port="${port#:}"
106
107 setup_resolv
108
109 if test -z "$host" -o -z "$path"
110 then
111 debug_takeover "Invalid tftp download url '$url'."
112 elif echo "Downloading '$url' from $host ..." &&
113 ! tftp -g -r "$path" -l /run/image-rofs "$host" ${port+"$port"}
114 then
115 debug_takeover "Download of '$url' failed."
116 fi
117}
118
119try_wget() {
120 setup_resolv
121
122 echo "Downloading '$1' ..."
123 if ! wget -O /run/image-rofs "$1"
124 then
125 debug_takeover "Download of '$url' failed."
126 fi
127}
128
Milton Miller22509822016-02-05 13:04:29 -0600129debug_takeover() {
130 echo "$@"
Adriana Kobylak7fd01732020-03-12 11:12:59 -0500131
132 if ! grep -w enable-initrd-debug-sh "$optfile"
133 then
134 echo "Fatal error, triggering kernel panic!"
135 exit 1
136 fi
137
138 test -n "$@" && echo Try to manually fix.
Milton Miller22509822016-02-05 13:04:29 -0600139 cat << HERE
140After fixing run exit to continue this script, or reboot -f to retry, or
141touch /takeover and exit to become PID 1 allowing editing of this script.
142HERE
143
Adriana Kobylak7fd01732020-03-12 11:12:59 -0500144 while ! /bin/sh && ! test -f /takeover
Milton Miller22509822016-02-05 13:04:29 -0600145 do
Adriana Kobylak7fd01732020-03-12 11:12:59 -0500146 echo /bin/sh failed, retrying
Milton Miller22509822016-02-05 13:04:29 -0600147 done
148
Adriana Kobylak7fd01732020-03-12 11:12:59 -0500149 # Touch /takeover in the above shell to become pid 1
Milton Miller22509822016-02-05 13:04:29 -0600150 if test -e /takeover
151 then
152 cat << HERE
153
154Takeover of init requested. Executing /bin/sh as PID 1.
155When finished exec new init or cleanup and run reboot -f.
156
157Warning: No job control! Shell exit will panic the system!
158HERE
159 export PS1=init#\
160 exec /bin/sh
161 fi
162}
163
Milton D. Miller II0e775142016-01-20 14:57:54 -0600164rofs=$(findmtd rofs)
165rwfs=$(findmtd rwfs)
166
Milton Millerba65b7b2016-02-05 12:07:53 -0600167rodev=/dev/mtdblock${rofs#mtd}
168rwdev=/dev/mtdblock${rwfs#mtd}
169
Milton Millerec0ba3c2016-02-23 21:48:48 -0600170# Set to y for yes, anything else for no.
171force_rwfst_jffs2=y
172flash_images_before_init=n
Milton D. Miller II71e7ec12016-03-02 18:28:54 -0600173consider_download_files=y
174consider_download_tftp=y
175consider_download_http=y
176consider_download_ftp=y
Milton Millerec0ba3c2016-02-23 21:48:48 -0600177
Milton D. Miller II0e775142016-01-20 14:57:54 -0600178rofst=squashfs
Andrew Jeffery25a50222016-02-23 23:47:23 +1030179rwfst=$(probe_fs_type $rwdev)
Milton Millerba65b7b2016-02-05 12:07:53 -0600180roopts=ro
181rwopts=rw
182
Milton Millerec0ba3c2016-02-23 21:48:48 -0600183image=/run/initramfs/image-
184trigger=${image}rwfs
185
Milton Millerba65b7b2016-02-05 12:07:53 -0600186init=/sbin/init
Milton Millerec0ba3c2016-02-23 21:48:48 -0600187fsckbase=/sbin/fsck.
188fsck=$fsckbase$rwfst
Milton Miller5c212e42016-02-06 16:05:06 -0600189fsckopts=-a
Milton D. Miller II90b68472016-02-27 15:48:52 -0600190optfile=/run/initramfs/init-options
Milton Miller49ce6a12016-05-25 18:52:04 -0500191optbase=/run/initramfs/init-options-base
Milton D. Miller II71e7ec12016-03-02 18:28:54 -0600192urlfile=/run/initramfs/init-download-url
Milton D. Miller II383bfc72016-02-29 11:35:14 -0600193update=/run/initramfs/update
Milton D. Miller II90b68472016-02-27 15:48:52 -0600194
Milton D. Miller II6d854312016-03-07 07:59:09 -0600195if test -e /${optfile##*/}
196then
197 cp /${optfile##*/} $optfile
198fi
199
Milton Miller49ce6a12016-05-25 18:52:04 -0500200if test -e /${optbase##*/}
201then
202 cp /${optbase##*/} $optbase
203else
204 touch $optbase
205fi
206
Milton D. Miller II90b68472016-02-27 15:48:52 -0600207if test ! -f $optfile
208then
Milton Miller49ce6a12016-05-25 18:52:04 -0500209 cat /proc/cmdline $optbase > $optfile
Milton D. Miller IIab618362016-03-02 15:23:22 -0600210 get_fw_env_var openbmcinit >> $optfile
211 get_fw_env_var openbmconce >> $optfile
Milton D. Miller II90b68472016-02-27 15:48:52 -0600212fi
Milton D. Miller II0e775142016-01-20 14:57:54 -0600213
214echo rofs = $rofs $rofst rwfs = $rwfs $rwfst
215
Milton D. Miller II90b68472016-02-27 15:48:52 -0600216if grep -w debug-init-sh $optfile
Milton D. Miller II0e775142016-01-20 14:57:54 -0600217then
Adriana Kobylak7fd01732020-03-12 11:12:59 -0500218 if grep -w enable-initrd-debug-sh "$optfile"
219 then
220 debug_takeover "Debug initial shell requested by command line."
221 else
222 echo "Need to also add enable-initrd-debug-sh for debug shell."
223 fi
Milton D. Miller II0e775142016-01-20 14:57:54 -0600224fi
225
Milton D. Miller II71e7ec12016-03-02 18:28:54 -0600226if test "x$consider_download_files" = xy &&
227 grep -w openbmc-init-download-files $optfile
228then
229 if test -f ${urlfile##*/}
230 then
231 cp ${urlfile##*/} $urlfile
232 fi
233 if test ! -f $urlfile
234 then
235 get_fw_env_var openbmcinitdownloadurl > $urlfile
236 fi
237 url="$(cat $urlfile)"
238 rest="${url#*://}"
239 proto="${url%$rest}"
240
241 if test -z "$url"
242 then
243 echo "Download url empty. Ignoring download request."
244 elif test -z "$proto"
245 then
246 echo "Download failed."
247 elif test "$proto" = tftp://
248 then
249 if test "x$consider_download_tftp" = xy
250 then
251 try_tftp "$url"
252 else
253 echo "Download failed."
254 fi
255 elif test "$proto" = http://
256 then
257 if test "x$consider_download_http" = xy
258 then
259 try_wget "$url"
260 else
261 echo "Download failed."
262 fi
263 elif test "$proto" = ftp://
264 then
265 if test "x$consider_download_ftp" = xy
266 then
267 try_wget "$url"
268 else
269 echo "Download failed."
270 fi
271 else
272 echo "Download failed."
273 fi
274fi
275
Milton D. Miller II21786ff2016-02-27 17:01:13 -0600276# If there are images in root move them to /run/initramfs/ or /run/ now.
Milton Millerec0ba3c2016-02-23 21:48:48 -0600277imagebasename=${image##*/}
Milton D. Miller II21786ff2016-02-27 17:01:13 -0600278if test -n "${imagebasename}" && ls /${imagebasename}* > /dev/null 2>&1
Milton Millerec0ba3c2016-02-23 21:48:48 -0600279then
Milton D. Miller II21786ff2016-02-27 17:01:13 -0600280 if test "x$flash_images_before_init" = xy
281 then
282 echo "Flash images found, will update before starting init."
283 mv /${imagebasename}* ${image%$imagebasename}
284 else
285 echo "Flash images found, will use but deferring flash update."
286 mv /${imagebasename}* /run/
287 fi
Milton Millerec0ba3c2016-02-23 21:48:48 -0600288fi
289
Milton D. Miller II90b68472016-02-27 15:48:52 -0600290if grep -w clean-rwfs-filesystem $optfile
Milton Millerec0ba3c2016-02-23 21:48:48 -0600291then
292 echo "Cleaning of read-write overlay filesystem requested."
293 touch $trigger
294fi
295
Lei YUa08c9962018-07-20 15:11:27 +0800296if grep -w factory-reset $optfile
297then
298 echo "Factory reset requested."
299 touch $trigger
300 do_save=--no-save-files
301else
302 do_save=--save-files
303fi
304
Milton Millerec0ba3c2016-02-23 21:48:48 -0600305if test "x$force_rwfst_jffs2" = xy -a $rwfst != jffs2 -a ! -f $trigger
306then
307 echo "Converting read-write overlay filesystem to jffs2 forced."
308 touch $trigger
309fi
310
311if ls $image* > /dev/null 2>&1
312then
Milton D. Miller II383bfc72016-02-29 11:35:14 -0600313 if ! test -x $update
Milton Millerec0ba3c2016-02-23 21:48:48 -0600314 then
Milton D. Miller II383bfc72016-02-29 11:35:14 -0600315 debug_takeover "Flash update requested but $update missing!"
Milton Millerec0ba3c2016-02-23 21:48:48 -0600316 elif test -f $trigger -a ! -s $trigger
317 then
Lei YUa08c9962018-07-20 15:11:27 +0800318 if [ $do_save = "--save-files" ]
319 then
320 echo "Saving selected files from read-write overlay filesystem."
321 else
322 echo "No files will be selected for save."
323 fi
324 $update --no-restore-files $do_save
Milton Millerec0ba3c2016-02-23 21:48:48 -0600325 echo "Clearing read-write overlay filesystem."
326 flash_eraseall /dev/$rwfs
327 echo "Restoring saved files to read-write overlay filesystem."
328 touch $trigger
Milton D. Miller II383bfc72016-02-29 11:35:14 -0600329 $update --no-save-files --clean-saved-files
Milton Millerec0ba3c2016-02-23 21:48:48 -0600330 else
Lei YUa08c9962018-07-20 15:11:27 +0800331 $update --clean-saved-files $do_save
Milton Millerec0ba3c2016-02-23 21:48:48 -0600332 fi
333
334 rwfst=$(probe_fs_type $rwdev)
335 fsck=$fsckbase$rwfst
336fi
337
Milton D. Miller II5d772b02016-02-27 17:31:39 -0600338if grep -w overlay-filesystem-in-ram $optfile
339then
340 rwfst=none
341fi
342
Milton D. Miller II77be7042016-02-29 12:10:34 -0600343copyfiles=
344if grep -w copy-files-to-ram $optfile
345then
346 rwfst=none
347 copyfiles=y
348fi
349
350# It would be nice to do this after fsck but that mean rofs is mounted
351# which triggers the mtd is mounted check
352if test "$rwfst$copyfiles" = noney
353then
354 touch $trigger
355 $update --copy-files --clean-saved-files --no-restore-files
356fi
357
Milton D. Miller II9ecec172016-02-27 17:31:39 -0600358if grep -w copy-base-filesystem-to-ram $optfile &&
359 test ! -e /run/image-rofs && ! cp $rodev /run/image-rofs
360then
361 # Remove any partial copy to avoid attempted usage later
362 if test -e /run/image-rofs
363 then
364 ls -l /run/image-rofs
365 rm -f /run/image-rofs
366 fi
367 debug_takeover "Copying $rodev to /run/image-rofs failed."
368fi
369
Milton D. Miller IIa8f26b62016-02-27 16:04:32 -0600370if test -s /run/image-rofs
371then
372 rodev=/run/image-rofs
373 roopts=$roopts,loop
374fi
375
Milton Miller5c212e42016-02-06 16:05:06 -0600376mount $rodev $rodir -t $rofst -o $roopts
377
378if test -x $rodir$fsck
379then
380 for fs in $fslist
381 do
382 mount --bind $fs $rodir/$fs
383 done
384 chroot $rodir $fsck $fsckopts $rwdev
385 rc=$?
386 for fs in $fslist
387 do
388 umount $rodir/$fs
389 done
390 if test $rc -gt 1
391 then
392 debug_takeover "fsck of read-write fs on $rwdev failed (rc=$rc)"
393 fi
Milton D. Miller IIed3680d2016-02-27 16:38:16 -0600394elif test "$rwfst" != jffs2 -a "$rwfst" != none
Milton Millere4425842016-02-23 21:00:06 -0600395then
Milton Miller5c212e42016-02-06 16:05:06 -0600396 echo "No '$fsck' in read only fs, skipping fsck."
397fi
398
Milton D. Miller IIed3680d2016-02-27 16:38:16 -0600399if test "$rwfst" = none
400then
401 echo "Running with read-write overlay in RAM for this boot."
402 echo "No state will be preserved unless flash update performed."
403elif ! mount $rwdev $rwdir -t $rwfst -o $rwopts
Milton D. Miller II0e775142016-01-20 14:57:54 -0600404then
Milton Miller22509822016-02-05 13:04:29 -0600405 msg="$(cat)" << HERE
406
407Mounting read-write $rwdev filesystem failed. Please fix and run
Andrew Jefferye4f6d372016-02-17 17:19:58 +1030408 mount $rwdev $rwdir -t $rwfst -o $rwopts
Adriana Kobylak7fd01732020-03-12 11:12:59 -0500409or perform a factory reset with the clean-rwfs-filesystem option.
Milton Miller22509822016-02-05 13:04:29 -0600410HERE
411 debug_takeover "$msg"
Milton D. Miller II0e775142016-01-20 14:57:54 -0600412fi
413
Milton D. Miller II0e775142016-01-20 14:57:54 -0600414rm -rf $work
Milton Miller5c212e42016-02-06 16:05:06 -0600415mkdir -p $upper $work
Milton D. Miller II0e775142016-01-20 14:57:54 -0600416
417mount -t overlay -o lowerdir=$rodir,upperdir=$upper,workdir=$work cow /root
418
Milton Miller22509822016-02-05 13:04:29 -0600419while ! chroot /root /bin/sh -c "test -x '$init' -a -s '$init'"
420do
421 msg="$(cat)" << HERE
422
423Unable to confirm /sbin/init is an executable non-empty file
424in merged file system mounted at /root.
425
Adriana Kobylak7fd01732020-03-12 11:12:59 -0500426Change Root test failed!
Milton Miller22509822016-02-05 13:04:29 -0600427HERE
428 debug_takeover "$msg"
429done
Milton D. Miller II0e775142016-01-20 14:57:54 -0600430
Milton Millerba65b7b2016-02-05 12:07:53 -0600431for f in $fslist
Milton D. Miller II0e775142016-01-20 14:57:54 -0600432do
433 mount --move $f root/$f
434done
435
Milton Millerba65b7b2016-02-05 12:07:53 -0600436# switch_root /root $init
437exec chroot /root $init
Milton D. Miller II0e775142016-01-20 14:57:54 -0600438