Welcome to the Tiny Core Linux Wiki at tinycorelinux.net!

dCore Boot Process and Boot Codes

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.

Suggested Readings

Although primarily related to Tiny Core, The following resources contain excellent material to help understand the boot process:

Early Boot

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'.

'init' (on initrd)

 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')

multivt: make all six TTYs available

L3: if the boot-code multivt is set then un-comment all six tty-entries in '/etc/inittab' which will make them available.

noembed: special way of handling RAM

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.


  • The main purpose of this script is to prepare '/etc/inittab' for making multiple TTYs available, according to the multivt boot-code. The exotic boot-code noembed is also handled here.
  • Control passes over to the init-process '/bb/init'.

'/bb/init' & '/etc/inittab'

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.


  • At system start, it runs '/etc/init.d/rcS' and makes TTYs available.
  • At system shutdown it runs '/etc/init.d/rc.shutdown'.


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'.


  • Standard procedures, after which control is passed to '/etc/init.d/tc-config' which will do the bulk of work.

dCore Takes Over: '/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.

Variables and function definition of adduser()

  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"
 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.

Start of system startup process

L26-29: print out nicely colored messages about the start of the system.

L30: prepend ”/usr/local/{s}bin” to the PATH-variable

Check boot-parameters

  1. check the boot-stanza for boot-codes with values and store them as variables, with the appropriate value, if applicable.
  2. check the boot-stanza for boot-codes without values and store them as variables of value 1.

Thus we have the following list of boot-codes and variables with values:


Noteworthy cases

  • host does not store its value in the variable HOST (cf. sethostname())
  • rsyslog also set SYSLOG=1
  • noicons may be used as a flag as well as with a value (cf. below)

Additional boot-codes

Some few boot-codes are treated elsewhere, notably …

  • multivt and noembed in 'init' (on initrd) as seen above
  • lst (TARGETLIST, defaults to 'onboot.lst') and cde (CDE) in '/usr/bin/tce-setup'

Kernel boot-parameters

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.

Starting the work

blacklist: black-list modules

copy names of black-listed modules into '/etc/modprobe.d/blacklist.conf' (does not trigger any further action)

Start Udev

start udev daemon for hotplug support

waitusb: wait for USB-device

do as requested

Load modules loop, ohci_hcd

modprobe loop and ohci_hcd (a USB-1.1 module ?!)

nozswap: skip de-compressing swap in RAM (de-activated)

all commented out

nofstab: inhibit preparing mount points for physical partitions

if NOFSTAB is not set then populate '/etc/fstab' with entries for physical partitions and create appropriate mount-points under '/mnt'.

checkfs() function definition

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.

syslog, rsyslog: start 'syslogd'

start 'syslogd' locally and also remotely if RSYSLOG specifies host:port

lang: set language

set and export LANG and write corresponding command into '/etc/sysconfig/language' (does not trigger any further action)

tz: set time zone

set and export TZ and write corresponding command into '/etc/sysconfig/tz' (does not trigger any further action)

nortc, noutc: skip real-time clock (de-activated)

(all commented out): (only) if NORTC was not set then call 'hwclock' (with option for UTC-time or, if NOUTC was set, localtime).

host: set host name

calls '/usr/bin/sethostname' to do its job.

Set up loop-back device

loop-back device with route

aoe: ATAOverEthernet (?!)


wait4Server() function definition

used to make sure that 'dhcp.sh' does not exit prematurely (?!)

user: set user name

'adduser' of the desired name


simply touches '/etc/sysconfig/superuser' (does not trigger any further action)

Setup base directories and set some stick bits

  1. make sure directories “$TCEINSTALLED”, “$TCEDIR”, “$TCLOOP” exist and symlink '/etc/sysconfig/tcedir/' to “$TCEDIR”
  2. set sticky bit on '/bin/busybox' and '/usr/bin/sudo'

Netbooting, LVM, RAID etc.

Consult the wikipages about netbooting or LVM & RAID for a rather complete discussion.

'get_app()' function definition

'get_app()' can down-load files (cf. httplist, tftplist below) (?!)

pretce: drivers for lvm/RAID etc.

preload drivers needed for tce/opt/home on lvm/RAID etc. (?!)

