blob: c37b3d53d60ae0b009cafac3ac2abd2f19011fc8 [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.
Milton D. Miller IIab618362016-03-02 15:23:22 -060049# The u-boot environemnt starts with a crc32, followed by a flag byte
50# 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
58 copies=1
59
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
67 cat /run/fw_env |
68 tr '\n\000' '\r\n' |
69 tail -c +5 | tail -c +${copies-1} |
70 sed -ne '/^$/,$d' -e "s/^$1=//p"
Milton D. Miller IIab618362016-03-02 15:23:22 -060071}
72
Milton D. Miller II71e7ec12016-03-02 18:28:54 -060073setup_resolv() {
74 runresolv=/run/systemd/resolve/resolv.conf
75 etcresolv=/etc/resolv.conf
76
77 if test ! -e $etcresolv -a ! -L $etcresolv
78 then
79 mkdir -p ${runresolv%/*}
80 ln -s $runresolv $etcresolv
81 fi
82 if test ! -f $runresolv
83 then
84 cat /proc/net/pnp > $runresolv
85 fi
86
87 return 0
88}
89
90try_tftp() {
91 # split into tftp:// host:port/ path/on/remote
92 # then spilt off / and then :port from the end of host:port/
93 # and : from the beginning of port
94
95 rest="${1#tftp://}"
96 path=${rest#*/}
97 host=${rest%$path}
98 host="${host%/}"
99 port="${host#${host%:*}}"
100 host="${host%$port}"
101 port="${port#:}"
102
103 setup_resolv
104
105 if test -z "$host" -o -z "$path"
106 then
107 debug_takeover "Invalid tftp download url '$url'."
108 elif echo "Downloading '$url' from $host ..." &&
109 ! tftp -g -r "$path" -l /run/image-rofs "$host" ${port+"$port"}
110 then
111 debug_takeover "Download of '$url' failed."
112 fi
113}
114
115try_wget() {
116 setup_resolv
117
118 echo "Downloading '$1' ..."
119 if ! wget -O /run/image-rofs "$1"
120 then
121 debug_takeover "Download of '$url' failed."
122 fi
123}
124
Milton Miller22509822016-02-05 13:04:29 -0600125debug_takeover() {
126 echo "$@"
127 test -n "$@" && echo Enter password to try to manually fix.
128 cat << HERE
129After fixing run exit to continue this script, or reboot -f to retry, or
130touch /takeover and exit to become PID 1 allowing editing of this script.
131HERE
132
133 while ! sulogin && ! test -f /takeover
134 do
135 echo getty failed, retrying
136 done
137
138 # Touch /takeover in the above getty to become pid 1
139 if test -e /takeover
140 then
141 cat << HERE
142
143Takeover of init requested. Executing /bin/sh as PID 1.
144When finished exec new init or cleanup and run reboot -f.
145
146Warning: No job control! Shell exit will panic the system!
147HERE
148 export PS1=init#\
149 exec /bin/sh
150 fi
151}
152
Milton D. Miller II8084d742016-01-27 20:18:16 -0600153env=$(findmtd u-boot-env)
154if test -n $env
155then
156 ln -s /dev/$env /run/mtd:u-boot-env
157 cp /run/mtd:u-boot-env /run/fw_env
158fi
159
Milton D. Miller II0e775142016-01-20 14:57:54 -0600160rofs=$(findmtd rofs)
161rwfs=$(findmtd rwfs)
162
Milton Millerba65b7b2016-02-05 12:07:53 -0600163rodev=/dev/mtdblock${rofs#mtd}
164rwdev=/dev/mtdblock${rwfs#mtd}
165
Milton Millerec0ba3c2016-02-23 21:48:48 -0600166# Set to y for yes, anything else for no.
167force_rwfst_jffs2=y
168flash_images_before_init=n
Milton D. Miller II71e7ec12016-03-02 18:28:54 -0600169consider_download_files=y
170consider_download_tftp=y
171consider_download_http=y
172consider_download_ftp=y
Milton Millerec0ba3c2016-02-23 21:48:48 -0600173
Milton D. Miller II0e775142016-01-20 14:57:54 -0600174rofst=squashfs
Andrew Jeffery25a50222016-02-23 23:47:23 +1030175rwfst=$(probe_fs_type $rwdev)
Milton Millerba65b7b2016-02-05 12:07:53 -0600176roopts=ro
177rwopts=rw
178
Milton Millerec0ba3c2016-02-23 21:48:48 -0600179image=/run/initramfs/image-
180trigger=${image}rwfs
181
Milton Millerba65b7b2016-02-05 12:07:53 -0600182init=/sbin/init
Milton Millerec0ba3c2016-02-23 21:48:48 -0600183fsckbase=/sbin/fsck.
184fsck=$fsckbase$rwfst
Milton Miller5c212e42016-02-06 16:05:06 -0600185fsckopts=-a
Milton D. Miller II90b68472016-02-27 15:48:52 -0600186optfile=/run/initramfs/init-options
Milton D. Miller II71e7ec12016-03-02 18:28:54 -0600187urlfile=/run/initramfs/init-download-url
Milton D. Miller II383bfc72016-02-29 11:35:14 -0600188update=/run/initramfs/update
Milton D. Miller II90b68472016-02-27 15:48:52 -0600189
Milton D. Miller II6d854312016-03-07 07:59:09 -0600190if test -e /${optfile##*/}
191then
192 cp /${optfile##*/} $optfile
193fi
194
Milton D. Miller II90b68472016-02-27 15:48:52 -0600195if test ! -f $optfile
196then
197 cat /proc/cmdline > $optfile
Milton D. Miller IIab618362016-03-02 15:23:22 -0600198 get_fw_env_var openbmcinit >> $optfile
199 get_fw_env_var openbmconce >> $optfile
Milton D. Miller II90b68472016-02-27 15:48:52 -0600200fi
Milton D. Miller II0e775142016-01-20 14:57:54 -0600201
202echo rofs = $rofs $rofst rwfs = $rwfs $rwfst
203
Milton D. Miller II90b68472016-02-27 15:48:52 -0600204if grep -w debug-init-sh $optfile
Milton D. Miller II0e775142016-01-20 14:57:54 -0600205then
Milton Miller22509822016-02-05 13:04:29 -0600206 debug_takeover "Debug initial shell requested by command line."
Milton D. Miller II0e775142016-01-20 14:57:54 -0600207fi
208
Milton D. Miller II71e7ec12016-03-02 18:28:54 -0600209if test "x$consider_download_files" = xy &&
210 grep -w openbmc-init-download-files $optfile
211then
212 if test -f ${urlfile##*/}
213 then
214 cp ${urlfile##*/} $urlfile
215 fi
216 if test ! -f $urlfile
217 then
218 get_fw_env_var openbmcinitdownloadurl > $urlfile
219 fi
220 url="$(cat $urlfile)"
221 rest="${url#*://}"
222 proto="${url%$rest}"
223
224 if test -z "$url"
225 then
226 echo "Download url empty. Ignoring download request."
227 elif test -z "$proto"
228 then
229 echo "Download failed."
230 elif test "$proto" = tftp://
231 then
232 if test "x$consider_download_tftp" = xy
233 then
234 try_tftp "$url"
235 else
236 echo "Download failed."
237 fi
238 elif test "$proto" = http://
239 then
240 if test "x$consider_download_http" = xy
241 then
242 try_wget "$url"
243 else
244 echo "Download failed."
245 fi
246 elif test "$proto" = ftp://
247 then
248 if test "x$consider_download_ftp" = xy
249 then
250 try_wget "$url"
251 else
252 echo "Download failed."
253 fi
254 else
255 echo "Download failed."
256 fi
257fi
258
Milton D. Miller II21786ff2016-02-27 17:01:13 -0600259# If there are images in root move them to /run/initramfs/ or /run/ now.
Milton Millerec0ba3c2016-02-23 21:48:48 -0600260imagebasename=${image##*/}
Milton D. Miller II21786ff2016-02-27 17:01:13 -0600261if test -n "${imagebasename}" && ls /${imagebasename}* > /dev/null 2>&1
Milton Millerec0ba3c2016-02-23 21:48:48 -0600262then
Milton D. Miller II21786ff2016-02-27 17:01:13 -0600263 if test "x$flash_images_before_init" = xy
264 then
265 echo "Flash images found, will update before starting init."
266 mv /${imagebasename}* ${image%$imagebasename}
267 else
268 echo "Flash images found, will use but deferring flash update."
269 mv /${imagebasename}* /run/
270 fi
Milton Millerec0ba3c2016-02-23 21:48:48 -0600271fi
272
Milton D. Miller II90b68472016-02-27 15:48:52 -0600273if grep -w clean-rwfs-filesystem $optfile
Milton Millerec0ba3c2016-02-23 21:48:48 -0600274then
275 echo "Cleaning of read-write overlay filesystem requested."
276 touch $trigger
277fi
278
279if test "x$force_rwfst_jffs2" = xy -a $rwfst != jffs2 -a ! -f $trigger
280then
281 echo "Converting read-write overlay filesystem to jffs2 forced."
282 touch $trigger
283fi
284
285if ls $image* > /dev/null 2>&1
286then
Milton D. Miller II383bfc72016-02-29 11:35:14 -0600287 if ! test -x $update
Milton Millerec0ba3c2016-02-23 21:48:48 -0600288 then
Milton D. Miller II383bfc72016-02-29 11:35:14 -0600289 debug_takeover "Flash update requested but $update missing!"
Milton Millerec0ba3c2016-02-23 21:48:48 -0600290 elif test -f $trigger -a ! -s $trigger
291 then
292 echo "Saving selected files from read-write overlay filesystem."
Milton D. Miller II383bfc72016-02-29 11:35:14 -0600293 $update --no-restore-files
Milton Millerec0ba3c2016-02-23 21:48:48 -0600294 echo "Clearing read-write overlay filesystem."
295 flash_eraseall /dev/$rwfs
296 echo "Restoring saved files to read-write overlay filesystem."
297 touch $trigger
Milton D. Miller II383bfc72016-02-29 11:35:14 -0600298 $update --no-save-files --clean-saved-files
Milton Millerec0ba3c2016-02-23 21:48:48 -0600299 else
Milton D. Miller II383bfc72016-02-29 11:35:14 -0600300 $update --clean-saved-files
Milton Millerec0ba3c2016-02-23 21:48:48 -0600301 fi
302
303 rwfst=$(probe_fs_type $rwdev)
304 fsck=$fsckbase$rwfst
305fi
306
Milton D. Miller II5d772b02016-02-27 17:31:39 -0600307if grep -w overlay-filesystem-in-ram $optfile
308then
309 rwfst=none
310fi
311
Milton D. Miller II77be7042016-02-29 12:10:34 -0600312copyfiles=
313if grep -w copy-files-to-ram $optfile
314then
315 rwfst=none
316 copyfiles=y
317fi
318
319# It would be nice to do this after fsck but that mean rofs is mounted
320# which triggers the mtd is mounted check
321if test "$rwfst$copyfiles" = noney
322then
323 touch $trigger
324 $update --copy-files --clean-saved-files --no-restore-files
325fi
326
Milton D. Miller II9ecec172016-02-27 17:31:39 -0600327if grep -w copy-base-filesystem-to-ram $optfile &&
328 test ! -e /run/image-rofs && ! cp $rodev /run/image-rofs
329then
330 # Remove any partial copy to avoid attempted usage later
331 if test -e /run/image-rofs
332 then
333 ls -l /run/image-rofs
334 rm -f /run/image-rofs
335 fi
336 debug_takeover "Copying $rodev to /run/image-rofs failed."
337fi
338
Milton D. Miller IIa8f26b62016-02-27 16:04:32 -0600339if test -s /run/image-rofs
340then
341 rodev=/run/image-rofs
342 roopts=$roopts,loop
343fi
344
Milton Miller5c212e42016-02-06 16:05:06 -0600345mount $rodev $rodir -t $rofst -o $roopts
346
347if test -x $rodir$fsck
348then
349 for fs in $fslist
350 do
351 mount --bind $fs $rodir/$fs
352 done
353 chroot $rodir $fsck $fsckopts $rwdev
354 rc=$?
355 for fs in $fslist
356 do
357 umount $rodir/$fs
358 done
359 if test $rc -gt 1
360 then
361 debug_takeover "fsck of read-write fs on $rwdev failed (rc=$rc)"
362 fi
Milton D. Miller IIed3680d2016-02-27 16:38:16 -0600363elif test "$rwfst" != jffs2 -a "$rwfst" != none
Milton Millere4425842016-02-23 21:00:06 -0600364then
Milton Miller5c212e42016-02-06 16:05:06 -0600365 echo "No '$fsck' in read only fs, skipping fsck."
366fi
367
Milton D. Miller IIed3680d2016-02-27 16:38:16 -0600368if test "$rwfst" = none
369then
370 echo "Running with read-write overlay in RAM for this boot."
371 echo "No state will be preserved unless flash update performed."
372elif ! mount $rwdev $rwdir -t $rwfst -o $rwopts
Milton D. Miller II0e775142016-01-20 14:57:54 -0600373then
Milton Miller22509822016-02-05 13:04:29 -0600374 msg="$(cat)" << HERE
375
376Mounting read-write $rwdev filesystem failed. Please fix and run
Andrew Jefferye4f6d372016-02-17 17:19:58 +1030377 mount $rwdev $rwdir -t $rwfst -o $rwopts
Milton Miller22509822016-02-05 13:04:29 -0600378to to continue, or do change nothing to run from RAM for this boot.
379HERE
380 debug_takeover "$msg"
Milton D. Miller II0e775142016-01-20 14:57:54 -0600381fi
382
Milton D. Miller II0e775142016-01-20 14:57:54 -0600383rm -rf $work
Milton Miller5c212e42016-02-06 16:05:06 -0600384mkdir -p $upper $work
Milton D. Miller II0e775142016-01-20 14:57:54 -0600385
386mount -t overlay -o lowerdir=$rodir,upperdir=$upper,workdir=$work cow /root
387
Milton Miller22509822016-02-05 13:04:29 -0600388while ! chroot /root /bin/sh -c "test -x '$init' -a -s '$init'"
389do
390 msg="$(cat)" << HERE
391
392Unable to confirm /sbin/init is an executable non-empty file
393in merged file system mounted at /root.
394
395Change Root test failed! Invoking emergency shell.
396HERE
397 debug_takeover "$msg"
398done
Milton D. Miller II0e775142016-01-20 14:57:54 -0600399
Milton Millerba65b7b2016-02-05 12:07:53 -0600400for f in $fslist
Milton D. Miller II0e775142016-01-20 14:57:54 -0600401do
402 mount --move $f root/$f
403done
404
Milton Millerba65b7b2016-02-05 12:07:53 -0600405# switch_root /root $init
406exec chroot /root $init
Milton D. Miller II0e775142016-01-20 14:57:54 -0600407