-
Notifications
You must be signed in to change notification settings - Fork 15
Expand file tree
/
Copy pathboot.txt
More file actions
125 lines (101 loc) · 4.68 KB
/
boot.txt
File metadata and controls
125 lines (101 loc) · 4.68 KB
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
Booting the system with minibase
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Happy path only. Generic boot sequence for PC-like systems that may
need to load modules, wait for devices and deal with non-persistent
device names in order to locate system partitions.
See Embedded section below for non-initrd boot.
* The kernel loads initrd, starts /init (msh script)
* init starts udevmod in background (using `runwith`) to load modules
* init runs findblk or passblk to find system partitions
* pass/findblk waits for devices to appear if necessary
* passblk prompts for passphrase and sets up disk encryption
* once partitions are located, runwith kills udevmod and exits
* init calls mount on all system partitions
* init execs into switchroot
* switchroot replaces initrd root with the real root
* moves mounts onto the real root
* cleans up initrd
* pivots the root
* switchroot execs into /sbin/system/start (msh script) on the real
root partition
* start sets up basic process environment
* start performs one-time system configuration
* sysctl and related stuff
* hwclock if necessary
* loadkeys, setfonts if necessary
* possibly iptables
* start execs into /sbin/system/super
* super runs as pid 1 for the whole time the system is up
* super (re)spawns all long-running services
* udevmod
* sysklogd
* ifmon
* vtmux
...
* long-running services keep the system running, super respawns
them if necessary
* on SIGTERM/SIGINT/svctl request, super kills all spawned services
and waits for them to terminate
* super execs into /sbin/system/reboot
* reboot syncs, umounts all mounted partitions and calls reboot(2)
* that's all really, this part is not scripted in any way
User session startup sequence
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* vtmux receives a command to start a new session
* vtmux spawns /etc/vts/$name with all fds directed to /dev/ttyN
* $name is a host-specific msh script
* $name changes its credentials (uid, gid, groups, maybe also caps)
* $name execs into appropriate interactive shell (xinit, weston, bash etc)
* vtmux reaps the process once it dies
The /etc/vtmux/$name script itself is a part of host configuration,
replacing the rightmost fields in conventional /etc/passwd and
the 3rd field in /etc/group.
Service startup sequence
~~~~~~~~~~~~~~~~~~~~~~~~
* super spawns /etc/super/$name (msh script)
* $name sets up process environment, uids, gids and so on
* $name execs into the actual service executable
The script itself is a part of host configuration.
Handling errors in pid 1 scripts
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Normally msh aborts on any errors. This is not acceptable when the script
runs as pid 1 since that would cause immediate panic. For this particular
case, msh got `onexit` built-in. The expected usage is always
onexit /path/to/reboot
but having it as an explicit command removes the need to hard-code any paths
into msh. This way, instead of calling exit(), msh execs into reboot, and
the system gets terminated properly.
Another idea considered and rejected was a small wrapper executable what would
"catch" non-zero msh exits and exec into reboot. This would avoid the need to
have a single-use built-in, however it would also prevent msh from running as
pid 1 and using its *other* builtins to set up environment for subsequent
processes. Turns out onexit implementation within msh is much easier than any
workaround not involving msh.
System shutdown and /path/to/reboot
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Initially the path that super exec()ed into was hard-coded. With `onexit`
implemented in msh, the hard-coded path was replaced with an explicit argument
for `super`. This allows somewhat unusual directory layouts like
/sbin/system/reboot without forcing them onto all minibase users.
Having the path to reboot dangling in ps output isn't pretty, so measures were
taken to erase it from argv in `super`.
Embedded systems
~~~~~~~~~~~~~~~~
In case device nodes for system partitions are predictable (because
of device trees for instance) and the kernel is capable of finding
them without userspace help, initrd is not needed and the boot sequence
becomes much simpler.
* The kernel boots, mounts / and spawns /sbin/init (msh script)
* /sbin/init mounts all necessary file systems,
waiting for devices using msh waitfor built-in if necessary.
* sets up basic process environment
* performs one-time system configuration
* sysctl and related stuff
* hwclock if necessary
* loadkeys, setfonts if necessary
* possibly iptables
* finally execs into /sbin/system/super
Once super is running, the system behaves just like in the PC case.
udevmod (if needed at all) is only run as a regular service.
Neither findblk nor passblk are used in this case, all devices are
located using their /dev node names.