tftplist, httplist, nfsmount, nbd

  1. ”# First process tftp and http entries” (?!)
  2. NFS-mount
  3. network block device

Hard drive installation


check if '/dev/root' is mounted and, if so, set INSTALLED=1

On with the boot-process

run '/sbin/ldconfig' (configure dynamic linker run-time bindings (?!))

text, xonly

touch '/etc/sysconfig/text' or '/etc/sysconfig/xonly' if demanded by the respective boot-codes (does not trigger any further action)

tcvd: check for virtual hard drive


home: set up persistent home

(only) if MYHOME is set then …

  1. determine partition and run checkfs() if specified by the checkfs boot code. Mount it afterwards.
  2. check if persistent home is on a supported file system (i.e none of FAT, VFAT, MSODS, NTFS); if so then ignore request for persistent home and ask for user confirmation before proceeding.
  3. otherwise check if 'home/$USER' exists on the mount-point; create it if necessary. Then bind-mount the home-directory under '/home'. The variable HOME_SETUP is set only if 'home/$USER' existed before.
  4. fall-through option if invalid device is specified; ignore request for persistent home.
  5. call setupHome()

opt: set up persistent opt

(only) if MYOPT is set then …

  1. determine partition and run checkfs() if specified by the checkfs boot code. Mount it afterwards.
  2. check if persistent opt is on a supported file system (i.e none of FAT, VFAT, MSODS, NTFS). Ignore request for persistent opt and ask for user confirmation before proceeding.
  3. check if '/opt' exists on the mount-point; create it if necessary. Copy all content from the existing '/opt' to the new 'opt' on the mount-point. Bind-mount the new opt-directory under '/opt' with appropriate permissions.
  4. fall-through option if invalid device is specified; ignore request for persistent opt.


touch '/tmp/xsetup_requested' if xsetup is set (does not trigger any further action)

latop: load laptop-related kernel modules

if LAPTOP is set then load the following kernel modules: ac and battery, yenta_socket or i82365.

noswap: ignore swap partition

(only) if NOSWAP is not set then swapon all devices

swapfile: use specified swap-file

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.

resume: resume from hibernation information

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.)

no-/icons: set-up icon manager

  1. if NOICONS is to 1 set then create an empty file '/etc/sysconfig/icons'. Else if ICONS is set to some icon manager (?!) then write that value into '/etc/sysconfig/icons'; if not then check if '/etc/sysconfig/icons' contains something and if so then set the value of ICONS to that.
  2. if NOICONS is set to “ondemand” then touch '/etc/sysconfig/noondemandicons'.
  3. sync file systems

(Does not trigger any further action.)

checkfs: check the file system containing the tce-directory

if CHECKFS is set then determine the tce-directory and check the file-system it resides on by calling the function checkfs() (see above).

Preparing for user interaction

showapps: show loaded extensions

  1. if SHOWAPPS is set then touch the flag file '/etc/sysconfig/showapps'. Afterwards set-up the tce-directory by calling '/usr/bin/tce-setup “booting”' (which must check the freshly touched file). If ISOFILE is set then include extensions from the specified ISO-file by calling '/usr/bin/fromISOfile'. After all is done, remove the flag file.
  2. otherwise, that is if SHOWAPPS is not set, then do the very same as above but without the flag file untouched. If the loading should fail for any reason then output the collected error messages and wait for user confirmation.

kmap: set keyboard layout (currently only "us")

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'.

secure: set passwords during boot

if SECURE is set then call getpasswd() for root as well as the user and change their passwords.

protect: password-protection for 'mydata.gz' (?!)

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.

xvesa: replace standard XGA-resolution

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>(?!).

desktop: specify desktop environment (window manager) to start

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'.

mydata: set name for user data ('mydata.gz')

if MYDATA is set then write its value to '/etc/sysconfig/mydata', otherwise write “mydata” to it (does not trigger any further action)

norestore: skip restoring user data

