# Linux kernel - Module Programming
###### tags: `linux2021`
---
## Set and Remove The Module
### strace
> Run the exectable with `strace ./hello`. Are you impressed? Every line you see corresponds to a system call. strace is a handy program that gives you details about what system calls a program is making, including which call is made, what its arguments are and what it returns.
### `insmod` with strace
:::spoiler
```sh
execve("/usr/sbin/insmod", ["insmod", "hello-1.ko"], 0x7ffec113f208 /* 25 vars */) = 0
brk(NULL) = 0x55c2ad121000
arch_prctl(0x3001 /* ARCH_??? */, 0x7ffe19aff320) = -1 EINVAL (Invalid argument)
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=92122, ...}) = 0
mmap(NULL, 92122, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f3238cde000
close(3) = 0
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/liblzma.so.5", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\3003\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0644, st_size=162264, ...}) = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f3238cdc000
mmap(NULL, 164104, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f3238cb3000
mprotect(0x7f3238cb6000, 147456, PROT_NONE) = 0
mmap(0x7f3238cb6000, 98304, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x3000) = 0x7f3238cb6000
mmap(0x7f3238cce000, 45056, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1b000) = 0x7f3238cce000
mmap(0x7f3238cda000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x26000) = 0x7f3238cda000
close(3) = 0
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libcrypto.so.1.1", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\0\220\7\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0644, st_size=2954080, ...}) = 0
mmap(NULL, 2973600, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f32389dd000
mmap(0x7f3238a55000, 1683456, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x78000) = 0x7f3238a55000
mmap(0x7f3238bf0000, 593920, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x213000) = 0x7f3238bf0000
mmap(0x7f3238c81000, 188416, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x2a3000) = 0x7f3238c81000
mmap(0x7f3238caf000, 16288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f3238caf000
close(3) = 0
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\360q\2\0\0\0\0\0"..., 832) = 832
pread64(3, "\6\0\0\0\4\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0"..., 784, 64) = 784
pread64(3, "\4\0\0\0\20\0\0\0\5\0\0\0GNU\0\2\0\0\300\4\0\0\0\3\0\0\0\0\0\0\0", 32, 848) = 32
pread64(3, "\4\0\0\0\24\0\0\0\3\0\0\0GNU\0\t\233\222%\274\260\320\31\331\326\10\204\276X>\263"..., 68, 880) = 68
fstat(3, {st_mode=S_IFREG|0755, st_size=2029224, ...}) = 0
pread64(3, "\6\0\0\0\4\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0"..., 784, 64) = 784
pread64(3, "\4\0\0\0\20\0\0\0\5\0\0\0GNU\0\2\0\0\300\4\0\0\0\3\0\0\0\0\0\0\0", 32, 848) = 32
pread64(3, "\4\0\0\0\24\0\0\0\3\0\0\0GNU\0\t\233\222%\274\260\320\31\331\326\10\204\276X>\263"..., 68, 880) = 68
mmap(NULL, 2036952, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f32387eb000
mprotect(0x7f3238810000, 1847296, PROT_NONE) = 0
mmap(0x7f3238810000, 1540096, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x25000) = 0x7f3238810000
mmap(0x7f3238988000, 303104, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x19d000) = 0x7f3238988000
mmap(0x7f32389d3000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1e7000) = 0x7f32389d3000
mmap(0x7f32389d9000, 13528, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f32389d9000
close(3) = 0
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libpthread.so.0", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\220\201\0\0\0\0\0\0"..., 832) = 832
pread64(3, "\4\0\0\0\24\0\0\0\3\0\0\0GNU\0\345Ga\367\265T\320\374\301V)Yf]\223\337"..., 68, 824) = 68
fstat(3, {st_mode=S_IFREG|0755, st_size=157224, ...}) = 0
pread64(3, "\4\0\0\0\24\0\0\0\3\0\0\0GNU\0\345Ga\367\265T\320\374\301V)Yf]\223\337"..., 68, 824) = 68
mmap(NULL, 140408, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f32387c8000
mmap(0x7f32387cf000, 69632, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x7000) = 0x7f32387cf000
mmap(0x7f32387e0000, 20480, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x18000) = 0x7f32387e0000
mmap(0x7f32387e5000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1c000) = 0x7f32387e5000
mmap(0x7f32387e7000, 13432, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f32387e7000
close(3) = 0
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libdl.so.2", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0 \22\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0644, st_size=18816, ...}) = 0
mmap(NULL, 20752, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f32387c2000
mmap(0x7f32387c3000, 8192, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1000) = 0x7f32387c3000
mmap(0x7f32387c5000, 4096, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x3000) = 0x7f32387c5000
mmap(0x7f32387c6000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x3000) = 0x7f32387c6000
close(3) = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f32387c0000
arch_prctl(ARCH_SET_FS, 0x7f32387c1540) = 0
mprotect(0x7f32389d3000, 12288, PROT_READ) = 0
mprotect(0x7f32387c6000, 4096, PROT_READ) = 0
mprotect(0x7f32387e5000, 4096, PROT_READ) = 0
mprotect(0x7f3238c81000, 180224, PROT_READ) = 0
mprotect(0x7f3238cda000, 4096, PROT_READ) = 0
mprotect(0x55c2ac3a4000, 8192, PROT_READ) = 0
mprotect(0x7f3238d22000, 4096, PROT_READ) = 0
munmap(0x7f3238cde000, 92122) = 0
set_tid_address(0x7f32387c1810) = 11344
set_robust_list(0x7f32387c1820, 24) = 0
rt_sigaction(SIGRTMIN, {sa_handler=0x7f32387cfbf0, sa_mask=[], sa_flags=SA_RESTORER|SA_SIGINFO, sa_restorer=0x7f32387dd3c0}, NULL, 8) = 0
rt_sigaction(SIGRT_1, {sa_handler=0x7f32387cfc90, sa_mask=[], sa_flags=SA_RESTORER|SA_RESTART|SA_SIGINFO, sa_restorer=0x7f32387dd3c0}, NULL, 8) = 0
rt_sigprocmask(SIG_UNBLOCK, [RTMIN RT_1], NULL, 8) = 0
prlimit64(0, RLIMIT_STACK, NULL, {rlim_cur=8192*1024, rlim_max=RLIM64_INFINITY}) = 0
brk(NULL) = 0x55c2ad121000
brk(0x55c2ad142000) = 0x55c2ad142000
uname({sysname="Linux", nodename="strix-laptop", ...}) = 0
openat(AT_FDCWD, "/lib/modules/5.8.0-59-generic/modules.softdep", O_RDONLY|O_CLOEXEC) = 3
fcntl(3, F_GETFL) = 0x8000 (flags O_RDONLY|O_LARGEFILE)
fstat(3, {st_mode=S_IFREG|0644, st_size=885, ...}) = 0
read(3, "# Soft dependencies extracted fr"..., 4096) = 885
read(3, "", 4096) = 0
close(3) = 0
openat(AT_FDCWD, "/proc/cmdline", O_RDONLY|O_CLOEXEC) = 3
read(3, "BOOT_IMAGE=/boot/vmlinuz-5.8.0-5"..., 4095) = 118
read(3, "", 3977) = 0
close(3) = 0
getcwd("/home/slda/develop/kernel/hello-1", 4096) = 34
stat("/home/slda/develop/kernel/hello-1/hello-1.ko", {st_mode=S_IFREG|0664, st_size=4224, ...}) = 0
openat(AT_FDCWD, "/home/slda/develop/kernel/hello-1/hello-1.ko", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1", 6) = 6
lseek(3, 0, SEEK_SET) = 0
fstat(3, {st_mode=S_IFREG|0664, st_size=4224, ...}) = 0
mmap(NULL, 4224, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f3238cf3000
finit_module(3, "", 0) = 0
munmap(0x7f3238cf3000, 4224) = 0
close(3) = 0
exit_group(0) = ?
+++ exited with 0 +++
```
:::
### `lsmod` with strace
:::spoiler
```sh
execve("/usr/sbin/lsmod", ["lsmod", "hello-5"], 0x7ffc23bbee58 /* 57 vars */) = 0
brk(NULL) = 0x55e0b2765000
arch_prctl(0x3001 /* ARCH_??? */, 0x7ffdabfb5840) = -1 EINVAL (Invalid argument)
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=92122, ...}) = 0
mmap(NULL, 92122, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7face40b5000
close(3) = 0
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/liblzma.so.5", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\3003\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0644, st_size=162264, ...}) = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7face40b3000
mmap(NULL, 164104, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7face408a000
mprotect(0x7face408d000, 147456, PROT_NONE) = 0
mmap(0x7face408d000, 98304, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x3000) = 0x7face408d000
mmap(0x7face40a5000, 45056, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1b000) = 0x7face40a5000
mmap(0x7face40b1000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x26000) = 0x7face40b1000
close(3) = 0
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libcrypto.so.1.1", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\0\220\7\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0644, st_size=2954080, ...}) = 0
mmap(NULL, 2973600, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7face3db4000
mmap(0x7face3e2c000, 1683456, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x78000) = 0x7face3e2c000
mmap(0x7face3fc7000, 593920, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x213000) = 0x7face3fc7000
mmap(0x7face4058000, 188416, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x2a3000) = 0x7face4058000
mmap(0x7face4086000, 16288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7face4086000
close(3) = 0
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\360q\2\0\0\0\0\0"..., 832) = 832
pread64(3, "\6\0\0\0\4\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0"..., 784, 64) = 784
pread64(3, "\4\0\0\0\20\0\0\0\5\0\0\0GNU\0\2\0\0\300\4\0\0\0\3\0\0\0\0\0\0\0", 32, 848) = 32
pread64(3, "\4\0\0\0\24\0\0\0\3\0\0\0GNU\0\t\233\222%\274\260\320\31\331\326\10\204\276X>\263"..., 68, 880) = 68
fstat(3, {st_mode=S_IFREG|0755, st_size=2029224, ...}) = 0
pread64(3, "\6\0\0\0\4\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0"..., 784, 64) = 784
pread64(3, "\4\0\0\0\20\0\0\0\5\0\0\0GNU\0\2\0\0\300\4\0\0\0\3\0\0\0\0\0\0\0", 32, 848) = 32
pread64(3, "\4\0\0\0\24\0\0\0\3\0\0\0GNU\0\t\233\222%\274\260\320\31\331\326\10\204\276X>\263"..., 68, 880) = 68
mmap(NULL, 2036952, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7face3bc2000
mprotect(0x7face3be7000, 1847296, PROT_NONE) = 0
mmap(0x7face3be7000, 1540096, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x25000) = 0x7face3be7000
mmap(0x7face3d5f000, 303104, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x19d000) = 0x7face3d5f000
mmap(0x7face3daa000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1e7000) = 0x7face3daa000
mmap(0x7face3db0000, 13528, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7face3db0000
close(3) = 0
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libpthread.so.0", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\220\201\0\0\0\0\0\0"..., 832) = 832
pread64(3, "\4\0\0\0\24\0\0\0\3\0\0\0GNU\0\345Ga\367\265T\320\374\301V)Yf]\223\337"..., 68, 824) = 68
fstat(3, {st_mode=S_IFREG|0755, st_size=157224, ...}) = 0
pread64(3, "\4\0\0\0\24\0\0\0\3\0\0\0GNU\0\345Ga\367\265T\320\374\301V)Yf]\223\337"..., 68, 824) = 68
mmap(NULL, 140408, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7face3b9f000
mmap(0x7face3ba6000, 69632, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x7000) = 0x7face3ba6000
mmap(0x7face3bb7000, 20480, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x18000) = 0x7face3bb7000
mmap(0x7face3bbc000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1c000) = 0x7face3bbc000
mmap(0x7face3bbe000, 13432, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7face3bbe000
close(3) = 0
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libdl.so.2", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0 \22\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0644, st_size=18816, ...}) = 0
mmap(NULL, 20752, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7face3b99000
mmap(0x7face3b9a000, 8192, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1000) = 0x7face3b9a000
mmap(0x7face3b9c000, 4096, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x3000) = 0x7face3b9c000
mmap(0x7face3b9d000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x3000) = 0x7face3b9d000
close(3) = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7face3b97000
arch_prctl(ARCH_SET_FS, 0x7face3b98540) = 0
mprotect(0x7face3daa000, 12288, PROT_READ) = 0
mprotect(0x7face3b9d000, 4096, PROT_READ) = 0
mprotect(0x7face3bbc000, 4096, PROT_READ) = 0
mprotect(0x7face4058000, 180224, PROT_READ) = 0
mprotect(0x7face40b1000, 4096, PROT_READ) = 0
mprotect(0x55e0b0a43000, 8192, PROT_READ) = 0
mprotect(0x7face40f9000, 4096, PROT_READ) = 0
munmap(0x7face40b5000, 92122) = 0
set_tid_address(0x7face3b98810) = 21835
set_robust_list(0x7face3b98820, 24) = 0
rt_sigaction(SIGRTMIN, {sa_handler=0x7face3ba6bf0, sa_mask=[], sa_flags=SA_RESTORER|SA_SIGINFO, sa_restorer=0x7face3bb43c0}, NULL, 8) = 0
rt_sigaction(SIGRT_1, {sa_handler=0x7face3ba6c90, sa_mask=[], sa_flags=SA_RESTORER|SA_RESTART|SA_SIGINFO, sa_restorer=0x7face3bb43c0}, NULL, 8) = 0
rt_sigprocmask(SIG_UNBLOCK, [RTMIN RT_1], NULL, 8) = 0
prlimit64(0, RLIMIT_STACK, NULL, {rlim_cur=8192*1024, rlim_max=RLIM64_INFINITY}) = 0
write(2, "Usage: lsmod\n", 13Usage: lsmod
) = 13
exit_group(1) = ?
+++ exited with 1 +++
```
:::
### `rmmod` with strace
:::spoiler
```sh
execve("/usr/sbin/rmmod", ["rmmod", "hello_1"], 0x7ffd116dd448 /* 25 vars */) = 0
brk(NULL) = 0x562b972a9000
arch_prctl(0x3001 /* ARCH_??? */, 0x7fff56c17ab0) = -1 EINVAL (Invalid argument)
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=92122, ...}) = 0
mmap(NULL, 92122, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f9e4a64a000
close(3) = 0
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/liblzma.so.5", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\3003\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0644, st_size=162264, ...}) = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f9e4a648000
mmap(NULL, 164104, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f9e4a61f000
mprotect(0x7f9e4a622000, 147456, PROT_NONE) = 0
mmap(0x7f9e4a622000, 98304, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x3000) = 0x7f9e4a622000
mmap(0x7f9e4a63a000, 45056, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1b000) = 0x7f9e4a63a000
mmap(0x7f9e4a646000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x26000) = 0x7f9e4a646000
close(3) = 0
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libcrypto.so.1.1", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\0\220\7\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0644, st_size=2954080, ...}) = 0
mmap(NULL, 2973600, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f9e4a349000
mmap(0x7f9e4a3c1000, 1683456, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x78000) = 0x7f9e4a3c1000
mmap(0x7f9e4a55c000, 593920, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x213000) = 0x7f9e4a55c000
mmap(0x7f9e4a5ed000, 188416, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x2a3000) = 0x7f9e4a5ed000
mmap(0x7f9e4a61b000, 16288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f9e4a61b000
close(3) = 0
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\360q\2\0\0\0\0\0"..., 832) = 832
pread64(3, "\6\0\0\0\4\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0"..., 784, 64) = 784
pread64(3, "\4\0\0\0\20\0\0\0\5\0\0\0GNU\0\2\0\0\300\4\0\0\0\3\0\0\0\0\0\0\0", 32, 848) = 32
pread64(3, "\4\0\0\0\24\0\0\0\3\0\0\0GNU\0\t\233\222%\274\260\320\31\331\326\10\204\276X>\263"..., 68, 880) = 68
fstat(3, {st_mode=S_IFREG|0755, st_size=2029224, ...}) = 0
pread64(3, "\6\0\0\0\4\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0"..., 784, 64) = 784
pread64(3, "\4\0\0\0\20\0\0\0\5\0\0\0GNU\0\2\0\0\300\4\0\0\0\3\0\0\0\0\0\0\0", 32, 848) = 32
pread64(3, "\4\0\0\0\24\0\0\0\3\0\0\0GNU\0\t\233\222%\274\260\320\31\331\326\10\204\276X>\263"..., 68, 880) = 68
mmap(NULL, 2036952, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f9e4a157000
mprotect(0x7f9e4a17c000, 1847296, PROT_NONE) = 0
mmap(0x7f9e4a17c000, 1540096, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x25000) = 0x7f9e4a17c000
mmap(0x7f9e4a2f4000, 303104, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x19d000) = 0x7f9e4a2f4000
mmap(0x7f9e4a33f000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1e7000) = 0x7f9e4a33f000
mmap(0x7f9e4a345000, 13528, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f9e4a345000
close(3) = 0
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libpthread.so.0", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\220\201\0\0\0\0\0\0"..., 832) = 832
pread64(3, "\4\0\0\0\24\0\0\0\3\0\0\0GNU\0\345Ga\367\265T\320\374\301V)Yf]\223\337"..., 68, 824) = 68
fstat(3, {st_mode=S_IFREG|0755, st_size=157224, ...}) = 0
pread64(3, "\4\0\0\0\24\0\0\0\3\0\0\0GNU\0\345Ga\367\265T\320\374\301V)Yf]\223\337"..., 68, 824) = 68
mmap(NULL, 140408, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f9e4a134000
mmap(0x7f9e4a13b000, 69632, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x7000) = 0x7f9e4a13b000
mmap(0x7f9e4a14c000, 20480, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x18000) = 0x7f9e4a14c000
mmap(0x7f9e4a151000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1c000) = 0x7f9e4a151000
mmap(0x7f9e4a153000, 13432, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f9e4a153000
close(3) = 0
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libdl.so.2", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0 \22\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0644, st_size=18816, ...}) = 0
mmap(NULL, 20752, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f9e4a12e000
mmap(0x7f9e4a12f000, 8192, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1000) = 0x7f9e4a12f000
mmap(0x7f9e4a131000, 4096, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x3000) = 0x7f9e4a131000
mmap(0x7f9e4a132000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x3000) = 0x7f9e4a132000
close(3) = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f9e4a12c000
arch_prctl(ARCH_SET_FS, 0x7f9e4a12d540) = 0
mprotect(0x7f9e4a33f000, 12288, PROT_READ) = 0
mprotect(0x7f9e4a132000, 4096, PROT_READ) = 0
mprotect(0x7f9e4a151000, 4096, PROT_READ) = 0
mprotect(0x7f9e4a5ed000, 180224, PROT_READ) = 0
mprotect(0x7f9e4a646000, 4096, PROT_READ) = 0
mprotect(0x562b96fb9000, 8192, PROT_READ) = 0
mprotect(0x7f9e4a68e000, 4096, PROT_READ) = 0
munmap(0x7f9e4a64a000, 92122) = 0
set_tid_address(0x7f9e4a12d810) = 11560
set_robust_list(0x7f9e4a12d820, 24) = 0
rt_sigaction(SIGRTMIN, {sa_handler=0x7f9e4a13bbf0, sa_mask=[], sa_flags=SA_RESTORER|SA_SIGINFO, sa_restorer=0x7f9e4a1493c0}, NULL, 8) = 0
rt_sigaction(SIGRT_1, {sa_handler=0x7f9e4a13bc90, sa_mask=[], sa_flags=SA_RESTORER|SA_RESTART|SA_SIGINFO, sa_restorer=0x7f9e4a1493c0}, NULL, 8) = 0
rt_sigprocmask(SIG_UNBLOCK, [RTMIN RT_1], NULL, 8) = 0
prlimit64(0, RLIMIT_STACK, NULL, {rlim_cur=8192*1024, rlim_max=RLIM64_INFINITY}) = 0
brk(NULL) = 0x562b972a9000
brk(0x562b972ca000) = 0x562b972ca000
uname({sysname="Linux", nodename="strix-laptop", ...}) = 0
openat(AT_FDCWD, "/lib/modules/5.8.0-59-generic/modules.softdep", O_RDONLY|O_CLOEXEC) = 3
fcntl(3, F_GETFL) = 0x8000 (flags O_RDONLY|O_LARGEFILE)
fstat(3, {st_mode=S_IFREG|0644, st_size=885, ...}) = 0
read(3, "# Soft dependencies extracted fr"..., 4096) = 885
read(3, "", 4096) = 0
close(3) = 0
openat(AT_FDCWD, "/proc/cmdline", O_RDONLY|O_CLOEXEC) = 3
read(3, "BOOT_IMAGE=/boot/vmlinuz-5.8.0-5"..., 4095) = 118
read(3, "", 3977) = 0
close(3) = 0
stat("hello_1", 0x7fff56c179c0) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/lib/modules/5.8.0-59-generic/modules.builtin.bin", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=12521, ...}) = 0
read(3, "\260\7\364W\0\2\0\1 \0/\333ase\0\0\0\0\1\0\0\0\0\0ci\0\0\0\0\1"..., 4096) = 4096
lseek(3, 8192, SEEK_SET) = 8192
read(3, "\0\0\0\0\0\0\0\0\0\300\0\37\324\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 4096) = 4096
read(3, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 4096) = 233
lseek(3, 4096, SEEK_SET) = 4096
read(3, "\0\0\0 \0\17\207\0\0\0\0\300\0\17\235\0\0\0\1\0\0\0\0\0\0\0\0\1\0\0\0\0"..., 4096) = 4096
lseek(3, 8192, SEEK_SET) = 8192
close(3) = 0
openat(AT_FDCWD, "/sys/module/hello_1/initstate", O_RDONLY|O_CLOEXEC) = 3
read(3, "live\n", 31) = 5
read(3, "", 26) = 0
close(3) = 0
openat(AT_FDCWD, "/sys/module/hello_1/holders", O_RDONLY|O_NONBLOCK|O_CLOEXEC|O_DIRECTORY) = 3
fstat(3, {st_mode=S_IFDIR|0755, st_size=0, ...}) = 0
getdents64(3, /* 2 entries */, 32768) = 48
getdents64(3, /* 0 entries */, 32768) = 0
close(3) = 0
openat(AT_FDCWD, "/sys/module/hello_1/refcnt", O_RDONLY|O_CLOEXEC) = 3
read(3, "0\n", 31) = 2
read(3, "", 29) = 0
close(3) = 0
delete_module("hello_1", O_NONBLOCK) = 0
exit_group(0) = ?
+++ exited with 0 +++
```
:::
---
## `__init` and `__exit` Macro
> The `__init` macro causes the init function to be discarded and its memory freed once the init function finishes for built-in drivers, but not loadable modules.
>There is also an `__initdata` which works similarly to `__init` but for init variables rather than functions.
> The `__exit` macro causes the omission of the function when the module is built into the kernel, and like `__init`, has no effect for loadable modules. Again, if you consider when the cleanup function runs, this makes complete sense; built-in drivers don’t need a cleanup function, while loadable modules do.
---
## `pr_info` output place
use the command [**dmesg**](https://man7.org/linux/man-pages/man1/dmesg.1.html) to get:
```sh
[12668.645524] Hello, world 5
=============
[12668.645525] myshort is a short integer: 1
[12668.645525] myint is an integer: 420
[12668.645526] mylong is a long integer: 9999
[12668.645526] mystring is a string: bebop
[12668.645526] myintArray[0] = -1
[12668.645527] myintArray[1] = -1
[12668.645527] got 1 arguments for myintArray.
[12685.293063] Goodbye, world 5
[12695.876260] hello_5: unknown parameter 'mybyte' ignored
[12695.876358] Hello, world 5
=============
[12695.876360] myshort is a short integer: 1
[12695.876362] myint is an integer: 420
[12695.876363] mylong is a long integer: 9999
[12695.876365] mystring is a string: bebop
[12695.876366] myintArray[0] = -1
[12695.876367] myintArray[1] = -1
[12695.876369] got 1 arguments for myintArray.
[12703.330228] [UFW BLOCK] IN=wlo1 OUT= MAC=01:00:5e:00:00:fb:86:2e:8a:78:9c:0a:08:00 SRC=192.168.0.14 DST=224.0.0.251 LEN=32 TOS=0x00 PREC=0x00 TTL=1 ID=34754 PROTO=2
[12703.536425] Goodbye, world 5
[12752.817737] hello_5: unknown parameter 'mybyte' ignored
[12752.817835] Hello, world 5
=============
[12752.817837] myshort is a short integer: 1
[12752.817839] myint is an integer: 420
[12752.817840] mylong is a long integer: 9999
[12752.817841] mystring is a string: bebop
[12752.817843] myintArray[0] = -1
[12752.817844] myintArray[1] = -1
[12752.817845] got 1 arguments for myintArray.
[12902.114177] Goodbye, world 5
[12928.609991] [UFW BLOCK] IN=wlo1 OUT= MAC=01:00:5e:00:00:fb:86:2e:8a:78:9c:0a:08:00 SRC=192.168.0.14 DST=224.0.0.251 LEN=32 TOS=0x00 PREC=0x00 TTL=1 ID=17291 PROTO=2
[13057.855247] hello_5: unknown parameter 'mybyte' ignored
[13057.855345] Hello, world 5
=============
[13057.855347] myshort is a short integer: 1
[13057.855348] myint is an integer: 420
[13057.855350] mylong is a long integer: 9999
[13057.855351] mystring is a string: bebop
[13057.855353] myintArray[0] = -1
[13057.855354] myintArray[1] = -1
[13057.855355] got 1 arguments for myintArray.
[13066.851112] [UFW BLOCK] IN=wlo1 OUT= MAC=01:00:5e:00:00:fb:86:2e:8a:78:9c:0a:08:00 SRC=192.168.0.14 DST=224.0.0.251 LEN=32 TOS=0x00 PREC=0x00 TTL=1 ID=6727 PROTO=2
[13069.329031] Goodbye, world 5
```
According to [kernel.org - printk](https://www.kernel.org/doc/html/latest/core-api/printk-basics.html) we can use `echo 8 /proc/sys/kernel/printk` to get the output in the terminal.
> The result shows the current, default, minimum and boot-time-default log levels.
Moreover, from [stackoverflow - using printk to print data on linux terminal](https://stackoverflow.com/questions/39330184/using-printk-to-print-data-on-linux-terminal) we may also write this script to setup.
```cpp
/*
* setlevel.c -- choose a console_loglevel for the kernel
*
* Copyright (C) 1998,2000,2001 Alessandro Rubini
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/klog.h>
int main(int argc, char **argv)
{
int level;
if (argc==2) {
level = atoi(argv[1]); /* the chosen console */
} else {
fprintf(stderr, "%s: need a single arg\n",argv[0]); exit(1);
}
if (klogctl(8,NULL,level) < 0) {
fprintf(stderr,"%s: syslog(setlevel): %s\n",
argv[0],strerror(errno));
exit(1);
}
exit(0);
}
```
```sh
gcc setlevel.c -o setlevel
sudo ./setlevel 8
```
---
## Insert the module in precompiled kernel
> Consequently, we want to compile our module in an environment which was identical to the one in which our precompiled kernel was built.
> First of all, make sure that a kernel source tree is available, having exactly the same version as your current kernel. Then, find the configuration file which was used to compile your precompiled kernel. Usually, this is available in your current boot directory, under a name like `config-2.6.x`. You may just want to copy it to your kernel source tree:
> `*cp /boot/config-‘uname -r‘ /usr/src/linux-‘uname -r‘.config*`.
:::warning
The config file between module and kernel maybe different.
A slight difference in the version magic could be possible,
> page 17
:::
---
## The Symbols Provided by kernel
```sh
$ cat /proc/kallsyms | grep printk
...
0000000000000000 T vprintk
...
0000000000000000 T __warn_printk
0000000000000000 T printk
0000000000000000 T printk_deferred
...
```
---
## Device Driver
> Notice the column of numbers separated by a comma? The first number is called the device’s major number. The second number is the minor number. The major number tells you which driver is used to access the hardware. Each driver is assigned a unique major number; all device files with the same major number are controlled by the same driver. All the above major numbers are 3, because they’re all controlled by the same driver.
> Devices are divided into two types: character devices and block devices. The difference is that block devices have a buffer for requests, so they can choose the best order in which to respond to the requests.
```sh
# major number(which driver to access the hardware),
# minor number(various hardware controlled)
$ ls -l /dev/usb
total 0
crw------- 1 root root 180, 0 Jul 23 03:56 hiddev0
crw------- 1 root root 180, 1 Jul 23 03:56 hiddev1
crw------- 1 root root 180, 2 Jul 23 03:56 hiddev2
```
> major number - /usr/src/linux/Documentation/devices.txt
| block device | character device |
|:------------:|:----------------:|
| buffer | few bytes |
```sh
$ ls -l /dev/
crw-rw---- 1 root tty 7, 70 Jul 23 03:56 vcsu6
drwxr-xr-x 2 root root 60 Jul 23 2021 vfio
```
* `mknod /dev/name type_c_or_d major minor` for creating the device file
The driver is only the thing that care about the minor number.
The phyiscal hardware can hold two or more device files with same major number but different minor number.
---
## `pidof` with strace
```sh
execve("/usr/bin/pidof", ["pidof", "cron"], 0x7ffe9763e888 /* 57 vars */) = 0
brk(NULL) = 0x56166273e000
arch_prctl(0x3001 /* ARCH_??? */, 0x7ffe62bfae20) = -1 EINVAL (Invalid argument)
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=92122, ...}) = 0
mmap(NULL, 92122, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7fca76a08000
close(3) = 0
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\360q\2\0\0\0\0\0"..., 832) = 832
pread64(3, "\6\0\0\0\4\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0"..., 784, 64) = 784
pread64(3, "\4\0\0\0\20\0\0\0\5\0\0\0GNU\0\2\0\0\300\4\0\0\0\3\0\0\0\0\0\0\0", 32, 848) = 32
pread64(3, "\4\0\0\0\24\0\0\0\3\0\0\0GNU\0\t\233\222%\274\260\320\31\331\326\10\204\276X>\263"..., 68, 880) = 68
fstat(3, {st_mode=S_IFREG|0755, st_size=2029224, ...}) = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fca76a06000
pread64(3, "\6\0\0\0\4\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0"..., 784, 64) = 784
pread64(3, "\4\0\0\0\20\0\0\0\5\0\0\0GNU\0\2\0\0\300\4\0\0\0\3\0\0\0\0\0\0\0", 32, 848) = 32
pread64(3, "\4\0\0\0\24\0\0\0\3\0\0\0GNU\0\t\233\222%\274\260\320\31\331\326\10\204\276X>\263"..., 68, 880) = 68
mmap(NULL, 2036952, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7fca76814000
mprotect(0x7fca76839000, 1847296, PROT_NONE) = 0
mmap(0x7fca76839000, 1540096, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x25000) = 0x7fca76839000
mmap(0x7fca769b1000, 303104, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x19d000) = 0x7fca769b1000
mmap(0x7fca769fc000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1e7000) = 0x7fca769fc000
mmap(0x7fca76a02000, 13528, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7fca76a02000
close(3) = 0
arch_prctl(ARCH_SET_FS, 0x7fca76a07580) = 0
mprotect(0x7fca769fc000, 12288, PROT_READ) = 0
mprotect(0x561661751000, 4096, PROT_READ) = 0
mprotect(0x7fca76a4c000, 4096, PROT_READ) = 0
munmap(0x7fca76a08000, 92122) = 0
chdir("/proc") = 0
openat(AT_FDCWD, ".", O_RDONLY|O_NONBLOCK|O_CLOEXEC|O_DIRECTORY) = 3
fstat(3, {st_mode=S_IFDIR|0555, st_size=0, ...}) = 0
brk(NULL) = 0x56166273e000
brk(0x56166275f000) = 0x56166275f000
getdents64(3, /* 418 entries */, 32768) = 10968
openat(AT_FDCWD, "1/stat", O_RDONLY) = 4
fstat(4, {st_mode=S_IFREG|0444, st_size=0, ...}) = 0
read(4, "1 (systemd) S 0 1 1 0 -1 4194560"..., 4096) = 190
read(4, "", 3072) = 0
close(4) = 0
openat(AT_FDCWD, "1/cmdline", O_RDONLY) = 4
fstat(4, {st_mode=S_IFREG|0444, st_size=0, ...}) = 0
read(4, "/sbin/init\0splash\0", 1024) = 18
close(4) = 0
stat("/proc/1/exe", 0x7ffe62bf8900) = -1 EACCES (Permission denied)
readlink("/proc/1/exe", 0x7ffe62bf99b0, 4096) = -1 EACCES (Permission denied)
openat(AT_FDCWD, "2/stat", O_RDONLY) = 4
fstat(4, {st_mode=S_IFREG|0444, st_size=0, ...}) = 0
read(4, "2 (kthreadd) S 0 0 0 0 -1 212998"..., 4096) = 150
read(4, "", 3072) = 0
close(4) = 0
openat(AT_FDCWD, "2/cmdline", O_RDONLY) = 4
fstat(4, {st_mode=S_IFREG|0444, st_size=0, ...}) = 0
read(4, "", 1024) = 0
close(4) = 0
stat("/proc/2/exe", 0x7ffe62bf8900) = -1 EACCES (Permission denied)
readlink("/proc/2/exe", 0x7ffe62bf99b0, 4096) = -1 EACCES (Permission denied)
openat(AT_FDCWD, "3/stat", O_RDONLY) = 4
fstat(4, {st_mode=S_IFREG|0444, st_size=0, ...}) = 0
read(4, "3 (rcu_gp) I 2 0 0 0 -1 69238880"..., 4096) = 151
read(4, "", 3072) = 0
close(4) = 0
openat(AT_FDCWD, "3/cmdline", O_RDONLY) = 4
fstat(4, {st_mode=S_IFREG|0444, st_size=0, ...}) = 0
read(4, "", 1024) = 0
close(4) = 0
stat("/proc/3/exe", 0x7ffe62bf8900) = -1 EACCES (Permission denied)
readlink("/proc/3/exe", 0x7ffe62bf99b0, 4096) = -1 EACCES (Permission denied)
openat(AT_FDCWD, "4/stat", O_RDONLY) = 4
fstat(4, {st_mode=S_IFREG|0444, st_size=0, ...}) = 0
read(4, "4 (rcu_par_gp) I 2 0 0 0 -1 6923"..., 4096) = 155
read(4, "", 3072) = 0
close(4) = 0
openat(AT_FDCWD, "4/cmdline", O_RDONLY) = 4
fstat(4, {st_mode=S_IFREG|0444, st_size=0, ...}) = 0
read(4, "", 1024) = 0
close(4) = 0
stat("/proc/4/exe", 0x7ffe62bf8900) = -1 EACCES (Permission denied)
readlink("/proc/4/exe", 0x7ffe62bf99b0, 4096) = -1 EACCES (Permission denied)
openat(AT_FDCWD, "6/stat", O_RDONLY) = 4
fstat(4, {st_mode=S_IFREG|0444, st_size=0, ...}) = 0
...
```
---
## CHARACTER DEVICE DRIVERS
• try_module_get(THIS_MODULE): Increment the use count.
• module_put(THIS_MODULE): Decrement the use count.
---
## Related
[linux2021 - J06: fibdrv](https://hackmd.io/@sysprog/linux2021-fibdrv#J06-fibdrv)