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