An indepth review of the boot process, including relevant scripts and a boot code summary. The version used for this review was dCore-trusty, release version 20150429, and the 'vmlinuz-trusty' kernel, version 3.16.6. Although there are many similarities between dCore and Tiny Core, this review focuses solely on dCore.
Although primarily related to Tiny Core, The following resources contain excellent material to help understand the boot process:
The boot loader dumps the chosen kernel into RAM and let's it do its thing. Among many other things, it unpacks the specified initial RAM disk and hands control over to the init script on the initrd. This is where we shall begin with our study.
The boot codes are available in the full boot stanza from '/proc/cmdline'.
1 #!/bb/ash 2 /bb/mount proc 3 /bb/grep -qw multivt /proc/cmdline && /bb/sed -i s/^#tty/tty/ /etc/inittab 4 if ! /bb/grep -qw noembed /proc/cmdline; then 5 /bb/mount / -o remount,size=90% 6 /bb/umount proc 7 exec /bb/init 8 fi . ... 16 ...
L1: this script is interpreted by Busybox Ash.
L2: mount '/proc' (virtual file system as by '/etc/fstab')
L3: if the boot-code multivt is set then un-comment all six tty-entries in '/etc/inittab' which will make them available.
The role of this boot-code is very well explained in the respective section in the CoreBook.
L4-8: if the boot-code noembed is not set (which is the usual case) then make the root file system use up 90% of all available RAM, unmount '/proc' and execute '/bb/init' as init-process (process number one).
L9-16: cf. the section on the embed boot-code in the CoreBook.
What the init-process does is governed by '/etc/inittab' whose content is shown below (blank lines skipped).
1 # /etc/inittab: init configuration for busybox init. 2 # Boot-time system configuration/initialization script. 3 # 4 ::sysinit:/etc/init.d/rcS 5 # /bb/getty respawn shell invocations for selected ttys. 6 tty1::respawn:/bb/getty -nl /sbin/autologin 38400 tty1 7 #tty2::respawn:/bb/getty 38400 tty2 8 #tty3::respawn:/bb/getty 38400 tty3 9 #tty4::askfirst:/bb/getty 38400 tty4 10 #tty5::askfirst:/bb/getty 38400 tty5 11 #tty6::askfirst:/bb/getty 38400 tty6 12 # Stuff to do when restarting the init 13 # process, or before rebooting. 14 ::restart:/etc/init.d/rc.shutdown 15 ::restart:/bb/init 16 ::ctrlaltdel:/bb/reboot 17 ::shutdown:/etc/init.d/rc.shutdown
Busybox-Init is quite similar to System-V-Init in its structure. The main difference is that it does only respect '/etc/inittab' and does not use run-levels with their respective directories '/etc/rc#.d'.
L4: after system start it runs '/etc/init.d/rcS'.
L6-11: make the uncommented TTYs available.
L14,15: at a requested restart, run '/etc/init.d/rc.shutdown' (and then afterwards '/bb/init' ?!).
L16: reboot immediately after Ctrl+Alt+Del is hit.
L17: call '/etc/init.d/rc.shutdown' before shutting down.
This script is the first entry point of dCore (blank lines skipped).
1 #!/bb/ash 2 # RC Script for Tiny Core Linux 3 # (c) Robert Shingledecker 2004-2012 . ... 10 /etc/init.d/tc-config
L4-9: make sure '/proc' is mounted, remount '/' in read-write mode and mount system devices already listed in '/etc/fstab' (will be enhanced later).
L10: call '/etc/init.d/tc-config'.
This script stretches out over several hunderd lines of code. We shall dissect it in smaller chunks.
1 #!/bb/ash 2 # RC Script for Tiny Core Linux 3 # (c) Robert Shingledecker 2004-2012 4 # Several modifications for speed by Curaga 5 . /etc/init.d/tc-functions
Check the separate page for an overview of 'tc-functions'. Any external functions referenced will be from that module.
7 PATH="/bb:/bin:/sbin:/usr/bin:/usr/sbin" 8 export PATH 9 USER="tc" 10 TCEDIR="/tmp/tce" 11 TCLOOP="/tmp/tcloop" 12 TCEINSTALLED="/usr/local/tce.installed" 13 INSTALLED="" 14 VERSION="$(cat /usr/share/doc/tc/release.txt)" 15 KERNEL="$(uname -r)"
L17-22: addUser() adds user USER in group “staff” without a password. Then set its password to “tcuser” and give it passwordless sudo-rights.
L26-29: print out nicely colored messages about the start of the system.
L30: prepend “/usr/local/{s}bin” to the PATH-variable
Thus we have the following list of boot-codes and variables with values:
aoe | AOE | base | ONLYBASE=1 |
blacklist | BLACKLIST | checkfs | CHECKFS=1 |
desktop | DESKTOP | cron | CRON=1 |
home | MYHOME | laptop | LAPTOP=1 |
host | HOST=1 | noautologin | NOAUTOLOGIN=1 |
httplist | HTTPLIST | nodhcp | NODHCP=1 |
icons | ICONS | nofstab | NOFSTAB=1 |
iso | ISOFILE | noicons | NOICONS=1 |
kmap | KEYMAP | norestore | NORESTORE=1 |
lang | LANGUAGE | nortc | NORTC=1 |
mydata | MYDATA | noswap | NOSWAP=1 |
nbd | NBD | noutc | NOUTC=1 |
nfsmount | NFSMOUNT | nozswap | NOZSWAP=1 |
noicons | NOICONS | pause | PAUSE=1 |
opt | MYOPT | protect | PROTECT=1 |
pretce | PRETCE | secure | SECURE=1 |
resume | RESUME | showapps | SHOWAPPS=1 |
rsyslog | RSYSLOG | superuser | SUPERUSER=1 |
swapfile | SWAPFILE | syslog | SYSLOG=1 |
tcvd | TCVD | text | TEXT=1 |
tftplist | TFTPLIST | xonly | XONLY=1 |
tz | TZ | xsetup | XSETUP=1 |
user | USER | debug | |
waitusb | WAITUSB | ||
xvesa | XVESA |
Some few boot-codes are treated elsewhere, notably …
Additional boot-codes have been treated by the kernel at boot-time already. One notable case is resume which, although similar in syntax to home, opt and tce does not accept disk LABELs.
copy names of black-listed modules into '/etc/modprobe.d/blacklist.conf' (does not trigger any further action)
start udev daemon for hotplug support
do as requested
modprobe loop and ohci_hcd (a USB-1.1 module ?!)
all commented out
if NOFSTAB is not set then populate '/etc/fstab' with entries for physical partitions and create appropriate mount-points under '/mnt'.
check ext-filesystems (only); it writes its e2fsck-log to '/tmp/checkfs.“$1” and errors to '/tmp/checkfs.errors'. It is only called later (cf. below). A second argument specifies what the file system is used for (e.g. “TCE”) so that error messages can be better attributed.
start 'syslogd' locally and also remotely if RSYSLOG specifies host:port
set and export LANG and write corresponding command into '/etc/sysconfig/language' (does not trigger any further action)
set and export TZ and write corresponding command into '/etc/sysconfig/tz' (does not trigger any further action)
(all commented out): (only) if NORTC was not set then call 'hwclock' (with option for UTC-time or, if NOUTC was set, localtime).
calls '/usr/bin/sethostname' to do its job.
loop-back device with route
(?!)
used to make sure that 'dhcp.sh' does not exit prematurely (?!)
'adduser' of the desired name
simply touches '/etc/sysconfig/superuser' (does not trigger any further action)
Consult the wikipages about netbooting or LVM & RAID for a rather complete discussion.
'get_app()' can down-load files (cf. httplist, tftplist below) (?!)
preload drivers needed for tce/opt/home on lvm/RAID etc. (?!)
check if '/dev/root' is mounted and, if so, set INSTALLED=1
run '/sbin/ldconfig' (configure dynamic linker run-time bindings (?!))
touch '/etc/sysconfig/text' or '/etc/sysconfig/xonly' if demanded by the respective boot-codes (does not trigger any further action)
(?!)
(only) if MYHOME is set then …
(only) if MYOPT is set then …
touch '/tmp/xsetup_requested' if xsetup is set (does not trigger any further action)
if LAPTOP is set then load the following kernel modules: ac and battery, yenta_socket or i82365.
(only) if NOSWAP is not set then swapon all devices
if SWAPFILE specifies a filepath (of the form 'sdX#/filename'; prepending '/dev/ is not an error BTW) then mount the respective partition and use that file for swap space.
if RESUME is set (to a swap device or file) then remove the file '/etc/sysconfig/tc.resume'. Determine the size of the specified swap space; if that is not possible, exit with error code 1. Check if swap size is greater than memory and if '/sys/power/state' contains “disk” then store that value in '/etc/sysconfig/tc.resume'. (Does not trigger any further action.)
(Does not trigger any further action.)
if CHECKFS is set then determine the tce-directory and check the file-system it resides on by calling the function checkfs() (see above).
if KEYMAP is set and an appropriate '.kmap'-file exists under '/usr/share/kmap/' then load that keymap and write the value of KEYMAP into '/etc/sysconfig/keymap'.
if SECURE is set then call getpasswd() for root as well as the user and change their passwords.
if PROTECT is set then call getpasswd() for encryption and store it in '/etc/sysconfig/bfe', changing the permissions of that file to 600.
The encryption must happen at backup and there must be some mechanism for decryption at the next boot. It is unclear to me at the moment where this happens.
if XVESA is set then replace “1024x768x32” in '~/.xsession' by that string.
The file '~/.xsession' is empty at boot-time so this boot-code does not do anything. Possibly this boot code has become obsolete by the extension graphics-<KERNEL>(?!).
if DESKTOP is specified then write its value to '/etc/sysconfig/desktop'; else if '/etc/sysconfig/desktop' already should contain a value store that in DESKTOP (does not trigger any further action)
The proper starting of the desktop environment happen later when the X server starts, eventually calling '~/.xinitrc'.
if MYDATA is set then write its value to '/etc/sysconfig/mydata', otherwise write “mydata” to it (does not trigger any further action)
(only) if NORESTORE is not set then set TCEDIR to the link target of '/etc/sysconfig/tcedir' and run '/etc/init.d/tc-restore.sh'.
Call '/etc/init.d/tc-restore.sh' with the link in '/etc/sysconfig/tcedir' as argument (pointing to the desired location of the tce-directory. That script (presumably!) does what it says in its name.
if CRON is set then start service '/etc/init.d/services/crond'
call '/sbin/loadcpufreq &'
a direct call to this script which is run in the foreground, i.e. waited for to terminate.
remove 'rm /etc/udev/rules.d/60-persistent-storage.rules' and trigger a Udev update
At present, the file in question does not exist at boot-time so there is nothing to do really.
add the user to the groups cdrom, tty, dialout, audio, video, plugdev
(only) if NOAUTOLOGIN is not set then store “booting” in '/etc/sysconfig/noautologin' (does not trigger any further action)
(only) if PAUSE is set then wait for user confirmation
creates a /var/log/sce.log
The main dCore boot-process is managed by '/etc/init.d/tc-config'. It does not do all the work directly but, in some cases, simply sets flag files under '/etc/sysconfig/'.
The end result will be a Linux console with a login shell (Almquist shell, Ash) for a single user.
A login shell first reads commands from the files '/etc/profile' and '.profile' if they exist. If ENV is set on entry to a shell, or is set in the .profile of a login shell, the shell next reads commands from the file named in ENV. (Cf. source.) ENV is indeed set to '~/.ashrc' in '~/.profile' (see below).
This is the system-wide profile for shell.
LC_ALL has not been explicitly set up to now.
execute all readable files of type '*.sh' under '/etc/profile.d/'
This is where the bulk of actions related to the user interface are triggered.
At present, LANG=en_US.UTF8 is hard-coded (see above), thereby ignoring the boot-code lang. An internationalisation mechanism would have to check if the necessary files are present before adapting the value of '/etc/sysconfig/language'.
Strictly speaking, the boot process terminates here.
The X server is started from '~/.profile', if applicable, and runs '~/.xinitrc'.
Note that files under '~/.X.d/' must contain backgrounded commands, i.e. with trailing “&”.
wait until the window manager has completed (in essence, makes this console log all window manager output)