CSE412: Embedded
Operating Systems
Lecture 6
Dr. Karim Emara
Computer Systems Department
Faculty of Computer and Information Sciences
Ain Shams University
2
Agenda
Filesystem addons
Disk filesystem & device table
Init Program
3
Filesystem add-ons
We created the root filesystem with minimal
configurations
There are several things to add:
proc and sys
init program
daemon process
user accounts
device nodes
4
proc and sysfs filesystems
proc and sysfs are two pseudo filesystems
that give a window onto the inner workings
of the kernel.
They both represent kernel data as files in a
hierarchy of directories
Their contents do not come from disk storage
but formatted on-the-fly by a function in the
kernel
5
proc and sysfs filesystems
proc and sysfs provide another way to
interact with device drivers and other kernel
code.
Without them, ps command cannot run or
show output
The proc and sysfs filesystems should be
mounted on the directories called /proc and
/sys
6
proc filesystem
The original purpose of proc is to expose
information about processes to user space
There is a directory for each process named
/proc/<PID>, which contains information
about its state.
The process list command, ps, reads these
files to generate its output.
To mount proc on target,
# mount -t proc procfs /proc
7
Sys filesystem
The role of sysfs is to present the kernel
driver model to user space.
It exports a hierarchy of files related to
devices and device drivers and the way they
are connected to each other.
To mount sysfs on target,
# mount -t sysfs sysfs /sys
8
Filesystem add-ons
We created the root filesystem with minimal
configurations
There are several things to add:
proc and sys
init program
daemon process
user accounts
device nodes
9
Init Program
Running a shell at boot time is fine for simple
cases
Normally, Unix systems run a program called
init that starts up and monitors other
programs.
The BusyBox init program begins by reading
the configuration file, /etc/inittab
10
Filesystem add-ons
We created the root filesystem with minimal
configurations
There are several things to add:
proc and sys
init program
daemon process
user accounts
device nodes
11
Daemons
Usually, certain processes are needed at startup,
syslogd for example.
The purpose of syslogd is to accumulate log
messages from other programs, mostly other
daemons.
Starting the daemon is as simple as adding a line
like this to etc/inittab :
::respawn:/sbin/syslogd -n
respawn means that if the program terminates, it
will be automatically restarted; -n means that it
should run as a foreground process.
12
Filesystem add-ons
We created the root filesystem with minimal
configurations
There are several things to add:
proc and sys
init program
daemon process
user accounts
device nodes
13
Configure user accounts
It is not good practice to run all programs as root, since if one is
compromised by an outside attack, then the whole system is at
risk.
It is preferable to create unprivileged user accounts and use them
where full root is not necessary.
User names are configured in /etc/passwd. There is one line per
user, with seven fields of information separated by colons, which
are in order:
1. The login name
2. A hash code used to verify the password, or more usually an x to indicate that
the password is stored in /etc/shadow
3. The user ID
4. The group ID
5. A comment field, often left blank
6. The user's home directory
7. (Optional) the shell this user will use
14
Simple /etc/passwd file
Simple example in which we have user root with UID 0 ,
and user daemon with UID 1
root:x:0:0:root:/root:/bin/sh
daemon:x:1:1:daemon:/usr/sbin:/bin/false
Setting the shell for user daemon to /bin/false ensures
that any attempt to log on with that name will fail.
To reduce the exposure of password information, they are
stored in /etc/shadow and x is placed in the password field
in /etc/passwd.
The file called /etc/shadow only needs to be accessed by
root , so as long as the root user is not compromised, the
passwords are safe.
15
Simple /etc/shadow file
The shadow password file consists of one
entry per user, made up of nine fields.
Here is an example that mirrors the password
file shown in the preceding slide:
root::10933:0:99999:7:::
daemon:*:10933:0:99999:7:::
The first two fields are the username and the
password hash. The remaining seven fields
are related to password aging
16
Filesystem add-ons
We created the root filesystem with minimal
configurations
There are several things to add:
proc and sys
init program
daemon process
user accounts
device nodes
17
Device nodes
Statically created device nodes using mknode
have one advantage over running a device
manager: they don't take any time during boot
to create.
However, static device nodes is quite hard work
and inflexible.
There are other ways to create device nodes
automatically on demand:
Devtmpfs
mdev
udev
18
devtmpfs
This is a pseudo filesystem that you mount over
/dev at boot time.
The kernel populates it with device nodes for all
the devices that the kernel currently knows
about, and it creates nodes for new devices as
they are detected at runtime.
The nodes are owned by root and have default
permissions of 600 .
Some well-known device nodes, such as /dev/null
and /dev/random , override the default to 666 .
19
devtmpfs
Support for the devtmpfs filesystem is controlled by
kernel configuration variable: CONFIG_DEVTMPFS
At menuconfig: Device Drivers/Generic Drivers/Maintain
a devtmpfs...
Trying out devtmpfs is as simple as entering this
command in init.d/rcS file:
# mount -t devtmpfs devtmpfs /dev
You can configure the kernel to automatically mount
devtmpfs just after mounting the root filesystem by
setting CONFIG_DEVTMPFS_MOUNT. However, this
option has no effect when booting initramfs
20
Agenda
Root filesystem recap & deployment
Filesystem addons
Disk filesystem & device table
Init Program
21
Disk filesystem image
Creating a disk image for filesystem is similar
to initramfs but using different archiving tool
Filesystem disk format is related to the type
of disk. For example, ext2 is usually used with
SD cards, jffs2 with flash memory.
These tools use device table file to handle file
permissions
22
Device table
A device table is a text file that lists the files,
directories, device nodes, and links that go
into an archive or filesystem image.
Its advantage is allowing the creation of
entries in the archive file that are owned by
the root user, or any other UID, without
having root privileges
The device table file with the format
<name> <type> <mode> <uid> <gid> <major>
<minor> <start> <inc> <count>
23
Device Table
name:
type: One of the following: f, d, c, b, p
mode: permission mode
uid: The UID of the file
gid: The GID of the file
major and minor: The device numbers (device
nodes only)
start, inc, and count: Allow you to create a group
of device nodes starting from the minor number
in start (device nodes only)
24
Device table
We don’t need to specify every file of the
staging directory into the device table file,
but only exceptions.
A simple example which populates static
device nodes for us is as follows:
/dev d 755 0 0 - - - - -
/dev/null c 666 0 0 1 3 0 0 -
/dev/console c 600 0 0 5 1 0 0 -
25
Disk filesystem image
Use genext2fs tool to generate a filesystem
image of 4 MB (that is 4,096 blocks of the
default size, 1,024 bytes):
$ genext2fs -b 4096 -d rootfs -D device-
[Link] -U rootfs.ext2
The resulting image, rootfs.ext2, can be
copied to an SD card or similar to be used as
permanent root filesystem
26
Agenda
Root filesystem recap & deployment
Filesystem addons
Disk filesystem & device table
Init Program (ch.13)
27
Init Program
There are many possible implementations of init:
BusyBox init, System V init, and systemd .
They differ in balancing the trade-off between
complexity and flexibility.
Kernel bootstrap code seeks to find a root
filesystem, either initramfs or a filesystem
specified by root= on the kernel command line
It executes then a program which, by default, is
/init for initramfs and /sbin/init for a regular
filesystem.
28
Init Program
The init program has root privilege of a PID=1
and if cannot be started, the kernel will panic.
The Init basic tasks are:
Starts daemon programs and configures system
parameters
Optionally, it launches a login daemon (e.g. getty),
on terminals that allow a login shell.
Optionally handle other runtime events, such as a
new hardware and the loading and unloading of
modules.
Optionally, it restarts those daemons that have
terminated. It handles the system shutdown.
29
Init Programs
The following table gives some metrics to
compare the three:
BusyBox init is a stripped version of system V
init
30
BusyBox init
BusyBox has a minimal init program that uses
a configuration file, /etc/inittab, to define
rules to start programs at boot up and to
stop them at shutdown.
Usually, the actual work is done by shell
scripts, which, by convention, are placed in
the /etc/init.d directory.
init begins by reading /etc/inittab which
contains a list of programs to run, one per
line
31
Inittab file format
inittab file contains a list of entries with the
following format
<id>:<runlevels>:<action>:<process>
<id>: specifies the controlling tty for the process.
If blank, init’s stdin/out will be used
<runlevels>: ignored
<action>: valid actions include: sysinit, respawn,
askfirst, restart, ..etc.
<process>: specifies the process to be executed
and its command line.
32
Inittab file format
inittab file contains a list of entries with the
following format
<id>:<runlevels>:<action>:<process>
<id>: specifies the controlling tty for the process.
If blank, init’s stdin/out will be used
<runlevels>: ignored
<action>: valid actions include: sysinit, respawn,
askfirst, restart, ..etc.
<process>: specifies the process to be executed
and its command line.
33
Init Actions
sysinit: Runs the program before any of the
other types of actions.
respawn: Runs the program and restarts it if
it terminates. (daemons)
askfirst: same as respawn, but it prints an ask
message first
once: Runs the program once but does not
attempt to restart it if it terminates.
34
Init Actions
wait: Runs the program and waits for it to
complete.
restart: Runs the program when init receives
the signal SIGHUP to reload the inittab file.
ctrlaltdel: Runs the program when init
receives the signal, SIGINT
shutdown: Runs the program when init shuts
down.
35
Default BusyBox inittab
Busybox init works without inittab file. In this case,
the following entries are the default behavior:
::sysinit:/etc/init.d/rcS
::askfirst:/bin/sh
::ctrlaltdel:/sbin/reboot
::shutdown:/sbin/swapoff -a
::shutdown:/bin/umount -a -r
::restart:/sbin/init
tty2::askfirst:/bin/sh
tty3::askfirst:/bin/sh
tty4::askfirst:/bin/sh
36
rcS file
The script called /etc/init.d/rcS is the place to
put initialization commands that need to be
performed at boot
For example, mounting the proc and sysfs
filesystems:
#!/bin/sh
mount -t proc proc /proc
mount -t sysfs sysfs /sys
37
Daemons
Usually, certain processes are needed at startup,
syslogd for example.
The purpose of syslogd is to accumulate log
messages from other programs, mostly other
daemons.
Starting the daemon is as simple as adding a line
like this to etc/inittab :
::respawn:/sbin/syslogd -n
respawn means that if the program terminates, it
will be automatically restarted; -n means that it
should run as a foreground process.
38
rcS file
Make sure that you make rcS executable:
$ cd ~/rootfs
$ chmod +x etc/init.d/rcS
Since we now utilize the BusyBox init
program, the kernel CL is changed
$ QEMU_AUDIO_DRV=none qemu-system-arm -m
256M -nographic -M versatilepb -kernel
zImage -append "console=ttyAMA0
rdinit=/sbin/init" -dtb [Link]
-initrd [Link]
39
Buildroot BusyBox init
Buildroot has been making effective use of the
BusyBox init for many years.
Buildroot has two scripts in /etc/init.d/ named rcS
and rcK
rcS runs at boot up and iterates over all the
scripts in /etc/init.d/ with names that begin with a
capital S (start scripts) followed by two digits
and runs them in numerical order.
The rcK script runs at shutdown and iterates over
all the scripts beginning with a capital K (kill
scripts) followed by two digits, and runs them in
numerical order.
40
System V init
System V init has two advantages.
boot scripts are written in a well-known, modular
format, making it easy to add new packages at
build time or runtime.
it has the concept of runlevels, which allow a
collection of programs to be started or stopped in
one go when switching from one runlevel to
another.
41
Sysvinit runlevels
There are 8 runlevels numbered from 0 to 6,
plus S:
S : Runs startup tasks
0 : Halts the system
1 to 5 : Available for general use
6 : Reboots the system
42
Sysvinit runlevels
Levels 1 to 5 can be used and they are
conventionally assigned as follows:
1 : Single user
2 : Multi-user with no network configuration
3 : Multi-user with network configuration
4 : Not used
5 : Multi-user with graphical login
The halt and reboot commands switch to
runlevels called 0 and 6 respectively
43
Runlevels
Each runlevel has a number of scripts that
stop things, called kill scripts, and another
group that start things, the start scripts.
When entering a new runlevel, init first runs
the kill scripts, and then the start scripts in
the new level.
The default action on the switching runlevel
is to terminate daemons unless told to do
otherwise.
44
Sysvinit inittab
The format of each line in inittab is as follows:
id:runlevels:action:process
The fields are similar to BusyBox inittab but
the runlevel is added which specifies which
level this entry should be executed.
45
Default sysvinit inittab
46
Default sysvinit inittab
The /etc/init.d/rcS script that is run by the
sysinit entry does little more than enter the
runlevel, S:
#!/bin/sh
[...]
exec /etc/init.d/rc S
Hence, the first runlevel entered is S,
followed by the default runlevel of 5.
47
Homework
1. Follow the steps of configuring the network
in chapter 5
2. Mount the rootfile system using NFS
48
References
Chapters 5 & 13: Chris Simmonds, Mastering
Embedded Linux Programming, 3rd ed, 2021
49
Thank You
Questions?