(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'.

Restore 'mydata.tgz'

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.

nodhcp, nortc: skip network detection (DHCP) and setting time (NTP)

  1. (only) if DHCP is not set then check if DHCP_RAN is already set and run '/etc/init.d/dhcp.sh &' in case it is not.
  2. (only) if NORTC is not set then run '/etc/init.d/settime.sh &'

cron: start 'crond'

if CRON is set then start service '/etc/init.d/services/crond'

Load kernel modules for CPU frequency control

call '/sbin/loadcpufreq &'

Run '/opt/bootsync.sh'

a direct call to this script which is run in the foreground, i.e. waited for to terminate.

Set up Udev

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 USER to groups

add the user to the groups cdrom, tty, dialout, audio, video, plugdev

noautologin: demand login

(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/'.

  • Copy boot-codes into suitable variables (cf. table above).
  • Handle setting up a tce-source (on a physical parition or via netbooting)
  • Handle swap space
  • Check file system containing user datas upon request.
  • Start (r-)syslogd as well as crond if requested.
  • Set up persistent home and opt, if applicable.
  • Handle security questions (passwords, login)

The end result will be a Linux console with a login shell (Almquist shell, Ash) for a single user.

Shell Inits

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.

  1. set PATH with '/bb' at the end
  2. set prompt format for Ash
  3. set encoding for GTK+ apps (and screen display for X ?!) by G_FILENAME_ENCODING=iso8859-1
  4. if 'ldd' should not be in the path then alias ldd=LD_TRACE_LOADED_OBJECTS=1 (“ldd fake”)
  5. export variables defined above
  6. set mask to 022

export LANG, TZ

  1. if file '/etc/sysconfig/language' exists then execute it and export LANG, LC_ALL
  2. if file '/etc/sysconfig/timezone' exist then execute it and export TZ

LC_ALL has not been explicitly set up to now.

execute scripts under '/etc/profile.d/'

execute all readable files of type '*.sh' under '/etc/profile.d/'


  • settings for the shell for all users
  • execute supplementary profile scripts


This is where the bulk of actions related to the user interface are triggered.

PATH and variables

  1. make sure '~/.local/bin' exists and prepend it to PATH which is exported
  2. set ONDEMAND to '/etc/sysconfig/tcedir/ondemand'; if that directory exists then append it to PATH which is exported
  3. set prompt format PS1 for Ash or Bash
  4. set variables PAGER, MANPAGER (both using from 'less')
  5. set LANG=en_US.UTF8
  6. make sure EDITOR is set (defaults to 'vi')
  7. export these five variables
  8. export BACKUP=1
  9. if the current user is the one specified in '/etc/sysconfig/tcuser' then write the value of BACKUP to '/etc/sysconfig/backup'

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'.

Set up the user interface

  1. export FLWM_TITLEBAR_COLOR as “58:7D:AA”
  2. if '~/.ashrc' exists then export ENV='~/.ashrc' and run that file
  3. determine TERMTYPE by running '/bb/tty' (which returns ”/dev/ttyX” in the command line and ”/dev/pts/X” from the graphical desktop)
  4. when running in a TTY and if either of the following conditions hold, then call 'startx' unless
    1. '/usr/bin/Xorg' does not exist, meaning the extension has not been loaded yet
    2. '/etc/sysconfig/text' exists
    3. '/tmp/.X11-unix/X0' exists


  1. read '/etc/init.d/tc-functions'
  2. set aliases for df, du (both human-readable), ls (add slash to directory names), ll, la, cp, mv, rm (setting the latter three recursive)


  • script is performed anew for any instance of Ash
  • set aliases for Ash
  • place to put individual shell settings as file lives is user data

Strictly speaking, the boot process terminates here.

Starting X: '~/.xinitrc'

The X server is started from '~/.profile', if applicable, and runs '~/.xinitrc'.

  1. read DESKTOP from '/etc/sysconfig/desktop'; exit with error if this is not possible.
  2. execute the specified window manager (i.e. X-client), logging errors to '/tmp/wm_errors'

Set up

  1. call '/usr/bin/setupdesktop', setting up menus and icons
  2. if executable files '~/.setbackground' or '~/.mouse_config' exist then execute them


  1. execute any file under '~/.X.d/'
  2. (commented out) start an Xterm as a background process.

Auto-start files

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)


  • calls window manager
  • calls '/usr/bin/setupdesktop'
  • executes any file under '~/.X.d/' (auto-start)
  • acts as a log console

> Return to the dCore Wiki Welcome page