-
Notifications
You must be signed in to change notification settings - Fork 37
/
init
211 lines (177 loc) · 5 KB
/
init
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
203
204
205
206
207
208
209
#!/bin/sh
PATH=/sbin:/bin:/usr/sbin:/usr/bin
ROOT_MOUNT="/rootfs"
ROOT_IMAGE="rootfs.img"
ROOT_TYPE="ramfs"
MOUNT="/bin/mount"
UMOUNT="/bin/umount"
ISOLINUX=""
ROOT_DISK=""
skip_load_tables="no"
# for debugging
#set -xv
# Copied from initramfs-framework. The core of this script probably should be
# turned into initramfs-framework modules to reduce duplication.
udev_daemon() {
OPTIONS="/sbin/udev/udevd /sbin/udevd /lib/udev/udevd /lib/systemd/systemd-udevd"
for o in $OPTIONS; do
if [ -x "$o" ]; then
echo $o
return 0
fi
done
return 1
}
_UDEV_DAEMON=`udev_daemon`
early_setup() {
mkdir -p /proc
mkdir -p /sys
mount -t proc proc /proc
mount -t sysfs sysfs /sys
mount -t devtmpfs none /dev
# support modular kernel
modprobe isofs 2> /dev/null
mkdir -p /run
mkdir -p /var/run
$_UDEV_DAEMON --daemon
udevadm trigger --action=add
}
acpi_load() {
if [ "$skip_load_tables" = "yes" ]; then
echo "Loading acpi tables deferred"
elif [ -d /sys/firmware/acpi ]; then
echo "Kernel with acpi enabled detected"
if [ -f /usr/bin/acpi-tables-load ]; then
echo "Loading acpi tables"
mount -t configfs configfs /sys/kernel/config
/usr/bin/acpi-tables-load
umount /sys/kernel/config
fi
else
echo "Kernel with SFI detected"
fi
}
read_args() {
[ -z "$CMDLINE" ] && CMDLINE=`cat /proc/cmdline`
for arg in $CMDLINE; do
optarg=`expr "x$arg" : 'x[^=]*=\(.*\)'`
case $arg in
root=*)
ROOT_DEVICE=$optarg ;;
rootimage=*)
ROOT_IMAGE=$optarg ;;
rootfstype=*)
ROOT_TYPE=$optarg
modprobe $ROOT_TYPE 2> /dev/null ;;
rootflags=*)
ROOTFLAGS="-o ${optarg}" ;;
LABEL=*)
label=$optarg ;;
video=*)
video_mode=$arg ;;
vga=*)
vga_mode=$arg ;;
console=*)
if [ -z "${console_params}" ]; then
console_params=$arg
else
console_params="$console_params $arg"
fi ;;
skiptables*)
skip_load_tables="yes" ;;
debugshell*)
if [ -z "$optarg" ]; then
shelltimeout=30
else
shelltimeout=$optarg
fi
esac
done
}
boot_root() {
# Watches the udev event queue, and exits if all current events are handled
udevadm settle --timeout=3
# Kills the current udev running processes, which survived after
# device node creation events were handled, to avoid unexpected behavior
killall -9 "${_UDEV_DAEMON##*/}" 2>/dev/null
# Unmount the remaining filesystems mounted on /run/media
for dir in `awk '/\/run\/media\/.* /{print $2}' /proc/mounts`; do
umount ${dir}
done
# Allow for identification of the real root even after boot
mkdir -p /realroot
mount -n -t ${ROOT_TYPE} ${ROOTFLAGS} ${ROOT_DEVICE} /realroot
# check if init found
if [[ -h /realroot/sbin/init || -f /realroot/sbin/init ]]; then
echo "Init found, booting..."
else
return 1
fi
# copy fstab
if [[ -h /realroot/etc/fstab || -f /realroot/etc/fstab ]]; then
cp /realroot/etc/fstab /etc
# if /boot in fstab mount it now
mount -n /boot || true
mount -n --move /boot /realroot/boot || true
# if /lib/modules in fstab mount it now
mount -n /lib/modules || true
mount -n --move /lib/modules /realroot/lib/modules || true
else
echo "Error: /etc/fstab not found"
return 1
fi
# Move system mounts over to
# the corresponding directories under the real root filesystem.
mount -n --move /proc /realroot/proc
mount -n --move /sys /realroot/sys
mount -n --move /dev /realroot/dev
cd /realroot
# busybox switch_root supports -c option
exec switch_root -c /dev/console /realroot /sbin/init $CMDLINE ||
fatal "Couldn't switch_root, dropping to shell"
}
fatal() {
echo $1 >$CONSOLE
echo >$CONSOLE
exec sh
}
modprobe btrfs
btrfs device scan
early_setup
[ -z "$CONSOLE" ] && CONSOLE="/dev/console"
read_args
acpi_load
echo "Waiting for root device $ROOT_DEVICE"
C=0
found=""
while true
do
for i in `df | grep "$ROOT_DEVICE" | awk '{print $6}' 2>/dev/null`; do
echo "Found device '$i'"
found="yes"
ROOT_DISK="$i"
break
done
# don't wait for more than $shelltimeout seconds, if it's set
if [ -n "$shelltimeout" ]; then
echo -n " " $(( $shelltimeout - $C ))
if [ $C -ge $shelltimeout ]; then
found="no"
break
fi
fi
C=$(( C + 1 ))
sleep 1
if [ -n "$found" ]; then
break
fi
done
if [ "$found" = "yes" ]; then
boot_root
fi
echo "..."
echo "Mounted filesystems"
mount | grep media
echo "Available block devices"
cat /proc/partitions
fatal "Cannot find $ROOT_DEVICE or no /sbin/init present , dropping to a shell "