Notes from Linux Kernel Fundamentals course

I took the Linux Kernel fundamentals course on Linkedin Learning during the Week of Learning. I went through the first three lessons. The last two deals with compiling the kernel. I skipped them as I had done some kernel compiling years ago and I won’t be doing them anytime soon.

These are my notes from the lessons:

I have always thought Virtual Filesystems like /proc and /sys are stored in memory, they are not. They are generated when asked for it. Each file and directory has associated function in the kernel that generates the content when you ask.

strace -c “command” gives you the list of syscalls and count for each. In the example below, open is called 7 times.

 # strace -c pwd
/root
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
 56.21    0.000181          26         7         4 open
 11.49    0.000037           4         9           mmap
  6.21    0.000020           5         4           mprotect
  6.21    0.000020          10         2           munmap
  4.97    0.000016          16         1         1 access
  4.04    0.000013           3         4         3 stat
  3.11    0.000010           3         4           fstat
  1.86    0.000006           6         1           write
  1.55    0.000005           1         4           brk
  1.24    0.000004           1         5           close
  1.24    0.000004           4         1           execve
  0.93    0.000003           3         1           getcwd
  0.62    0.000002           2         1           read
  0.31    0.000001           1         1           arch_prctl
------ ----------- ----------- --------- --------- ----------------
100.00    0.000322                    45         8 total

I have always thought cd is a shell builtin and I am right. However, in the RHEL 7, there is a script which in turn calls the shell builtin.

# which cd
/usr/bin/cd
# file /usr/bin/cd
/usr/bin/cd: POSIX shell script, ASCII text executable
# cat  /usr/bin/cd
#!/bin/sh
builtin cd "$@"
# type cd
cd is a shell builtin
# type `which cd`
/usr/bin/cd is /usr/bin/cd

strace prints its traces on standard error, not on standard output.

    # strace fdisk -l  |&  grep /sys/block
    open("/sys/block/dm-0/dm/name", O_RDONLY|O_CLOEXEC) = 5
    open("/sys/block/dm-1/dm/name", O_RDONLY|O_CLOEXEC) = 5
    open("/sys/block/dm-2/dm/name", O_RDONLY|O_CLOEXEC) = 5
    open("/sys/block/dm-3/dm/name", O_RDONLY|O_CLOEXEC) = 5
    open("/sys/block/dm-4/dm/name", O_RDONLY|O_CLOEXEC) = 5
    open("/sys/block/dm-5/dm/name", O_RDONLY|O_CLOEXEC) = 5
    open("/sys/block/dm-6/dm/name", O_RDONLY|O_CLOEXEC) = 5
    open("/sys/block/dm-7/dm/name", O_RDONLY|O_CLOEXEC) = 5
    open("/sys/block/dm-8/dm/name", O_RDONLY|O_CLOEXEC) = 5
    open("/sys/block/dm-9/dm/name", O_RDONLY|O_CLOEXEC) = 5
    open("/sys/block/dm-10/dm/name", O_RDONLY|O_CLOEXEC) = 5
    open("/sys/block/dm-11/dm/name", O_RDONLY|O_CLOEXEC) = 5
    open("/sys/block/dm-12/dm/name", O_RDONLY|O_CLOEXEC) = 5
    open("/sys/block/dm-13/dm/name", O_RDONLY|O_CLOEXEC) = 5
    open("/sys/block/dm-14/dm/name", O_RDONLY|O_CLOEXEC) = 5

You can also do

    # strace fdisk -l 2>&1  |   grep /sys/block

strace check /proc/partitions

    # strace fdisk -l  |&  grep /proc
    open("/proc/partitions", O_RDONLY)      = 3

You can view the kernel command line parameters passed to the kernel by grub from dmesg.

# dmesg  | grep -i command
[    0.000000] Command line: BOOT_IMAGE=/vmlinuz-3.10.0-327.36.1.el7.x86_64 root=/dev/mapper/vg00-root_lv ro crashkernel=128M@16M rd.lvm.lv=vg00/root_lv rd.lvm.lv=vg00/swap_lv vga=794 rd.shell=0 rhgb quiet LANG=en_US.UTF-8 systemd.debug
[    0.000000] Kernel command line: BOOT_IMAGE=/vmlinuz-3.10.0-327.36.1.el7.x86_64 root=/dev/mapper/vg00-root_lv ro crashkernel=128M@16M rd.lvm.lv=vg00/root_lv rd.lvm.lv=vg00/swap_lv vga=794 rd.shell=0 rhgb quiet LANG=en_US.UTF-8 systemd.debug
[    6.423078] [drm]   Command Buffers.

and from /proc/cmdline

# cat /proc/cmdline
BOOT_IMAGE=/vmlinuz-3.10.0-327.36.1.el7.x86_64 root=/dev/mapper/vg00-root_lv ro crashkernel=128M@16M rd.lvm.lv=vg00/root_lv rd.lvm.lv=vg00/swap_lv vga=794 rd.shell=0 rhgb quiet LANG=en_US.UTF-8 systemd.debug

All kernel paramters are documented in Documentation/kernel-parameters.txt in the kernel source tree.

rdinit=/bin/sh will start bash from within initramfs
init=/bin/bash will load bash after initramfs

Loadable kernel modules (LKM): An LKM is an object file with .ko suffix (ko=kernel object). It runs in kernel space and becomes apart of the kernel when loaded. It is written in C and compiled for a particular kernel. Kernel modules are at /lib/modules/kernel_version. A module should have a unique name. It can be stored anywhere but you cannot use modprobe command if they are not located at /lib/modules/kernel_version.

There are these many modules on my test machine.

# find -name '*.ko' | wc -l
2212
# pwd
/lib/modules/3.10.0-327.36.1.el7.x86_64/kernel

lsmod lists loaded modules chronologically, the most recently loaded module is at the top. The vermagic of module which you can find using modinfo module should match vermagic of kernel. I am sure if the vermagic of kernel is different from the kernel version.

# modinfo vmxnet3
filename:       /lib/modules/3.10.0-327.36.1.el7.x86_64/kernel/drivers/net/vmxnet3/vmxnet3.ko
version:        1.3.5.0-k
license:        GPL v2
description:    VMware vmxnet3 virtual NIC driver
author:         VMware, Inc.
rhelversion:    7.2
srcversion:     5A6F90E18800522C31A11B8
alias:          pci:v000015ADd000007B0sv*sd*bc*sc*i*
depends:
intree:         Y
vermagic:       3.10.0-327.36.1.el7.x86_64 SMP mod_unload modversions
signer:         Red Hat Enterprise Linux kernel signing key
sig_key:        00:88:04:02:8D:80:20:4E:24:5C:78:6E:96:FC:2A:83:08:4A:88:B4
sig_hashalgo:   sha256
# uname
Linux
# uname -r
3.10.0-327.36.1.el7.x86_64

modprobe looks up module dependencies, insmod does not. Module dependency is maintained in the file modules.dep. In this example, ext4 module needs mbcache and jbd.

# grep ext4 modules.dep
kernel/fs/ext4/ext4.ko: kernel/fs/mbcache.ko kernel/fs/jbd2/jbd2.ko
# pwd
/lib/modules/3.10.0-327.36.1.el7.x86_64

# lsmod | grep ext4
ext4                  578819  1
mbcache                14958  1 ext4
jbd2                  102940  1 ext4

The Linux kernel uses the syscall printk to print messages, the messages you see in dmesg.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s