summaryrefslogtreecommitdiff
path: root/packages/slugos-init/files/boot/kexec
blob: 7c02a14f0466afca0c6e9a54c819b313f353107e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
#!/bin/sh
#
# Loads the specified kernel and kexecs it.

# The access method and path from which to fetch the kernel
# is specified in "$1" and "$2":
#
# flash      /boot/zImage-ixp4xxbe
# nfs        spike:/home/slug/vmlinuz
# wget       http://devserv/kernels/vmlinuzbe
# wget       ftp://ftpserv/pub/zImage
# /dev/sda1  /kernels/zImage-test
# UUID       /kernels/zImage-test
# tftp       server:/pub/kernels/vmlinuz
#
# Command-line options for the new kernel are in "$3".


# In order to use this, you must exec this script from the /linuxrc file.
#
# This sample linuxrc script boots from external disk.  The last line of
# this example (exec /boot/flash) is a fallback; it will not normally be
# executed unless /boot/kexec is missing or damaged.
#--------------------
#  #!/bin/sh
#  sleep=8 exec /boot/kexec /dev/sda1 /boot/zImage-ixp4xxbe \
#  "console=ttyS0,115200n8 root=/dev/sda1 rootfstype=ext3 rw init=/linuxrc"
#  exec /boot/flash
#--------------------
#
# This one boots from flash in the normal fashion, except the kernel is
# loaded using wget.  This is common for kernel debugging.
#--------------------
#  #!/bin/sh
#  exec /boot/kexec wget http://myserver/boot/zImage-ixp4xxbe \
#  "console=ttyS0,115200n8 root=/dev/mtdblock4 rootfstype=jffs2 rw \
#    init=/boot/flash noirqdebug"
#  exec /boot/flash
#--------------------


# Use the standard init path (see /etc/init.d/rcS)
export PATH=/sbin:/bin:/usr/sbin:/usr/bin

# Wait at least a short while for the disks...
if [ ! "$sleep" -gt 0 ] ; then
    sleep=1
fi

# Load the helper functions
. /etc/default/functions
. /etc/default/modulefunctions

# Print a distinctive banner to make it easy to separate the in-flash
# kernel boot from the kexec'd kernel boot when looking at logs, etc.
echo '###########################################################'
echo '######################     KEXEC     ######################'

leds boot system

if [ -n "$1" -a -n "$2" ] ; then

	method="$1"
	shift
	kpath="$1"
	shift
	if [ -n "$1" ] ; then
	    kcmdline="$1"
	    shift
	fi
	kexec_image=
	need_umount=0
	do_kexec=0

	mount -t proc proc /proc

	case "$method" in

	    flash )
		echo "Loading kexec kernel directly from \"$kpath\"..."
		kexec_image="$kpath"
		;;

	    wget )
		if /boot/network ; then
		    echo "mounting tmpfs partition..."
		    if mount -t tmpfs tmpfs /mnt ; then
			need_umount=1
			echo "Loading kexec kernel using wget \"$kpath\"..."
			wget -P /mnt "$kpath"
			t=`basename "$kpath"`
			kexec_image="/mnt/$t"
		    fi
		fi
		;;

	    nfs )
		if /boot/network ; then
		    echo "Loading kexec kernel using nfs \"$kpath\"..."
		    echo "mounting nfs partition..."
		    if mount -o ro,nolock -t nfs `dirname "$kpath"` /mnt ; then
			need_umount=1
			t=`basename "$kpath"`
			kexec_image="/mnt/$t"
		    fi
		fi
		;;

	    /dev/* )
		echo "Loading kexec kernel using disk \"$kpath\"..."
		loaddiskmods
		sleep "$sleep"
		echo "mounting partition \"$method\"..."
		if mount -o ro "$method" /mnt ; then
		    need_umount=1
		    kexec_image="/mnt/$kpath"
		fi
		;;

	    UUID )
		echo "Loading kexec kernel using disk UUID \"$kpath\"..."
		loaddiskmods
		sleep "$sleep"
		if [ -n "$UUID" ] ; then
		echo "mounting partition UUID \"$UUID\"..."
		    if mount -o ro -U "$UUID" /mnt ; then
			need_umount=1
			kexec_image="/mnt/$kpath"
		    fi
		fi
		;;

	    tftp )
		if /boot/network ; then
		    echo "mounting tmpfs partition..."
		    if mount -t tmpfs tmpfs /mnt ; then
			need_umount=1
			t=`basename "$kpath"`
			kexec_image="/mnt/$t"
			echo "Loading kexec kernel using tftp \"$kpath\"..."
			tftp -g -l "$kexec_image" -r "${kpath#*:}" "${kpath%%:*}"
		    fi
		fi
		;;

	    * )
		echo "Unrecognized method: \"$method\""
		;;

	esac

	if [ -n "$kexec_image" -a -f "$kexec_image" ] ; then
	    if kexec -l "$kexec_image" ; then
		do_kexec=1
	    fi
	else
	    echo "Unable to load \"$kexec_image\""
	fi

	if [ $do_kexec -eq 1 -a -n "$kcmdline" ] ; then
	    echo "Attempting to mount /sys (sysfs)..."
	    if mount -t sysfs sysfs /sys ; then
		echo "Setting command line:"
		echo " \"$kcmdline\""
		echo "$kcmdline" > /sys/kernel/kexec_cmdline
		echo "unmounting /sys..."
		umount /sys
	    else
		do_kexec=0
	    fi
	fi

	if [ $need_umount -eq 1 ] ; then
	    echo "unmounting /mnt..."
	    umount /mnt
	fi

	if [ $do_kexec -eq 1 ] ; then
	    echo "Remounting root as read-only..."
	    mount -o remount,ro /
	    echo "Invoking \"kexec -f -e\" ..."
	    kexec -f -e
	    echo "ERROR!"
	    # We should never return here!  At this point, things are not
	    # too well.  Remount the root as rw, and fallback.
	    echo "Remounting root as read-write..."
	    mount -o remount,rw /
	fi
else
	echo "Usage: $0 flash|nfs|wget|UUID|/dev/<partition> <path-or-URL> [cmdline]"
fi

# fallback - use the flash boot
echo "Falling back to flash boot..."
leds beep -f 1000 -r 2
exec /boot/flash

# fallback to the fallback
leds boot system panic
exec <>/dev/console >&0 2>&0
test -x /bin/sh && exec /bin/sh
exit 1