├── 000_test_module ├── Makefile ├── ReadMe.txt └── test_module.c ├── 001_hello_api ├── Makefile ├── README.md └── hello.c ├── 002_get_fs_type ├── Makefile └── get_fs_type.c ├── 003_list_super_block ├── Makefile ├── README.md └── list_super_block.c ├── 005_list_all_file_system_type ├── Makefile ├── README.md └── list_all_file_system_type.c ├── 006_register_unregister_filesystem ├── Makefile ├── ReadMe.txt └── register_unregister_filesystem.c ├── 007_sysfs_api ├── Makefile ├── ReadMe.txt ├── a.out ├── sysfs.c └── sysfs_api.c ├── 008_find_module ├── Makefile ├── ReadMe.txt └── find_module.c ├── 009_module_is_alive ├── Makefile ├── ReadMe.txt └── module_is_live.c ├── 010_try_module_get ├── Makefile ├── ReadMe.txt └── try_module_get.c ├── 011_ref_module ├── Makefile ├── ReadMe.txt └── ref_module.c ├── 012_module_put ├── Makefile ├── ReadMe.txt └── module_put.c ├── 013_atomic_t ├── Makefile ├── ReadMe.txt ├── atomic_t.c └── test_int_and_long.c ├── 014_get_max_files ├── Makefile ├── ReadMe.txt └── get_max_files.c ├── 015_get_super ├── Makefile ├── README.md └── get_super.c ├── clean.sh ├── create_new_example.sh ├── h001_list_modules ├── Makefile ├── ReadMe.txt └── list_module.c ├── h002_list_all_super_block ├── Makefile ├── README.md └── list_all_super_block.c ├── h003_list_all_process ├── Makefile ├── README.md └── list_all_process.c ├── h004_list_inode ├── Makefile ├── README.md └── list_inode.c ├── h005_list_directory_contents ├── Makefile ├── README.md └── list_directory_contents.c ├── h006_ls ├── Makefile ├── README.md └── ls.c ├── h007_task_css_set ├── Makefile ├── README.md ├── result │ ├── 0001.log │ ├── 0002.log │ ├── 0003.log │ ├── 0004.log │ └── 0005.log └── task_css_set.c ├── h008_proc_cgroups ├── Makefile ├── README.md └── proc_cgroups.c ├── h009_init_css_set ├── Makefile ├── README.md └── init_css_set.c ├── h010_calc_load_account_active ├── Makefile ├── README.md └── calc_load_account_active.c ├── h011_proc_mytasks ├── Makefile ├── README.md └── proc_mytasks.c ├── h012_inspect_task_struct ├── Makefile ├── README.md └── inspect_task_struct.c ├── h013_list_all_workqueues ├── Makefile ├── README.md └── list_all_workqueues.c ├── h014_list_all_bdi ├── Makefile ├── README.md └── list_all_bdi.c ├── h015_workqueue ├── Makefile ├── README.md └── myworkqueue.c ├── h016_list_all_percpu_counter ├── Makefile ├── README.md └── list_all_percpu_counter.c ├── h017_roundup_pow_of_two ├── Makefile ├── README.md └── roundup_pow_of_two.c ├── h018_percpu_refcount ├── Makefile ├── README.md └── percpu_refcount.c ├── h019_hweight ├── Makefile ├── README.md └── hweight.c ├── h020_rw_semaphore ├── Makefile ├── README.md └── semaphore_test.c ├── h021_proc_write ├── Makefile ├── README.md └── proc_write.c ├── h022_mem_section ├── Makefile ├── README.md └── mem_section_test.c ├── h023_spin_lock_irq ├── Makefile ├── README.md └── spin_lock_irq_test.c ├── h023_spin_lock_proc ├── Makefile ├── README.md └── spin_lock_proc.c ├── h024_shrink_zone_test ├── Makefile ├── README.md └── shrink_zone_test.c ├── h025_waitqueue ├── Makefile ├── README.md └── mywaitqueue.c ├── h026_css_set_cg_links ├── Makefile ├── README.md └── css_set_cg_links.c ├── h027_cgroup_css_links ├── Makefile ├── README.md └── cgroup_css_links.c ├── h028_debug_mem_cgroup_low ├── Makefile ├── README.md └── debug_mem_cgroup_low.c ├── h029_hlist ├── Makefile ├── README.md └── hlist_test.c ├── h030_radix_tree ├── Makefile ├── README.md └── radix_tree_example.c ├── h031_test_thread_info ├── Makefile ├── README.md └── test_thread_info.c ├── h032_test_current ├── Makefile ├── README.md └── test_current.c ├── h033_mem_cgroup_iter ├── Makefile ├── README.md └── mem_cgroup_iter_test.c ├── h034_my_crash ├── Makefile ├── README.md └── my_crash.c ├── h035_dynamic_printk ├── Makefile ├── README.md └── dynamic_printk.c ├── h036_sched_bug ├── Makefile ├── README.md ├── run.sh └── sched_bug.c ├── h037_my_test_rcu ├── Makefile ├── README.md └── my_test_rcu.c ├── h038_cn_test ├── Makefile ├── README.md ├── cn_test.c └── ucon.c ├── h039_get_cwd_exe ├── Makefile ├── README.md └── get_cwd_exe.c ├── h040_nspid ├── Makefile ├── README.md └── nspid.c ├── h041_show_max_fds ├── Makefile ├── README.md └── show_max_fds.c ├── h042_check_list ├── Makefile ├── README.md └── check_list.c ├── h043_hack_meminfo ├── Makefile ├── README.md └── hack_meminfo.c ├── h044_test_xarray ├── Makefile ├── README.md └── test_xarray.c ├── h045_test_xarray ├── Makefile ├── README.md └── test_xarray.c ├── h046_test_jiffies ├── Makefile ├── README.md └── test_jiffies.c ├── h047_test_timer ├── Makefile ├── README.md ├── main.c └── test_timer.c ├── h048_print_mem_cgroup ├── Makefile ├── README.md └── print_mem_cgroup_stat.c ├── h049_test_hlist_head ├── Makefile ├── README.md └── test_hlist_head.c ├── h050_drop_caches ├── Makefile ├── README.md └── drop_caches.c ├── h051_test_irq_cpu_on_off ├── Makefile ├── README.md ├── a.sh └── test_irq.c ├── h054_print_mem_cgroup_stat ├── Makefile ├── README.md └── print_mem_cgroup_stat.c ├── h055_per_cpu ├── Makefile ├── README.md └── test_per_cpu.c ├── h056_test_cap_sys_admin ├── Makefile ├── README.md └── test_cap_sys_admin.c ├── h057_add_mycatget_call ├── Makefile ├── README.md └── mycapset_call.c ├── h058_add_new_syscall ├── Makefile ├── README.md ├── add_new_syscall.c └── test.c ├── h059_add_new_syscall2 ├── Makefile ├── README.md ├── add_new_syscall.c └── test.c ├── h060_add_new_syscall3 ├── Makefile ├── README.md ├── add_new_syscall.c └── test.c ├── h061_test_set_fs ├── Makefile ├── README.md └── read_write_userspace.c ├── h062_test_kernel_read_write ├── Makefile ├── README.md └── read_write_userspace.c ├── h063_test_file_fop ├── Makefile ├── README.md └── read_write_userspace.c ├── m001 ├── Makefile ├── README.md └── up_sem.c ├── m002_test_kallsyms_lookup_name ├── Makefile ├── README.md └── test_kallsyms_lookup_name.c ├── m003_test_printf ├── Makefile ├── README.md └── test_printf.c ├── m004_test_rh_mark_used_feature ├── Makefile ├── README.md └── test_rh_mark_used_feature.c └── m005_test_linux_version_code ├── Makefile ├── README.md └── test_linux_version_code.c /000_test_module/Makefile: -------------------------------------------------------------------------------- 1 | ifneq ($(KERNELRELEASE), ) 2 | obj-m := test_module.o 3 | else 4 | KERNELDIR ?=/lib/modules/$(shell uname -r)/build 5 | PWD := $(shell pwd) 6 | all: 7 | $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 8 | clean: 9 | $(MAKE) -C $(KERNELDIR) M=$(PWD) clean 10 | endif 11 | -------------------------------------------------------------------------------- /000_test_module/ReadMe.txt: -------------------------------------------------------------------------------- 1 | this module is just for test some api. 2 | -------------------------------------------------------------------------------- /000_test_module/test_module.c: -------------------------------------------------------------------------------- 1 | /*********************************************** 2 | * module : test_module 3 | * 4 | * datawolf (wanglong@cse.buaa.edu.cn) 5 | **********************************************/ 6 | #include 7 | #include 8 | #include 9 | 10 | static int __init test_module_init(void) 11 | { 12 | printk(KERN_ALERT "[Hello] test_module \n"); 13 | return 0; 14 | } 15 | 16 | static void __exit test_module_exit(void) 17 | { 18 | printk(KERN_ALERT "[Goodbye] test_module\n"); 19 | } 20 | 21 | module_init(test_module_init); 22 | module_exit(test_module_exit); 23 | MODULE_LICENSE("GPL"); 24 | MODULE_AUTHOR("datawolf"); 25 | -------------------------------------------------------------------------------- /001_hello_api/Makefile: -------------------------------------------------------------------------------- 1 | ifneq ($(KERNELRELEASE), ) 2 | obj-m := hello.o 3 | else 4 | KERNELDIR ?=/lib/modules/$(shell uname -r)/build 5 | PWD := $(shell pwd) 6 | all: 7 | $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 8 | clean: 9 | $(MAKE) -C $(KERNELDIR) M=$(PWD) clean 10 | load: 11 | @sudo dmesg -c > /dev/null 12 | @echo "#############[START] #################" 13 | @sudo insmod hello.ko 14 | @sudo dmesg 15 | unload: 16 | @sudo dmesg -c > /dev/null 17 | @sudo rmmod hello 18 | @sudo dmesg 19 | @echo "#############[ END ] #################" 20 | test: 21 | @make load 22 | @make unload 23 | endif 24 | -------------------------------------------------------------------------------- /001_hello_api/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawolf/dive-in-kernel/663175ee02d5d976b289bdc64a23f70fefc4368f/001_hello_api/README.md -------------------------------------------------------------------------------- /001_hello_api/hello.c: -------------------------------------------------------------------------------- 1 | /*********************************************** 2 | * module : hello 3 | * 4 | * Wang Long (w@laoqinren.net) 5 | **********************************************/ 6 | #include 7 | #include 8 | #include 9 | 10 | static int __init hello_init(void) 11 | { 12 | printk(KERN_ALERT "[Hello] hello \n"); 13 | return 0; 14 | } 15 | 16 | static void __exit hello_exit(void) 17 | { 18 | printk(KERN_ALERT "[Goodbye] hello\n"); 19 | } 20 | 21 | module_init(hello_init); 22 | module_exit(hello_exit); 23 | MODULE_LICENSE("GPL"); 24 | -------------------------------------------------------------------------------- /002_get_fs_type/Makefile: -------------------------------------------------------------------------------- 1 | ifneq ($(KERNELRELEASE), ) 2 | obj-m := get_fs_type.o 3 | else 4 | KERNELDIR ?=/lib/modules/$(shell uname -r)/build 5 | PWD := $(shell pwd) 6 | all: 7 | $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 8 | clean: 9 | $(MAKE) -C $(KERNELDIR) M=$(PWD) clean 10 | endif 11 | -------------------------------------------------------------------------------- /002_get_fs_type/get_fs_type.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | 7 | static int __init get_fs_type_init(void) 8 | { 9 | const char *name = "ext4"; 10 | 11 | struct file_system_type *fst = get_fs_type(name); 12 | 13 | printk(KERN_ALERT "The filesystem's name is : %s\n", fst->name); 14 | return 0; 15 | } 16 | 17 | static void __exit get_fs_type_exit(void) 18 | { 19 | printk(KERN_ALERT "Goodbye get_fs_type\n"); 20 | } 21 | 22 | module_init(get_fs_type_init); 23 | module_exit(get_fs_type_exit); 24 | MODULE_LICENSE("GPL"); 25 | MODULE_AUTHOR("datawolf"); 26 | -------------------------------------------------------------------------------- /003_list_super_block/Makefile: -------------------------------------------------------------------------------- 1 | ifneq ($(KERNELRELEASE), ) 2 | obj-m := list_super_block.o 3 | else 4 | KERNELDIR ?=/lib/modules/$(shell uname -r)/build 5 | PWD := $(shell pwd) 6 | all: 7 | $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 8 | clean: 9 | $(MAKE) -C $(KERNELDIR) M=$(PWD) clean 10 | endif 11 | -------------------------------------------------------------------------------- /003_list_super_block/README.md: -------------------------------------------------------------------------------- 1 | ## 说明 2 | 3 | 该模块可以查看特定的文件系统在linux系统上的所有超级块信息。 4 | 5 | ## 实现说明 6 | 7 | 在linux的数据结构`file_system_type`中,有一个域`fs_supers`链接具有同一种类型的超级快。同一种文件系统类型的超级块通过`s_instances`链接。 8 | 9 | ## 使用方法 10 | 11 | 默认情况下,显示所有类型为ext4的`super_block`信息 12 | 13 | ``` 14 | # dmesg -c 15 | # insmod list_super_block.ko 16 | # rmmod list_super_block 17 | # dmesg 18 | [ 1307.249846] The filesystem's name is : ext4 19 | [ 1307.249870] ****************************************** 20 | [ 1307.249894] The ext4 filesystem is : xvde1 21 | [ 1307.249915] The ext4 filesystem is : xvda1 22 | [ 1315.040887] Goodbye list_super_block 23 | ``` 24 | 25 | 在插入模块时,我们可以指定参数`fs` 26 | 27 | ``` 28 | # dmesg -c 29 | # insmod list_super_block.ko fs="proc" 30 | # rmmod list_super_block 31 | # dmesg 32 | [ 1509.699923] The filesystem's name is : proc 33 | [ 1509.700322] ****************************************** 34 | [ 1509.700346] The proc filesystem is : proc 35 | [ 1509.701017] The proc filesystem is : proc 36 | [ 1509.701364] The proc filesystem is : proc 37 | [ 1514.676233] Goodbye list_super_block 38 | ``` 39 | -------------------------------------------------------------------------------- /003_list_super_block/list_super_block.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | static char *fs = "ext4"; 8 | module_param(fs, charp, 0); 9 | static int __init list_super_block_init(void) 10 | { 11 | struct super_block *sb; 12 | //找到ext4的文件系统类型描述结构体 13 | struct file_system_type *fst = get_fs_type(fs); 14 | 15 | printk(KERN_ALERT "The filesystem's name is : %s\n", fst->name); 16 | 17 | printk(KERN_ALERT "******************************************"); 18 | //遍历所有的ext4超级快 19 | hlist_for_each_entry(sb, &fst->fs_supers, s_instances) 20 | { 21 | printk(KERN_ALERT "The %s filesystem is : %s\n", fs, sb->s_id); 22 | } 23 | return 0; 24 | } 25 | 26 | static void __exit list_super_block_exit(void) 27 | { 28 | printk(KERN_ALERT "Goodbye list_super_block\n"); 29 | } 30 | 31 | module_init(list_super_block_init); 32 | module_exit(list_super_block_exit); 33 | MODULE_LICENSE("GPL"); 34 | MODULE_AUTHOR("datawolf"); 35 | -------------------------------------------------------------------------------- /005_list_all_file_system_type/Makefile: -------------------------------------------------------------------------------- 1 | ifneq ($(KERNELRELEASE), ) 2 | obj-m := list_all_file_system_type.o 3 | else 4 | KERNELDIR ?=/lib/modules/$(shell uname -r)/build 5 | PWD := $(shell pwd) 6 | all: 7 | $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 8 | clean: 9 | $(MAKE) -C $(KERNELDIR) M=$(PWD) clean 10 | endif 11 | -------------------------------------------------------------------------------- /005_list_all_file_system_type/README.md: -------------------------------------------------------------------------------- 1 | ## 说明 2 | 3 | 被linux支持的文件系统,都有且仅有一个`file_system_type`结构,而不管它有0个或者多个实例被安装到系统中。 4 | 5 | linux内核中通过双向链表来存储`file_system_type`,其头节点文件变量`file_systems`. 6 | 7 | ## 输出结果如下 8 | 9 | ``` 10 | [ 368.965951] list_all_file_system_type: module verification failed: signature and/or required key missing - tainting kernel 11 | [ 368.975237] file system type : sysfs 12 | [ 368.975260] file system type : rootfs 13 | [ 368.975278] file system type : ramfs 14 | [ 368.975296] file system type : bdev 15 | [ 368.975313] file system type : proc 16 | [ 368.975330] file system type : cpuset 17 | [ 368.975348] file system type : cgroup 18 | [ 368.975366] file system type : tmpfs 19 | [ 368.975383] file system type : devtmpfs 20 | [ 368.975401] file system type : debugfs 21 | [ 368.975420] file system type : tracefs 22 | [ 368.975438] file system type : securityfs 23 | [ 368.975458] file system type : sockfs 24 | [ 368.975475] file system type : bpf 25 | [ 368.975492] file system type : pipefs 26 | [ 368.975509] file system type : devpts 27 | [ 368.975527] file system type : ext3 28 | [ 368.975544] file system type : ext2 29 | [ 368.975561] file system type : ext4 30 | [ 368.975578] file system type : squashfs 31 | [ 368.975596] file system type : hugetlbfs 32 | [ 368.975615] file system type : vfat 33 | [ 368.975632] file system type : ecryptfs 34 | [ 368.975655] file system type : fuseblk 35 | [ 368.975673] file system type : fuse 36 | [ 368.975690] file system type : fusectl 37 | [ 368.975708] file system type : pstore 38 | [ 368.975725] file system type : mqueue 39 | [ 368.975743] file system type : btrfs 40 | [ 368.975761] file system type : autofs 41 | [ 368.975778] file system type : binfmt_misc 42 | [ 368.975798] file system type : aufs 43 | [ 374.655221] [goodbye] list_all_file_system_type 44 | ``` 45 | -------------------------------------------------------------------------------- /005_list_all_file_system_type/list_all_file_system_type.c: -------------------------------------------------------------------------------- 1 | /*********************************************** 2 | * module : list_all_file_system_type 3 | * 4 | * datawolf (wanglong@cse.buaa.edu.cn) 5 | **********************************************/ 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | static int __init list_all_file_system_type_init(void) 13 | { 14 | struct file_system_type **fs = (struct file_system_type **)kallsyms_lookup_name("file_systems"); 15 | while (*fs){ 16 | printk(KERN_ALERT "file system type : %s\n", (*fs)->name); 17 | fs = &(*fs)->next; 18 | } 19 | 20 | return 0; 21 | } 22 | 23 | static void __exit list_all_file_system_type_exit(void) 24 | { 25 | printk(KERN_ALERT "[goodbye] list_all_file_system_type\n"); 26 | } 27 | 28 | module_init(list_all_file_system_type_init); 29 | module_exit(list_all_file_system_type_exit); 30 | MODULE_LICENSE("GPL"); 31 | MODULE_AUTHOR("datawolf"); 32 | -------------------------------------------------------------------------------- /006_register_unregister_filesystem/Makefile: -------------------------------------------------------------------------------- 1 | ifneq ($(KERNELRELEASE), ) 2 | obj-m := register_unregister_filesystem.o 3 | else 4 | KERNELDIR ?=/lib/modules/$(shell uname -r)/build 5 | PWD := $(shell pwd) 6 | all: 7 | $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 8 | clean: 9 | $(MAKE) -C $(KERNELDIR) M=$(PWD) clean 10 | endif 11 | -------------------------------------------------------------------------------- /006_register_unregister_filesystem/ReadMe.txt: -------------------------------------------------------------------------------- 1 | 执行结果如下: 2 | 3 | [root@localhost 006_register_unregister_filesystem]# dmesg -c 4 | [Hello] register_unregister_filesystem 5 | Register filesystem failed 6 | Unregister filesystem successfully 7 | The name of the Unregister filesystem is ext4 8 | Register filesystem successfully 9 | The name of the Register filesystem is ext4 10 | 11 | -------------------------------------------------------------------------------- /006_register_unregister_filesystem/register_unregister_filesystem.c: -------------------------------------------------------------------------------- 1 | /*********************************************** 2 | * module : register_unregister_filesystem 3 | * 4 | * datawolf (wanglong@cse.buaa.edu.cn) 5 | **********************************************/ 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | static int __init register_unregister_filesystem_init(void) 12 | { 13 | const char *name = "ext4"; 14 | struct file_system_type *fst = get_fs_type(name); 15 | 16 | printk(KERN_ALERT "[Hello] register_unregister_filesystem \n"); 17 | //注册文件系统名为ext4的文件系统 18 | if (register_filesystem(fst) == 0) 19 | { 20 | printk(KERN_ALERT "Register filesystem successfully\n"); 21 | printk(KERN_ALERT "The name of the Register filesystem is %s\n", fst->name); 22 | }else 23 | { 24 | printk(KERN_ALERT "Register filesystem failed\n"); 25 | } 26 | 27 | 28 | //注销文件系统名为ext4的文件系统 29 | if (unregister_filesystem(fst) == 0) 30 | { 31 | printk(KERN_ALERT "Unregister filesystem successfully\n"); 32 | printk(KERN_ALERT "The name of the Unregister filesystem is %s\n", fst->name); 33 | }else 34 | { 35 | printk(KERN_ALERT "Unregister filesystem failed\n"); 36 | } 37 | 38 | //重新注册文件系统名为ext4的文件系统 39 | if (register_filesystem(fst) == 0) 40 | { 41 | printk(KERN_ALERT "Register filesystem successfully\n"); 42 | printk(KERN_ALERT "The name of the Register filesystem is %s\n", fst->name); 43 | }else 44 | { 45 | printk(KERN_ALERT "Register filesystem failed\n"); 46 | } 47 | 48 | return 0; 49 | } 50 | 51 | static void __exit register_unregister_filesystem_exit(void) 52 | { 53 | printk(KERN_ALERT "[Goodbye] register_unregister_filesystem\n"); 54 | } 55 | 56 | module_init(register_unregister_filesystem_init); 57 | module_exit(register_unregister_filesystem_exit); 58 | MODULE_LICENSE("GPL"); 59 | MODULE_AUTHOR("datawolf"); 60 | -------------------------------------------------------------------------------- /007_sysfs_api/Makefile: -------------------------------------------------------------------------------- 1 | ifneq ($(KERNELRELEASE), ) 2 | obj-m := sysfs_api.o 3 | else 4 | KERNELDIR ?=/lib/modules/$(shell uname -r)/build 5 | PWD := $(shell pwd) 6 | all: 7 | $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 8 | clean: 9 | $(MAKE) -C $(KERNELDIR) M=$(PWD) clean 10 | endif 11 | -------------------------------------------------------------------------------- /007_sysfs_api/ReadMe.txt: -------------------------------------------------------------------------------- 1 | [root@localhost] # cat /proc/filesystem 2 | nodev sysfs 3 | nodev rootfs 4 | nodev bdev 5 | nodev proc 6 | nodev cgroup 7 | nodev cpuset 8 | nodev tmpfs 9 | nodev devtmpfs 10 | nodev binfmt_misc 11 | nodev debugfs 12 | nodev securityfs 13 | nodev sockfs 14 | nodev usbfs 15 | nodev pipefs 16 | nodev anon_inodefs 17 | nodev devpts 18 | nodev ramfs 19 | nodev hugetlbfs 20 | iso9660 21 | nodev mqueue 22 | ext4 23 | ------------------------------------------------- 24 | there are 21 file systems. 25 | so the sysfs(3) return the number of 21. 26 | 27 | 28 | 29 | --------------------------------------------------- 30 | sysfs.c的执行结果: 31 | The total number of file system in the kernel is 0. 32 | The ext4 file system type index is 20 33 | The file system which index is 0 identifier string is : sysfs 34 | The file system which index is 1 identifier string is : rootfs 35 | The file system which index is 2 identifier string is : bdev 36 | The file system which index is 3 identifier string is : proc 37 | The file system which index is 4 identifier string is : cgroup 38 | The file system which index is 5 identifier string is : cpuset 39 | The file system which index is 6 identifier string is : tmpfs 40 | The file system which index is 7 identifier string is : devtmpfs 41 | The file system which index is 8 identifier string is : binfmt_misc 42 | The file system which index is 9 identifier string is : debugfs 43 | The file system which index is 10 identifier string is : securityfs 44 | The file system which index is 11 identifier string is : sockfs 45 | The file system which index is 12 identifier string is : usbfs 46 | The file system which index is 13 identifier string is : pipefs 47 | The file system which index is 14 identifier string is : anon_inodefs 48 | The file system which index is 15 identifier string is : devpts 49 | The file system which index is 16 identifier string is : ramfs 50 | The file system which index is 17 identifier string is : hugetlbfs 51 | The file system which index is 18 identifier string is : iso9660 52 | The file system which index is 19 identifier string is : mqueue 53 | The file system which index is 20 identifier string is : ext4 54 | -------------------------------------------------------------------------------- /007_sysfs_api/a.out: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawolf/dive-in-kernel/663175ee02d5d976b289bdc64a23f70fefc4368f/007_sysfs_api/a.out -------------------------------------------------------------------------------- /007_sysfs_api/sysfs.c: -------------------------------------------------------------------------------- 1 | #define _GNU_SOURCE 2 | #include 3 | #include 4 | #include 5 | 6 | int main(int argc, char **argv) 7 | { 8 | int num, index; 9 | int num_fs; 10 | const char *fsname = "ext4"; 11 | char buf[40]; 12 | unsigned int fs_index = 0; 13 | 14 | num_fs = syscall(SYS_sysfs, 3); 15 | printf("The total number of file system in the kernel is %d.\n", num); 16 | 17 | index = syscall(SYS_sysfs, 1, fsname); 18 | printf("The ext4 file system type index is %d\n", index); 19 | 20 | for (; fs_index < num_fs + 1; fs_index++){ 21 | num = syscall(SYS_sysfs, 2, fs_index, buf); 22 | if (num == -1 ) 23 | perror("syscall"); 24 | else 25 | printf("The file system which index is %d identifier string is : %s\n",fs_index, buf); 26 | } 27 | 28 | return 0; 29 | } 30 | -------------------------------------------------------------------------------- /007_sysfs_api/sysfs_api.c: -------------------------------------------------------------------------------- 1 | /*********************************************** 2 | * module : sysfs_api 3 | * 4 | * datawolf (wanglong@cse.buaa.edu.cn) 5 | **********************************************/ 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | static int __init sysfs_api_init(void) 12 | { 13 | printk(KERN_ALERT "[Hello] sysfs_api \n"); 14 | printk(KERN_ALERT "the number of file system in the kernel is %d", sysfs(3)); 15 | return 0; 16 | } 17 | 18 | static void __exit sysfs_api_exit(void) 19 | { 20 | printk(KERN_ALERT "[Goodbye] sysfs_api\n"); 21 | } 22 | 23 | module_init(sysfs_api_init); 24 | module_exit(sysfs_api_exit); 25 | MODULE_LICENSE("GPL"); 26 | MODULE_AUTHOR("datawolf"); 27 | -------------------------------------------------------------------------------- /008_find_module/Makefile: -------------------------------------------------------------------------------- 1 | ifneq ($(KERNELRELEASE), ) 2 | obj-m := find_module.o 3 | else 4 | KERNELDIR ?=/lib/modules/$(shell uname -r)/build 5 | PWD := $(shell pwd) 6 | all: 7 | $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 8 | clean: 9 | $(MAKE) -C $(KERNELDIR) M=$(PWD) clean 10 | endif 11 | -------------------------------------------------------------------------------- /008_find_module/ReadMe.txt: -------------------------------------------------------------------------------- 1 | find_module用来获取一个指向模块的指针。 2 | -------------------------------------------------------------------------------- /008_find_module/find_module.c: -------------------------------------------------------------------------------- 1 | /*********************************************** 2 | * module : find_module 3 | * 4 | * datawolf (wanglong@cse.buaa.edu.cn) 5 | **********************************************/ 6 | #include 7 | #include 8 | #include 9 | 10 | static int __init find_module_init(void) 11 | { 12 | const char *name = "ext3"; 13 | struct module * fmodule = find_module(name); 14 | 15 | printk(KERN_ALERT "[Hello] find_module \n"); 16 | 17 | if (fmodule != NULL){ 18 | printk(KERN_ALERT "fmodule->name: %s\n", fmodule->name); 19 | printk(KERN_ALERT "fmodule->state: %d\n", fmodule->state); 20 | printk(KERN_ALERT "fmodule->core_size: %d\n", fmodule->core_size); 21 | printk(KERN_ALERT "module_refcount(fmodule): %d\n", module_refcount(fmodule)); 22 | } 23 | 24 | name = "ext4"; 25 | fmodule = find_module(name); 26 | 27 | if (fmodule != NULL){ 28 | printk(KERN_ALERT "fmodule->name: %s\n", fmodule->name); 29 | printk(KERN_ALERT "fmodule->state: %d\n", fmodule->state); 30 | printk(KERN_ALERT "fmodule->core_size: %d\n", fmodule->core_size); 31 | printk(KERN_ALERT "module_refcount(fmodule): %d\n", module_refcount(fmodule)); 32 | } 33 | 34 | return 0; 35 | } 36 | 37 | static void __exit find_module_exit(void) 38 | { 39 | printk(KERN_ALERT "[Goodbye] find_module\n"); 40 | } 41 | 42 | module_init(find_module_init); 43 | module_exit(find_module_exit); 44 | MODULE_LICENSE("GPL"); 45 | MODULE_AUTHOR("datawolf"); 46 | -------------------------------------------------------------------------------- /009_module_is_alive/Makefile: -------------------------------------------------------------------------------- 1 | ifneq ($(KERNELRELEASE), ) 2 | obj-m := module_is_live.o 3 | else 4 | KERNELDIR ?=/lib/modules/$(shell uname -r)/build 5 | PWD := $(shell pwd) 6 | all: 7 | $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 8 | clean: 9 | $(MAKE) -C $(KERNELDIR) M=$(PWD) clean 10 | endif 11 | -------------------------------------------------------------------------------- /009_module_is_alive/ReadMe.txt: -------------------------------------------------------------------------------- 1 | module_is_live 函数判断module是否处于活动状态。 2 | 3 | [root@localhost 009_module_is_alive]# dmesg 4 | [root@localhost 009_module_is_alive]# insmod module_is_live.ko 5 | [root@localhost 009_module_is_alive]# dmesg 6 | [Hello] module_is_live 7 | in init , state is not GOING 8 | [root@localhost 009_module_is_alive]# rmmod module_is_live.ko 9 | [root@localhost 009_module_is_alive]# dmesg 10 | [Hello] module_is_live 11 | in init , state is not GOING 12 | in exit, state is GOING 13 | [Goodbye] module_is_live 14 | 15 | -------------------------------------------------------------------------------- /009_module_is_alive/module_is_live.c: -------------------------------------------------------------------------------- 1 | /*********************************************** 2 | * module : module_is_live 3 | * 4 | * datawolf (wanglong@cse.buaa.edu.cn) 5 | **********************************************/ 6 | #include 7 | #include 8 | #include 9 | 10 | 11 | static int ret; 12 | 13 | static int __init module_is_live_init(void) 14 | { 15 | printk(KERN_ALERT "[Hello] module_is_live \n"); 16 | 17 | ret = module_is_live(THIS_MODULE); 18 | 19 | if (ret == 1){ 20 | printk(KERN_ALERT "in init , state is not GOING\n"); 21 | }else{ 22 | printk(KERN_ALERT "in init , state is GOING \n"); 23 | } 24 | return 0; 25 | } 26 | 27 | static void __exit module_is_live_exit(void) 28 | { 29 | ret = module_is_live(THIS_MODULE); 30 | 31 | if (ret == 1){ 32 | printk(KERN_ALERT "in exit, state is not GOING\n"); 33 | }else{ 34 | printk(KERN_ALERT "in exit, state is GOING \n"); 35 | } 36 | 37 | printk(KERN_ALERT "[Goodbye] module_is_live\n"); 38 | } 39 | 40 | module_init(module_is_live_init); 41 | module_exit(module_is_live_exit); 42 | MODULE_LICENSE("GPL"); 43 | MODULE_AUTHOR("datawolf"); 44 | -------------------------------------------------------------------------------- /010_try_module_get/Makefile: -------------------------------------------------------------------------------- 1 | ifneq ($(KERNELRELEASE), ) 2 | obj-m := try_module_get.o 3 | else 4 | KERNELDIR ?=/lib/modules/$(shell uname -r)/build 5 | PWD := $(shell pwd) 6 | all: 7 | $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 8 | clean: 9 | $(MAKE) -C $(KERNELDIR) M=$(PWD) clean 10 | endif 11 | -------------------------------------------------------------------------------- /010_try_module_get/ReadMe.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawolf/dive-in-kernel/663175ee02d5d976b289bdc64a23f70fefc4368f/010_try_module_get/ReadMe.txt -------------------------------------------------------------------------------- /010_try_module_get/try_module_get.c: -------------------------------------------------------------------------------- 1 | /*********************************************** 2 | * module : try_module_get 3 | * 4 | * datawolf (wanglong@cse.buaa.edu.cn) 5 | **********************************************/ 6 | #include 7 | #include 8 | #include 9 | 10 | static int __init try_module_get_init(void) 11 | { 12 | int ret; 13 | const char *name; 14 | struct module *fmodule; 15 | 16 | printk(KERN_ALERT "[Hello] try_module_get \n"); 17 | 18 | name = "test_module"; 19 | fmodule = find_module(name); 20 | 21 | if (fmodule != NULL){ 22 | printk(KERN_ALERT "before calling try_module_get,\n"); 23 | printk(KERN_ALERT "refs of %s is : %d\n", name, module_refcount(fmodule)); 24 | ret = try_module_get(fmodule); 25 | printk(KERN_ALERT "after calling try_module_get,\n"); 26 | printk(KERN_ALERT "ret = %d\n", ret); 27 | printk(KERN_ALERT "refs of %s is : %d\n", name, module_refcount(fmodule)); 28 | } 29 | return 0; 30 | } 31 | 32 | static void __exit try_module_get_exit(void) 33 | { 34 | printk(KERN_ALERT "[Goodbye] try_module_get\n"); 35 | } 36 | 37 | module_init(try_module_get_init); 38 | module_exit(try_module_get_exit); 39 | MODULE_LICENSE("GPL"); 40 | MODULE_AUTHOR("datawolf"); 41 | -------------------------------------------------------------------------------- /011_ref_module/Makefile: -------------------------------------------------------------------------------- 1 | ifneq ($(KERNELRELEASE), ) 2 | obj-m := ref_module.o 3 | else 4 | KERNELDIR ?=/lib/modules/$(shell uname -r)/build 5 | PWD := $(shell pwd) 6 | all: 7 | $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 8 | clean: 9 | $(MAKE) -C $(KERNELDIR) M=$(PWD) clean 10 | endif 11 | -------------------------------------------------------------------------------- /011_ref_module/ReadMe.txt: -------------------------------------------------------------------------------- 1 | ref_module 实现模块a使用模块b,同时将模块b的引用计数加一。 2 | 3 | 4 | linux 2.6.35 中include/linux/module.h中没有ref_module的声明,需要自己添加。 5 | 6 | [root@localhost 011_ref_module]# lsmod | head -4 7 | Module Size Used by 8 | test_module 847 1 9 | ext3 132801 1 10 | jbd 50559 1 ext3 11 | [root@localhost 011_ref_module]# insmod ref_module.ko 12 | [root@localhost 011_ref_module]# lsmod | head -4 13 | Module Size Used by 14 | ref_module 942 0 15 | test_module 847 2 ref_module 16 | ext3 132801 1 17 | [root@localhost 011_ref_module]# rmmod ref_module 18 | [root@localhost 011_ref_module]# lsmod | head -4 19 | Module Size Used by 20 | test_module 847 1 21 | ext3 132801 1 22 | jbd 50559 1 ext3 23 | 24 | -------------------------------------------------------------------------------- /011_ref_module/ref_module.c: -------------------------------------------------------------------------------- 1 | /*********************************************** 2 | * module : ref_module 3 | * 4 | * datawolf (wanglong@cse.buaa.edu.cn) 5 | **********************************************/ 6 | #include 7 | #include 8 | #include 9 | 10 | static int __init ref_module_init(void) 11 | { 12 | struct module *b; 13 | const char *name = "test_module"; 14 | int ret; 15 | printk(KERN_ALERT "[Hello] ref_module \n"); 16 | 17 | b = find_module(name); 18 | 19 | if (b != NULL){ 20 | printk(KERN_ALERT "before calling ref_module,\n"); 21 | printk(KERN_ALERT "refs of %s is : %d\n", name, module_refcount(b)); 22 | ret = ref_module(THIS_MODULE, b); 23 | printk(KERN_ALERT "ret = %d\n", ret); 24 | printk(KERN_ALERT "after calling ref_module,\n"); 25 | printk(KERN_ALERT "refs of %s is : %d\n", name, module_refcount(b)); 26 | } 27 | return 0; 28 | } 29 | 30 | static void __exit ref_module_exit(void) 31 | { 32 | printk(KERN_ALERT "[Goodbye] ref_module\n"); 33 | } 34 | 35 | module_init(ref_module_init); 36 | module_exit(ref_module_exit); 37 | MODULE_LICENSE("GPL"); 38 | MODULE_AUTHOR("datawolf"); 39 | -------------------------------------------------------------------------------- /012_module_put/Makefile: -------------------------------------------------------------------------------- 1 | ifneq ($(KERNELRELEASE), ) 2 | obj-m := module_put.o 3 | else 4 | KERNELDIR ?=/lib/modules/$(shell uname -r)/build 5 | PWD := $(shell pwd) 6 | all: 7 | $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 8 | clean: 9 | $(MAKE) -C $(KERNELDIR) M=$(PWD) clean 10 | endif 11 | -------------------------------------------------------------------------------- /012_module_put/ReadMe.txt: -------------------------------------------------------------------------------- 1 | module_put 函数将指定模块的引用计数减一。 2 | -------------------------------------------------------------------------------- /012_module_put/module_put.c: -------------------------------------------------------------------------------- 1 | /*********************************************** 2 | * module : module_put 3 | * 4 | * datawolf (wanglong@cse.buaa.edu.cn) 5 | **********************************************/ 6 | #include 7 | #include 8 | #include 9 | 10 | static int __init module_put_init(void) 11 | { 12 | const char *name = "test_module"; 13 | struct module *fname = find_module(name); 14 | printk(KERN_ALERT "[Hello] module_put \n"); 15 | 16 | if (fname != NULL){ 17 | printk(KERN_ALERT "before calling module_put,\n"); 18 | printk(KERN_ALERT "refs of %s is : %d\n", name, module_refcount(fname)); 19 | module_put(fname); 20 | printk(KERN_ALERT "after calling module_put,\n"); 21 | printk(KERN_ALERT "refs of %s is : %d\n", name, module_refcount(fname)); 22 | } 23 | return 0; 24 | } 25 | 26 | static void __exit module_put_exit(void) 27 | { 28 | printk(KERN_ALERT "[Goodbye] module_put\n"); 29 | } 30 | 31 | module_init(module_put_init); 32 | module_exit(module_put_exit); 33 | MODULE_LICENSE("GPL"); 34 | MODULE_AUTHOR("datawolf"); 35 | -------------------------------------------------------------------------------- /013_atomic_t/Makefile: -------------------------------------------------------------------------------- 1 | ifneq ($(KERNELRELEASE), ) 2 | obj-m := atomic_t.o 3 | else 4 | KERNELDIR ?=/lib/modules/$(shell uname -r)/build 5 | PWD := $(shell pwd) 6 | all: 7 | $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 8 | clean: 9 | $(MAKE) -C $(KERNELDIR) M=$(PWD) clean 10 | endif 11 | -------------------------------------------------------------------------------- /013_atomic_t/ReadMe.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawolf/dive-in-kernel/663175ee02d5d976b289bdc64a23f70fefc4368f/013_atomic_t/ReadMe.txt -------------------------------------------------------------------------------- /013_atomic_t/test_int_and_long.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() 4 | { 5 | printf("size(char) = %d\n", sizeof(char)); 6 | printf("size(int) = %d\n", sizeof(int)); 7 | printf("size(double) = %d\n", sizeof(double)); 8 | printf("sizeof(long) = %d\n", sizeof(long)); 9 | printf("sizeof(long long) = %d\n", sizeof(long long)); 10 | 11 | return 0; 12 | } 13 | -------------------------------------------------------------------------------- /014_get_max_files/Makefile: -------------------------------------------------------------------------------- 1 | ifneq ($(KERNELRELEASE), ) 2 | obj-m := get_max_files.o 3 | else 4 | KERNELDIR ?=/lib/modules/$(shell uname -r)/build 5 | PWD := $(shell pwd) 6 | all: 7 | $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 8 | clean: 9 | $(MAKE) -C $(KERNELDIR) M=$(PWD) clean 10 | endif 11 | -------------------------------------------------------------------------------- /014_get_max_files/ReadMe.txt: -------------------------------------------------------------------------------- 1 | get_max_files函数用于返回系统中可以同时打开的最大文件数目。 2 | 3 | 4 | [root@localhost 014_get_max_files]# insmod get_max_files.ko 5 | [root@localhost 014_get_max_files]# dmesg 6 | [Hello] get_max_files 7 | the return value of the get_max_files is 184663. 8 | -------------------------------------------------------------------------------- /014_get_max_files/get_max_files.c: -------------------------------------------------------------------------------- 1 | /*********************************************** 2 | * module : get_max_files 3 | * 4 | * datawolf (wanglong@cse.buaa.edu.cn) 5 | **********************************************/ 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | static int __init get_max_files_init(void) 12 | { 13 | int num_of_max_files; 14 | printk(KERN_ALERT "[Hello] get_max_files \n"); 15 | num_of_max_files = get_max_files(); 16 | printk(KERN_ALERT "the return value of the get_max_files is %d. \n", num_of_max_files); 17 | 18 | return 0; 19 | } 20 | 21 | static void __exit get_max_files_exit(void) 22 | { 23 | printk(KERN_ALERT "[Goodbye] get_max_files\n"); 24 | } 25 | 26 | module_init(get_max_files_init); 27 | module_exit(get_max_files_exit); 28 | MODULE_LICENSE("GPL"); 29 | MODULE_AUTHOR("datawolf"); 30 | -------------------------------------------------------------------------------- /015_get_super/Makefile: -------------------------------------------------------------------------------- 1 | ifneq ($(KERNELRELEASE), ) 2 | obj-m := get_super.o 3 | else 4 | KERNELDIR ?=/lib/modules/$(shell uname -r)/build 5 | PWD := $(shell pwd) 6 | all: 7 | $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 8 | clean: 9 | $(MAKE) -C $(KERNELDIR) M=$(PWD) clean 10 | endif 11 | -------------------------------------------------------------------------------- /015_get_super/README.md: -------------------------------------------------------------------------------- 1 | ## 说明 2 | 3 | 该模块示例了如果通过`current`找到对应的工作目录的所在的文件系统的超级块信息。 4 | 即,说明了`get_super`内核API的使用。 5 | 6 | 7 | ## 运行结果 8 | ``` 9 | root@localhost:015_get_super# dmesg -c 10 | root@localhost:015_get_super# insmod get_super.ko 11 | root@localhost:015_get_super# rmmod get_super 12 | root@localhost:015_get_super# dmesg -c 13 | [ 3086.178329] [Hello] get_super 14 | [ 3086.178830] the super block's dev number is 202:1. 15 | [ 3086.179339] After the "get_super", the super block's dev number is 202:1. 16 | [ 3091.289649] [Goodbye] get_super 17 | ``` 18 | -------------------------------------------------------------------------------- /015_get_super/get_super.c: -------------------------------------------------------------------------------- 1 | /*********************************************** 2 | * module : get_super 3 | * 4 | * datawolf (wanglong@cse.buaa.edu.cn) 5 | **********************************************/ 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | 16 | static int __init get_super_init(void) 17 | { 18 | struct super_block *sb, *sb1; 19 | 20 | sb = current->fs->pwd.dentry->d_sb; 21 | 22 | printk(KERN_ALERT "[Hello] get_super \n"); 23 | printk(KERN_ALERT "the super block's dev number is %d:%d.\n", MAJOR(sb->s_dev), MINOR(sb->s_dev)); 24 | 25 | sb1 = get_super(sb->s_bdev); 26 | if (sb1 != NULL) 27 | printk(KERN_ALERT "After the \"get_super\", the super block's dev number is %d:%d.\n", 28 | MAJOR(sb1->s_dev), MINOR(sb1->s_dev)); 29 | else 30 | printk(KERN_ALERT "Can not be found! \n"); 31 | 32 | 33 | return 0; 34 | } 35 | 36 | static void __exit get_super_exit(void) 37 | { 38 | printk(KERN_ALERT "[Goodbye] get_super\n"); 39 | } 40 | 41 | module_init(get_super_init); 42 | module_exit(get_super_exit); 43 | MODULE_LICENSE("GPL"); 44 | MODULE_AUTHOR("datawolf"); 45 | -------------------------------------------------------------------------------- /clean.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | for file in `ls .` 4 | do 5 | if [ -d $file ] 6 | then 7 | echo "Clean directory "$file "......." 8 | cd $file 9 | make clean > /dev/null 10 | cd - 11 | echo "Clean directory "$file "....... done." 12 | fi 13 | done 14 | -------------------------------------------------------------------------------- /create_new_example.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # This shell scripte create a new directory which name is $1 4 | # and also create two files. 5 | # 6 | # one file is Makefile 7 | # the another file is a c source file 8 | # 9 | # then we can change the c file to complete some job. 10 | # and type "make" to compile the module. 11 | # 12 | # author: datawolf (datawolf@laoqinren.net) 13 | 14 | if [ $# -lt 2 ]; then 15 | echo "Usage: $0 dirname module_name" 16 | exit 1 17 | fi 18 | 19 | DIR=$1 20 | MODULE=$2 21 | 22 | # copy the hello example 23 | cp -r ./001_hello_api $DIR 24 | cd $DIR 25 | 26 | # change the source file name and the Makefile 27 | mv hello.c ${MODULE}.c 28 | sed -i "s/hello/${MODULE}/g" ${MODULE}.c 29 | sed -i "s/hello/${MODULE}/g" Makefile 30 | 31 | cd .. 32 | 33 | -------------------------------------------------------------------------------- /h001_list_modules/Makefile: -------------------------------------------------------------------------------- 1 | ifneq ($(KERNELRELEASE), ) 2 | obj-m := list_module.o 3 | else 4 | KERNELDIR ?=/lib/modules/$(shell uname -r)/build 5 | PWD := $(shell pwd) 6 | all: 7 | $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 8 | clean: 9 | $(MAKE) -C $(KERNELDIR) M=$(PWD) clean 10 | load: 11 | @sudo dmesg -c > /dev/null 12 | @echo "#############[START] #################" 13 | @sudo insmod list_module.ko 14 | @sudo dmesg 15 | unload: 16 | @sudo dmesg -c > /dev/null 17 | @sudo rmmod list_module 18 | @echo "#############[ END ] #################" 19 | test: 20 | @make load 21 | @make unload 22 | endif 23 | -------------------------------------------------------------------------------- /h001_list_modules/ReadMe.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawolf/dive-in-kernel/663175ee02d5d976b289bdc64a23f70fefc4368f/h001_list_modules/ReadMe.txt -------------------------------------------------------------------------------- /h001_list_modules/list_module.c: -------------------------------------------------------------------------------- 1 | /*********************************************** 2 | * module : list_module 3 | * 4 | * datawolf (wanglong@cse.buaa.edu.cn) 5 | **********************************************/ 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | struct module *m = &__this_module; 12 | 13 | static void list_module_test(void) 14 | { 15 | struct module *mod; 16 | list_for_each_entry(mod, m->list.prev, list) 17 | printk ("%s\n", mod->name); 18 | 19 | } 20 | 21 | static int __init list_module_init(void) 22 | { 23 | printk(KERN_ALERT "[Hello] list_module \n"); 24 | list_module_test(); 25 | return 0; 26 | } 27 | 28 | static void __exit list_module_exit(void) 29 | { 30 | printk(KERN_ALERT "[Goodbye] list_module\n"); 31 | } 32 | 33 | module_init(list_module_init); 34 | module_exit(list_module_exit); 35 | MODULE_LICENSE("GPL"); 36 | MODULE_AUTHOR("datawolf"); 37 | -------------------------------------------------------------------------------- /h002_list_all_super_block/Makefile: -------------------------------------------------------------------------------- 1 | ifneq ($(KERNELRELEASE), ) 2 | obj-m := list_all_super_block.o 3 | else 4 | KERNELDIR ?=/lib/modules/$(shell uname -r)/build 5 | PWD := $(shell pwd) 6 | all: 7 | $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 8 | clean: 9 | $(MAKE) -C $(KERNELDIR) M=$(PWD) clean 10 | load: 11 | @sudo dmesg -c > /dev/null 12 | @echo "#############[START] #################" 13 | @sudo insmod list_all_super_block.ko 14 | @sudo dmesg 15 | unload: 16 | @sudo dmesg -c > /dev/null 17 | @sudo rmmod list_all_super_block 18 | @sudo dmesg 19 | @echo "#############[ END ] #################" 20 | test: 21 | @make load 22 | @make unload 23 | endif 24 | -------------------------------------------------------------------------------- /h002_list_all_super_block/list_all_super_block.c: -------------------------------------------------------------------------------- 1 | /*********************************************** 2 | * module : list_all_super_block 3 | * 4 | * Wang Long (wanglong@laoqinren.net) 5 | **********************************************/ 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | static int __init list_all_super_block_init(void) 14 | { 15 | struct super_block *sb; 16 | struct list_head *super_blocks = (struct list_head *)kallsyms_lookup_name("super_blocks"); 17 | 18 | printk(KERN_ALERT "[Hello] list_all_super_block %lx\n", super_blocks); 19 | list_for_each_entry(sb, super_blocks, s_list) { 20 | printk(KERN_INFO "dev_t: %d,%d fs_name: %s name: %s", 21 | MAJOR(sb->s_dev), 22 | MINOR(sb->s_dev), 23 | sb->s_type->name, 24 | sb->s_id); 25 | } 26 | return 0; 27 | } 28 | 29 | static void __exit list_all_super_block_exit(void) 30 | { 31 | printk(KERN_ALERT "[Goodbye] list_all_super_block\n"); 32 | } 33 | 34 | module_init(list_all_super_block_init); 35 | module_exit(list_all_super_block_exit); 36 | MODULE_LICENSE("GPL"); 37 | MODULE_AUTHOR("datawolf"); 38 | -------------------------------------------------------------------------------- /h003_list_all_process/Makefile: -------------------------------------------------------------------------------- 1 | ifneq ($(KERNELRELEASE), ) 2 | obj-m := list_all_process.o 3 | else 4 | KERNELDIR ?=/lib/modules/$(shell uname -r)/build 5 | PWD := $(shell pwd) 6 | all: 7 | $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 8 | clean: 9 | $(MAKE) -C $(KERNELDIR) M=$(PWD) clean 10 | load: 11 | @sudo dmesg -c > /dev/null 12 | @echo "#############[START] #################" 13 | @sudo insmod list_all_process.ko 14 | @sudo dmesg 15 | unload: 16 | @sudo dmesg -c > /dev/null 17 | @sudo rmmod list_all_process 18 | @sudo dmesg 19 | @echo "#############[ END ] #################" 20 | test: 21 | @make load 22 | @make unload 23 | endif 24 | -------------------------------------------------------------------------------- /h003_list_all_process/list_all_process.c: -------------------------------------------------------------------------------- 1 | /*********************************************** 2 | * module : list_all_process 3 | * 4 | * Wang Long (wanglong@laoqinren.net) 5 | **********************************************/ 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | static int __init list_all_process_init(void) 13 | { 14 | struct task_struct *pos; 15 | struct list_head *current_head; 16 | int count = 0; 17 | 18 | printk(KERN_ALERT "[Hello] list_all_process \n"); 19 | current_head = &(current->tasks); 20 | list_for_each_entry(pos, current_head, tasks) 21 | { 22 | count++; 23 | printk(KERN_INFO "[process %d]: %s's pid is %d\n", 24 | count, pos->comm, pos->pid); 25 | } 26 | printk(KERN_INFO "The number of process is %d\n", count); 27 | return 0; 28 | } 29 | 30 | static void __exit list_all_process_exit(void) 31 | { 32 | printk(KERN_ALERT "[Goodbye] list_all_process\n"); 33 | } 34 | 35 | module_init(list_all_process_init); 36 | module_exit(list_all_process_exit); 37 | MODULE_LICENSE("GPL"); 38 | MODULE_AUTHOR("datawolf"); 39 | -------------------------------------------------------------------------------- /h004_list_inode/Makefile: -------------------------------------------------------------------------------- 1 | ifneq ($(KERNELRELEASE), ) 2 | obj-m := list_inode.o 3 | else 4 | KERNELDIR ?=/lib/modules/$(shell uname -r)/build 5 | PWD := $(shell pwd) 6 | all: 7 | $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 8 | clean: 9 | $(MAKE) -C $(KERNELDIR) M=$(PWD) clean 10 | load: 11 | @sudo dmesg -c > /dev/null 12 | @echo "#############[START] #################" 13 | @sudo insmod list_inode.ko 14 | @sudo dmesg 15 | unload: 16 | @sudo dmesg -c > /dev/null 17 | @sudo rmmod list_inode 18 | @sudo dmesg 19 | @echo "#############[ END ] #################" 20 | test: 21 | @make load 22 | @make unload 23 | endif 24 | -------------------------------------------------------------------------------- /h004_list_inode/list_inode.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | static char *fs = "ext4"; 11 | module_param(fs, charp, 0); 12 | static int __init list_inode_init(void) 13 | { 14 | struct super_block *sb; 15 | struct inode *pinode; 16 | struct dentry *pdentry; 17 | //找到ext4的文件系统类型描述结构体 18 | struct file_system_type *fst = get_fs_type(fs); 19 | spinlock_t * lock = (spinlock_t *)kallsyms_lookup_name("sb_lock"); 20 | 21 | printk(KERN_INFO "The filesystem's name is : %s\n", fst->name); 22 | 23 | printk(KERN_INFO "******************************************"); 24 | //遍历所有的ext4超级快 25 | spin_lock(lock); 26 | hlist_for_each_entry(sb, &fst->fs_supers, s_instances) 27 | { 28 | printk(KERN_INFO "The %s filesystem is : %s(%d:%d)\n", fs, sb->s_id, 29 | MAJOR(sb->s_dev), MINOR(sb->s_dev)); 30 | list_for_each_entry(pinode, &sb->s_inodes, i_sb_list) { 31 | printk("%lu [", pinode->i_ino); 32 | hlist_for_each_entry(pdentry, &pinode->i_dentry, d_u.d_alias) { 33 | printk("%s->", pdentry->d_name.name); 34 | } 35 | printk("]\n"); 36 | } 37 | 38 | printk("\n"); 39 | } 40 | spin_unlock(lock); 41 | return 0; 42 | } 43 | 44 | static void __exit list_inode_exit(void) 45 | { 46 | printk(KERN_ALERT "Goodbye list_inode\n"); 47 | } 48 | 49 | module_init(list_inode_init); 50 | module_exit(list_inode_exit); 51 | MODULE_LICENSE("GPL"); 52 | MODULE_AUTHOR("datawolf"); 53 | -------------------------------------------------------------------------------- /h005_list_directory_contents/Makefile: -------------------------------------------------------------------------------- 1 | ifneq ($(KERNELRELEASE), ) 2 | obj-m := list_directory_contents.o 3 | else 4 | KERNELDIR ?=/lib/modules/$(shell uname -r)/build 5 | PWD := $(shell pwd) 6 | all: 7 | $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 8 | clean: 9 | $(MAKE) -C $(KERNELDIR) M=$(PWD) clean 10 | load: 11 | @sudo dmesg -c > /dev/null 12 | @echo "#############[START] #################" 13 | @sudo insmod list_directory_contents.ko 14 | @sudo dmesg 15 | unload: 16 | @sudo dmesg -c > /dev/null 17 | @sudo rmmod list_directory_contents 18 | @sudo dmesg 19 | @echo "#############[ END ] #################" 20 | test: 21 | @make load 22 | @make unload 23 | endif 24 | -------------------------------------------------------------------------------- /h005_list_directory_contents/list_directory_contents.c: -------------------------------------------------------------------------------- 1 | /*********************************************** 2 | * module : list_directory_contents 3 | * 4 | * Wang Long (wanglong@laoqinren.net) 5 | **********************************************/ 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | static char *fs = "ext4"; 16 | module_param(fs, charp, 0); 17 | 18 | static unsigned int major = 0; 19 | module_param(major, uint, 0); 20 | 21 | static unsigned int minor = 0; 22 | module_param(minor, uint, 0); 23 | 24 | static unsigned long inode = 0; 25 | module_param(inode, ulong, 0); 26 | 27 | static int __init list_directory_contents_init(void) 28 | { 29 | struct super_block *sb; 30 | struct inode *pinode; 31 | struct dentry *pdentry; 32 | struct dentry *subdirs; 33 | //找到ext4的文件系统类型描述结构体 34 | struct file_system_type *fst = get_fs_type(fs); 35 | spinlock_t * lock = (spinlock_t *)kallsyms_lookup_name("sb_lock"); 36 | 37 | printk(KERN_INFO "The module params: inode = %ld, major = %d, minor = %d, fs = %s\n", 38 | inode, major, minor, fs); 39 | printk(KERN_INFO "The filesystem's name is : %s\n", fst->name); 40 | printk(KERN_INFO "******************************************"); 41 | //遍历特定的ext4超级快 42 | spin_lock(lock); 43 | hlist_for_each_entry(sb, &fst->fs_supers, s_instances) 44 | { 45 | // 只遍历特定的设备 46 | if (sb->s_dev == MKDEV(major, minor)) { 47 | printk(KERN_INFO "The %s filesystem is : %s(%d:%d)\n", fs, sb->s_id, 48 | MAJOR(sb->s_dev), MINOR(sb->s_dev)); 49 | list_for_each_entry(pinode, &sb->s_inodes, i_sb_list) { 50 | // 只遍历特定的inode节点 51 | if (inode == pinode->i_ino) { 52 | printk("%lu ", pinode->i_ino); 53 | hlist_for_each_entry(pdentry, &pinode->i_dentry, d_u.d_alias) { 54 | printk("[%s] parent = %s", pdentry->d_name.name, 55 | pdentry->d_parent->d_name.name); 56 | list_for_each_entry(subdirs, &pdentry->d_subdirs, d_child) { 57 | printk("\n\t\tfile = %s", subdirs->d_name.name); 58 | } 59 | } 60 | } 61 | } 62 | 63 | printk("\n"); 64 | } else 65 | printk(KERN_INFO "Skip the %s filesystem is : %s(%d:%d)\n", fs, sb->s_id, 66 | MAJOR(sb->s_dev), MINOR(sb->s_dev)); 67 | } 68 | spin_unlock(lock); 69 | return 0; 70 | } 71 | 72 | static void __exit list_directory_contents_exit(void) 73 | { 74 | printk(KERN_ALERT "[Goodbye] list_directory_contents\n"); 75 | } 76 | 77 | module_init(list_directory_contents_init); 78 | module_exit(list_directory_contents_exit); 79 | MODULE_LICENSE("GPL"); 80 | MODULE_AUTHOR("datawolf"); 81 | -------------------------------------------------------------------------------- /h006_ls/Makefile: -------------------------------------------------------------------------------- 1 | ifneq ($(KERNELRELEASE), ) 2 | obj-m := ls.o 3 | else 4 | KERNELDIR ?=/lib/modules/$(shell uname -r)/build 5 | PWD := $(shell pwd) 6 | all: 7 | $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 8 | clean: 9 | $(MAKE) -C $(KERNELDIR) M=$(PWD) clean 10 | load: 11 | @sudo dmesg -c > /dev/null 12 | @echo "#############[START] #################" 13 | @sudo insmod ls.ko 14 | @sudo dmesg 15 | unload: 16 | @sudo dmesg -c > /dev/null 17 | @sudo rmmod ls 18 | @sudo dmesg 19 | @echo "#############[ END ] #################" 20 | test: 21 | @make load 22 | @make unload 23 | endif 24 | -------------------------------------------------------------------------------- /h006_ls/README.md: -------------------------------------------------------------------------------- 1 | ## 说明 2 | 3 | 该模块根据通过遍历dentry,列出指定目录下的所有的文件和文件夹信息。 4 | 5 | ## 使用方法 6 | 7 | ``` 8 | insmod ls.ko dir="/root/" 9 | ``` 10 | 11 | ## 示例 12 | 13 | ``` 14 | root@localhost:h006_ls# make test 15 | make[1]: Entering directory '/root/dive-in-kernel/h006_ls' 16 | #############[START] ################# 17 | [ 2743.662962] [Hello] ls 18 | [ 2743.662981] DIR: /root/ has the following files:name = .viminfo 19 | [ 2743.662983] name = .NERDTreeBookmarks 20 | [ 2743.662984] name = .vimrc 21 | [ 2743.662985] name = .vim 22 | [ 2743.662986] name = dmesg 23 | [ 2743.662987] name = dmes 24 | [ 2743.662988] name = lxc-test 25 | [ 2743.662988] name = notes 26 | [ 2743.662989] name = temp 27 | [ 2743.662990] name = dive-in-kernel 28 | [ 2743.662991] name = chelper 29 | [ 2743.662992] name = util-linux 30 | [ 2743.662993] name = specs-c 31 | [ 2743.662993] name = work 32 | [ 2743.662994] name = lxc 33 | [ 2743.662995] name = lxc-pkg-ubuntu 34 | [ 2743.662996] name = libseccomp 35 | [ 2743.662997] name = kernel 36 | [ 2743.662998] name = libocispec 37 | [ 2743.662999] name = mem_proc 38 | [ 2743.662999] name = go 39 | [ 2743.663000] name = uts 40 | [ 2743.663001] name = bin 41 | [ 2743.663002] name = lxd 42 | [ 2743.663002] name = man-pages 43 | [ 2743.663003] name = git 44 | [ 2743.663004] name = test 45 | [ 2743.663005] name = main.c 46 | [ 2743.663006] name = skopeo 47 | [ 2743.663006] name = .inputrc 48 | [ 2743.663007] name = .terminfo 49 | [ 2743.663008] name = go1.7 50 | [ 2743.663009] name = iwyu 51 | [ 2743.663010] name = .bash_aliases 52 | [ 2743.663011] name = .dircolors 53 | [ 2743.663012] name = .bash_history 54 | [ 2743.663012] name = .bashrc 55 | [ 2743.663013] name = .profile 56 | [ 2743.663014] name = .bash_login 57 | [ 2743.663015] name = .bash_profile 58 | [ 2743.663016] name = .bash_completion 59 | [ 2743.663016] name = .m2 60 | [ 2743.663017] name = .sudo_as_admin_successful 61 | [ 2743.663018] name = .ssh 62 | [ 2743.663019] name = .hushlogin 63 | [ 2743.663020] name = .pam_environment 64 | [ 2743.663021] name = .cache 65 | [ 2743.663022] name = .config 66 | [ 2743.663023] name = .apport-ignore.xml 67 | [ 2743.663024] name = .local 68 | make[1]: Leaving directory '/root/dive-in-kernel/h006_ls' 69 | make[1]: Entering directory '/root/dive-in-kernel/h006_ls' 70 | [ 2743.680576] [Goodbye] ls 71 | #############[ END ] ################# 72 | make[1]: Leaving directory '/root/dive-in-kernel/h006_ls' 73 | ``` 74 | -------------------------------------------------------------------------------- /h006_ls/ls.c: -------------------------------------------------------------------------------- 1 | /*********************************************** 2 | * module : ls 3 | * 4 | * Wang Long (wanglong@laoqinren.net) 5 | **********************************************/ 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | static char *dir="/root/"; 14 | module_param(dir, charp, 0); 15 | 16 | static int __init ls_init(void) 17 | { 18 | struct file *fi; 19 | struct dentry *thedentry, *curdentry; 20 | 21 | printk(KERN_ALERT "[Hello] ls \n"); 22 | 23 | fi = filp_open(dir, O_RDONLY, 0); 24 | thedentry = fi->f_path.dentry; 25 | 26 | printk("DIR: %s has the following files:", dir); 27 | list_for_each_entry(curdentry, &thedentry->d_subdirs, d_child) { 28 | printk("name = %s\n", curdentry->d_name.name); 29 | } 30 | filp_close(fi, NULL); 31 | return 0; 32 | } 33 | 34 | static void __exit ls_exit(void) 35 | { 36 | printk(KERN_ALERT "[Goodbye] ls\n"); 37 | } 38 | 39 | module_init(ls_init); 40 | module_exit(ls_exit); 41 | MODULE_LICENSE("GPL"); 42 | MODULE_AUTHOR("datawolf"); 43 | -------------------------------------------------------------------------------- /h007_task_css_set/Makefile: -------------------------------------------------------------------------------- 1 | ifneq ($(KERNELRELEASE), ) 2 | obj-m := task_css_set.o 3 | else 4 | KERNELDIR ?=/lib/modules/$(shell uname -r)/build 5 | PWD := $(shell pwd) 6 | all: 7 | $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 8 | clean: 9 | $(MAKE) -C $(KERNELDIR) M=$(PWD) clean 10 | load: 11 | @sudo dmesg -c > /dev/null 12 | @echo "#############[START] #################" 13 | @sudo insmod task_css_set.ko 14 | @sudo dmesg 15 | unload: 16 | @sudo dmesg -c > /dev/null 17 | @sudo rmmod task_css_set 18 | @sudo dmesg 19 | @echo "#############[ END ] #################" 20 | test: 21 | @make load 22 | @make unload 23 | endif 24 | -------------------------------------------------------------------------------- /h007_task_css_set/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawolf/dive-in-kernel/663175ee02d5d976b289bdc64a23f70fefc4368f/h007_task_css_set/README.md -------------------------------------------------------------------------------- /h007_task_css_set/result/0001.log: -------------------------------------------------------------------------------- 1 | make[1]: Entering directory `/root/dive-in-kernel/h007_task_css_set' 2 | #############[START] ################# 3 | [ 8938.531223] [Hello] task_css_set 4 | [ 8938.531226] task name: systemd[1] 5 | [ 8938.531227] Process with the same css_set 6 | [ 8938.531228] name = [0] 7 | [ 8938.531229] name = xfsaild/sda1[536] 8 | [ 8938.531230] name = xfs-cil/sda1[534] 9 | [ 8938.531231] name = xfs-conv/sda1[533] 10 | [ 8938.531232] name = xfs-data/sda1[532] 11 | [ 8938.531232] name = xfs-buf/sda1[531] 12 | [ 8938.531233] name = rpciod[484] 13 | [ 8938.531234] name = xfsaild/dm-0[391] 14 | [ 8938.531235] name = xfs-cil/dm-0[390] 15 | [ 8938.531236] name = xfs-conv/dm-0[389] 16 | [ 8938.531237] name = xfs-data/dm-0[388] 17 | [ 8938.531238] name = xfs-buf/dm-0[387] 18 | [ 8938.531239] name = xfs_mru_cache[386] 19 | [ 8938.531239] name = xfsalloc[385] 20 | [ 8938.531240] name = bioset[372] 21 | [ 8938.531241] name = kdmflush[371] 22 | [ 8938.531242] name = bioset[360] 23 | [ 8938.531243] name = kdmflush[359] 24 | [ 8938.531244] name = kworker/0:1H[297] 25 | [ 8938.531245] name = kworker/u2:4[290] 26 | [ 8938.531245] name = kworker/u2:3[289] 27 | [ 8938.531246] name = scsi_tmf_2[288] 28 | [ 8938.531247] name = scsi_eh_2[287] 29 | [ 8938.531248] name = scsi_tmf_1[286] 30 | [ 8938.531249] name = kworker/u2:2[285] 31 | [ 8938.531250] name = scsi_eh_1[284] 32 | [ 8938.531251] name = scsi_tmf_0[283] 33 | [ 8938.531252] name = scsi_eh_0[281] 34 | [ 8938.531253] name = ata_sff[262] 35 | [ 8938.531254] name = kworker/0:3[95] 36 | [ 8938.531254] name = kauditd[93] 37 | [ 8938.531255] name = kworker/0:2[61] 38 | [ 8938.531256] name = deferwq[60] 39 | [ 8938.531257] name = kpsmoused[41] 40 | [ 8938.531258] name = kmpath_rdacd[40] 41 | [ 8938.531259] name = kworker/u2:1[39] 42 | [ 8938.531260] name = kthrotld[38] 43 | [ 8938.531260] name = crypto[29] 44 | [ 8938.531261] name = fsnotify_mark[28] 45 | [ 8938.531262] name = khugepaged[27] 46 | [ 8938.531263] name = ksmd[26] 47 | [ 8938.531264] name = kswapd0[25] 48 | [ 8938.531265] name = khungtaskd[24] 49 | [ 8938.531266] name = kworker/0:1[22] 50 | [ 8938.531266] name = md[21] 51 | [ 8938.531267] name = khubd[20] 52 | [ 8938.531268] name = kblockd[19] 53 | [ 8938.531269] name = bioset[18] 54 | [ 8938.531270] name = kintegrityd[17] 55 | [ 8938.531271] name = writeback[16] 56 | [ 8938.531272] name = netns[15] 57 | [ 8938.531272] name = kdevtmpfs[14] 58 | [ 8938.531273] name = khelper[13] 59 | [ 8938.531274] name = watchdog/0[12] 60 | [ 8938.531275] name = rcuos/0[11] 61 | [ 8938.531276] name = rcu_sched[10] 62 | [ 8938.531277] name = rcuob/0[9] 63 | [ 8938.531278] name = rcu_bh[8] 64 | [ 8938.531279] name = migration/0[7] 65 | [ 8938.531279] name = kworker/u2:0[6] 66 | [ 8938.531280] name = kworker/0:0H[5] 67 | [ 8938.531281] name = kworker/0:0[4] 68 | [ 8938.531282] name = ksoftirqd/0[3] 69 | [ 8938.531283] name = kthreadd[2] 70 | make[1]: Leaving directory `/root/dive-in-kernel/h007_task_css_set' 71 | make[1]: Entering directory `/root/dive-in-kernel/h007_task_css_set' 72 | [ 8938.564474] [Goodbye] task_css_set 73 | #############[ END ] ################# 74 | make[1]: Leaving directory `/root/dive-in-kernel/h007_task_css_set' 75 | -------------------------------------------------------------------------------- /h007_task_css_set/result/0002.log: -------------------------------------------------------------------------------- 1 | [ 8938.564474] [Goodbye] task_css_set 2 | [ 8980.749050] [Hello] task_css_set 3 | [ 8980.749054] task name: bioset[372] 4 | [ 8980.749055] Process with the same css_set 5 | [ 8980.749057] name = kdmflush[371] 6 | [ 8980.749058] name = bioset[360] 7 | [ 8980.749059] name = kdmflush[359] 8 | [ 8980.749060] name = kworker/0:1H[297] 9 | [ 8980.749061] name = kworker/u2:4[290] 10 | [ 8980.749062] name = kworker/u2:3[289] 11 | [ 8980.749064] name = scsi_tmf_2[288] 12 | [ 8980.749065] name = scsi_eh_2[287] 13 | [ 8980.749066] name = scsi_tmf_1[286] 14 | [ 8980.749067] name = kworker/u2:2[285] 15 | [ 8980.749068] name = scsi_eh_1[284] 16 | [ 8980.749069] name = scsi_tmf_0[283] 17 | [ 8980.749070] name = scsi_eh_0[281] 18 | [ 8980.749072] name = ata_sff[262] 19 | [ 8980.749073] name = kworker/0:3[95] 20 | [ 8980.749074] name = kauditd[93] 21 | [ 8980.749075] name = kworker/0:2[61] 22 | [ 8980.749076] name = deferwq[60] 23 | [ 8980.749077] name = kpsmoused[41] 24 | [ 8980.749079] name = kmpath_rdacd[40] 25 | [ 8980.749080] name = kworker/u2:1[39] 26 | [ 8980.749081] name = kthrotld[38] 27 | [ 8980.749082] name = crypto[29] 28 | [ 8980.749083] name = fsnotify_mark[28] 29 | [ 8980.749084] name = khugepaged[27] 30 | [ 8980.749085] name = ksmd[26] 31 | [ 8980.749086] name = kswapd0[25] 32 | [ 8980.749087] name = khungtaskd[24] 33 | [ 8980.749088] name = kworker/0:1[22] 34 | [ 8980.749089] name = md[21] 35 | [ 8980.749090] name = khubd[20] 36 | [ 8980.749092] name = kblockd[19] 37 | [ 8980.749093] name = bioset[18] 38 | [ 8980.749094] name = kintegrityd[17] 39 | [ 8980.749095] name = writeback[16] 40 | [ 8980.749096] name = netns[15] 41 | [ 8980.749097] name = kdevtmpfs[14] 42 | [ 8980.749098] name = khelper[13] 43 | [ 8980.749099] name = watchdog/0[12] 44 | [ 8980.749100] name = rcuos/0[11] 45 | [ 8980.749101] name = rcu_sched[10] 46 | [ 8980.749103] name = rcuob/0[9] 47 | [ 8980.749104] name = rcu_bh[8] 48 | [ 8980.749105] name = migration/0[7] 49 | [ 8980.749106] name = kworker/u2:0[6] 50 | [ 8980.749107] name = kworker/0:0H[5] 51 | [ 8980.749108] name = kworker/0:0[4] 52 | [ 8980.749109] name = ksoftirqd/0[3] 53 | [ 8980.749110] name = kthreadd[2] 54 | [ 8980.749111] name = systemd[1] 55 | [ 8980.749112] name = [0] 56 | [ 8980.749114] name = xfsaild/sda1[536] 57 | [ 8980.749115] name = xfs-cil/sda1[534] 58 | [ 8980.749116] name = xfs-conv/sda1[533] 59 | [ 8980.749117] name = xfs-data/sda1[532] 60 | [ 8980.749118] name = xfs-buf/sda1[531] 61 | [ 8980.749119] name = rpciod[484] 62 | [ 8980.749120] name = xfsaild/dm-0[391] 63 | [ 8980.749121] name = xfs-cil/dm-0[390] 64 | [ 8980.749122] name = xfs-conv/dm-0[389] 65 | [ 8980.749123] name = xfs-data/dm-0[388] 66 | [ 8980.749124] name = xfs-buf/dm-0[387] 67 | [ 8980.749125] name = xfs_mru_cache[386] 68 | [ 8980.749126] name = xfsalloc[385] 69 | [ 8983.708536] [Goodbye] task_css_set 70 | -------------------------------------------------------------------------------- /h007_task_css_set/result/0003.log: -------------------------------------------------------------------------------- 1 | [ 9057.965130] [Hello] task_css_set 2 | [ 9057.965134] task name: bash[3046] 3 | [ 9057.965135] Process with the same css_set 4 | [ 9057.965137] name = ig.py\xfffffffbG 5 | pconfig.pyc\xfffffffbH 6 | \xffffffa8config.pyo\xfffffffbI \xffffffe0handlers.py\xfffffffbJ Hhandlers.pyc\xfffffffb\xffffffb2 `handlers.pyo\xfffffffb\xffffffb2[0] 7 | [ 9065.693132] [Goodbye] task_css_set 8 | -------------------------------------------------------------------------------- /h007_task_css_set/result/0004.log: -------------------------------------------------------------------------------- 1 | [18617.109516] task name: bash[3489] 2 | [18617.109517] Process with the same css_set 3 | [18617.109518] name = [0] 4 | [18617.109519] ###### css_set info ####### 5 | [18617.109520] css_set.refcount = 1 6 | [18617.109520] CGROUP_SUBSYS_COUNT = 11 7 | [18617.109522] subsys[0].refcnt = 1 8 | [18617.109523] subsys[0].cgroup.name = e6cec8a9f3ae0453c63da68c67f8761713ed1eff09a07f1cb644e5e9271c7f1c 9 | [18617.109524] subsys[0].cgroupfs_root.name = / 10 | [18617.109525] subsys[0].cgroup.parent.name = docker 11 | 12 | [18617.109527] subsys[1].refcnt = 1 13 | [18617.109529] subsys[1].cgroup.name = e6cec8a9f3ae0453c63da68c67f8761713ed1eff09a07f1cb644e5e9271c7f1c 14 | [18617.109530] subsys[1].cgroupfs_root.name = / 15 | [18617.109531] subsys[1].cgroup.parent.name = docker 16 | 17 | [18617.109532] subsys[2].refcnt = 1 18 | [18617.109533] subsys[2].cgroup.name = e6cec8a9f3ae0453c63da68c67f8761713ed1eff09a07f1cb644e5e9271c7f1c 19 | [18617.109534] subsys[2].cgroupfs_root.name = / 20 | [18617.109535] subsys[2].cgroup.parent.name = docker 21 | 22 | [18617.109537] subsys[3].refcnt = 1 23 | [18617.109538] subsys[3].cgroup.name = e6cec8a9f3ae0453c63da68c67f8761713ed1eff09a07f1cb644e5e9271c7f1c 24 | [18617.109539] subsys[3].cgroupfs_root.name = / 25 | [18617.109540] subsys[3].cgroup.parent.name = docker 26 | 27 | [18617.109541] subsys[4].refcnt = 1 28 | [18617.109542] subsys[4].cgroup.name = e6cec8a9f3ae0453c63da68c67f8761713ed1eff09a07f1cb644e5e9271c7f1c 29 | [18617.109544] subsys[4].cgroupfs_root.name = / 30 | [18617.109545] subsys[4].cgroup.parent.name = docker 31 | 32 | [18617.109546] subsys[5].refcnt = 1 33 | [18617.109547] subsys[5].cgroup.name = e6cec8a9f3ae0453c63da68c67f8761713ed1eff09a07f1cb644e5e9271c7f1c 34 | [18617.109548] subsys[5].cgroupfs_root.name = / 35 | [18617.109549] subsys[5].cgroup.parent.name = docker 36 | 37 | [18617.109551] subsys[6].refcnt = 1 38 | [18617.109552] subsys[6].cgroup.name = e6cec8a9f3ae0453c63da68c67f8761713ed1eff09a07f1cb644e5e9271c7f1c 39 | [18617.109554] subsys[6].cgroupfs_root.name = / 40 | [18617.109555] subsys[6].cgroup.parent.name = docker 41 | 42 | [18617.109557] subsys[7].refcnt = 3 43 | [18617.109558] subsys[7].cgroup.name = e6cec8a9f3ae0453c63da68c67f8761713ed1eff09a07f1cb644e5e9271c7f1c 44 | [18617.109559] subsys[7].cgroupfs_root.name = / 45 | [18617.109560] subsys[7].cgroup.parent.name = docker 46 | 47 | [18617.109562] subsys[8].refcnt = 1 48 | [18617.109563] subsys[8].cgroup.name = e6cec8a9f3ae0453c63da68c67f8761713ed1eff09a07f1cb644e5e9271c7f1c 49 | [18617.109564] subsys[8].cgroupfs_root.name = / 50 | [18617.109565] subsys[8].cgroup.parent.name = docker 51 | 52 | [18617.109567] subsys[9].refcnt = 1 53 | [18617.109568] subsys[9].cgroup.name = e6cec8a9f3ae0453c63da68c67f8761713ed1eff09a07f1cb644e5e9271c7f1c 54 | [18617.109569] subsys[9].cgroupfs_root.name = / 55 | [18617.109570] subsys[9].cgroup.parent.name = docker 56 | 57 | 58 | [18622.317079] [Goodbye] task_css_set 59 | -------------------------------------------------------------------------------- /h007_task_css_set/task_css_set.c: -------------------------------------------------------------------------------- 1 | /*********************************************** 2 | * module : task_css_set 3 | * 4 | * Wang Long (wanglong@laoqinren.net) 5 | **********************************************/ 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | static int pid = 1; 16 | module_param(pid, int, 1); 17 | 18 | static int __init task_css_set_init(void) 19 | { 20 | pid_t p = (pid_t)pid; 21 | struct task_struct *tk = get_pid_task(find_get_pid(p), PIDTYPE_PID); 22 | struct task_struct *cur; 23 | int i; 24 | struct cgroup_subsys_state *css; 25 | struct css_set *init_css = (struct css_set*)kallsyms_lookup_name("init_css_set"); 26 | 27 | printk(KERN_ALERT "[Hello] task_css_set \n"); 28 | printk("task name: %s[%d]\n", tk->comm, tk->pid); 29 | 30 | printk("Process with the same css_set\n"); 31 | list_for_each_entry(cur, &tk->cg_list, cg_list) { 32 | printk("name = %s[%d]\n", cur->comm, cur->pid); 33 | } 34 | 35 | printk("###### css_set info #######\n"); 36 | printk("css_set.refcount = %d\n", tk->cgroups->refcount.counter); 37 | 38 | if (tk->cgroups == init_css) 39 | printk("@@@@@ in init cgroup @@@@@\n"); 40 | else 41 | printk("@@@@@ NOT in init cgroup @@@@@\n"); 42 | 43 | printk("CGROUP_SUBSYS_COUNT = %d\n", CGROUP_SUBSYS_COUNT); 44 | for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) { 45 | struct cgroup *cg; 46 | css = tk->cgroups->subsys[i]; 47 | if (css) { 48 | printk("subsys[%d].refcnt = %d\n", i, css->refcnt.counter); 49 | printk("subsys[%d].cgroup.name = %s\n", i, css->cgroup->name->name); 50 | printk("subsys[%d].cgroupfs_root.name = %s\n", i, css->cgroup->root->top_cgroup.name->name); 51 | printk("subsys[%d].cgroupfs_root.release_agent = %s\n", i, 52 | css->cgroup->root->release_agent_path); 53 | if (css->cgroup->parent) 54 | printk("subsys[%d].cgroup.parent.name = %s\n", i, css->cgroup->parent->name->name); 55 | list_for_each_entry(cg, &css->cgroup->children, sibling) { 56 | printk("subsys[%d].childcgroup.name = %s\n", i, cg->name->name); 57 | } 58 | } 59 | printk("\n"); 60 | } 61 | 62 | return 0; 63 | } 64 | 65 | static void __exit task_css_set_exit(void) 66 | { 67 | printk(KERN_ALERT "[Goodbye] task_css_set\n"); 68 | } 69 | 70 | module_init(task_css_set_init); 71 | module_exit(task_css_set_exit); 72 | MODULE_LICENSE("GPL"); 73 | MODULE_AUTHOR("datawolf"); 74 | -------------------------------------------------------------------------------- /h008_proc_cgroups/Makefile: -------------------------------------------------------------------------------- 1 | ifneq ($(KERNELRELEASE), ) 2 | obj-m := proc_cgroups.o 3 | else 4 | KERNELDIR ?=/lib/modules/$(shell uname -r)/build 5 | PWD := $(shell pwd) 6 | all: 7 | $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 8 | clean: 9 | $(MAKE) -C $(KERNELDIR) M=$(PWD) clean 10 | load: 11 | @sudo dmesg -c > /dev/null 12 | @echo "#############[START] #################" 13 | @sudo insmod proc_cgroups.ko 14 | @sudo dmesg 15 | unload: 16 | @sudo dmesg -c > /dev/null 17 | @sudo rmmod proc_cgroups 18 | @sudo dmesg 19 | @echo "#############[ END ] #################" 20 | test: 21 | @make load 22 | @make unload 23 | endif 24 | -------------------------------------------------------------------------------- /h008_proc_cgroups/README.md: -------------------------------------------------------------------------------- 1 | ## 说明 2 | 3 | 本模块通过`subsys`变量遍历系统中支持的`cgroups` 4 | 5 | ## 执行结果 6 | 7 | ``` 8 | make[1]: Entering directory `/root/dive-in-kernel/h008_proc_cgroups' 9 | #############[START] ################# 10 | [15710.101142] [Hello] proc_cgroups 11 | [15710.101145] CGROUP_BUILTIN_SUBSYS_COUNT = 10 12 | [15710.101146] CGROUP_SUBSYS_COUNT = 11 13 | 14 | [15710.101147] #subsys_name hierarchy num_cgroups enabled 15 | [15710.101148] [0]cpuset 5 1 1 16 | [15710.101150] [1]cpu 2 88 1 17 | [15710.101151] [2]cpuacct 2 88 1 18 | [15710.101152] [3]memory 10 88 1 19 | [15710.101153] [4]devices 6 88 1 20 | [15710.101153] [5]freezer 3 1 1 21 | [15710.101154] [6]net_cls 4 1 1 22 | [15710.101155] [7]blkio 8 88 1 23 | [15710.101156] [8]perf_event 9 1 1 24 | [15710.101157] [9]hugetlb 7 1 1 25 | [15710.101159] [10]net_prio 0 1 1 26 | make[1]: Leaving directory `/root/dive-in-kernel/h008_proc_cgroups' 27 | make[1]: Entering directory `/root/dive-in-kernel/h008_proc_cgroups' 28 | [15710.134711] [Goodbye] proc_cgroups 29 | #############[ END ] ################# 30 | make[1]: Leaving directory `/root/dive-in-kernel/h008_proc_cgroups' 31 | ``` 32 | -------------------------------------------------------------------------------- /h008_proc_cgroups/proc_cgroups.c: -------------------------------------------------------------------------------- 1 | /*********************************************** 2 | * module : proc_cgroups 3 | * 4 | * Wang Long (wanglong@laoqinren.net) 5 | **********************************************/ 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | 13 | static int __init proc_cgroups_init(void) 14 | { 15 | struct cgroup_subsys **sub = (struct cgroup_subsys **)kallsyms_lookup_name("subsys"); 16 | int i; 17 | 18 | printk(KERN_ALERT "[Hello] proc_cgroups \n"); 19 | printk("CGROUP_BUILTIN_SUBSYS_COUNT = %d\n", CGROUP_BUILTIN_SUBSYS_COUNT); 20 | printk("CGROUP_SUBSYS_COUNT = %d\n\n", CGROUP_SUBSYS_COUNT); 21 | printk("hierarchy subsys_id num_cgroups enabled used_id early_init ctype name base_cftype == base_cfset->cftype\n"); 22 | for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) { 23 | struct cgroup_subsys *ss = sub[i]; 24 | if (ss == NULL) 25 | continue; 26 | printk("[%d]%d\t\t%d\t%d\t%d\t%d\t%d\t%s\t\t%s\t%s\n", i, 27 | ss->root->hierarchy_id, 28 | ss->subsys_id, 29 | ss->root->number_of_cgroups, !ss->disabled, 30 | ss->use_id ? 1 : 0, 31 | ss->early_init, ss->base_cftypes->name, ss->name, 32 | ss->base_cftypes == ss->base_cftset.cfts ? "equal" : "not equal"); 33 | } 34 | 35 | return 0; 36 | } 37 | 38 | static void __exit proc_cgroups_exit(void) 39 | { 40 | printk(KERN_ALERT "[Goodbye] proc_cgroups\n"); 41 | } 42 | 43 | module_init(proc_cgroups_init); 44 | module_exit(proc_cgroups_exit); 45 | MODULE_LICENSE("GPL"); 46 | MODULE_AUTHOR("datawolf"); 47 | -------------------------------------------------------------------------------- /h009_init_css_set/Makefile: -------------------------------------------------------------------------------- 1 | ifneq ($(KERNELRELEASE), ) 2 | obj-m := init_css_set.o 3 | else 4 | KERNELDIR ?=/lib/modules/$(shell uname -r)/build 5 | PWD := $(shell pwd) 6 | all: 7 | $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 8 | clean: 9 | $(MAKE) -C $(KERNELDIR) M=$(PWD) clean 10 | load: 11 | @sudo dmesg -c > /dev/null 12 | @echo "#############[START] #################" 13 | @sudo insmod init_css_set.ko 14 | @sudo dmesg 15 | unload: 16 | @sudo dmesg -c > /dev/null 17 | @sudo rmmod init_css_set 18 | @sudo dmesg 19 | @echo "#############[ END ] #################" 20 | test: 21 | @make load 22 | @make unload 23 | endif 24 | -------------------------------------------------------------------------------- /h010_calc_load_account_active/Makefile: -------------------------------------------------------------------------------- 1 | ifneq ($(KERNELRELEASE), ) 2 | obj-m := calc_load_account_active.o 3 | else 4 | KERNELDIR ?=/lib/modules/$(shell uname -r)/build 5 | PWD := $(shell pwd) 6 | all: 7 | $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 8 | clean: 9 | $(MAKE) -C $(KERNELDIR) M=$(PWD) clean 10 | load: 11 | @sudo dmesg -c > /dev/null 12 | @echo "#############[START] #################" 13 | @sudo insmod calc_load_account_active.ko 14 | @sudo dmesg 15 | unload: 16 | @sudo dmesg -c > /dev/null 17 | @sudo rmmod calc_load_account_active 18 | @sudo dmesg 19 | @echo "#############[ END ] #################" 20 | test: 21 | @make load 22 | @make unload 23 | endif 24 | -------------------------------------------------------------------------------- /h010_calc_load_account_active/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawolf/dive-in-kernel/663175ee02d5d976b289bdc64a23f70fefc4368f/h010_calc_load_account_active/README.md -------------------------------------------------------------------------------- /h010_calc_load_account_active/calc_load_account_active.c: -------------------------------------------------------------------------------- 1 | /*********************************************** 2 | * module : calc_load_account_active 3 | * 4 | * Wang Long (wanglong@laoqinren.net) 5 | **********************************************/ 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | /* per-instance private data */ 14 | struct my_data { 15 | ktime_t entry_stamp; 16 | }; 17 | 18 | /* Here we use the entry_hanlder to timestamp function entry */ 19 | static int entry_handler(struct kretprobe_instance *ri, struct pt_regs *regs) 20 | { 21 | struct my_data *data; 22 | 23 | if (!current->mm) 24 | return 1; /* Skip kernel threads */ 25 | 26 | data = (struct my_data *)ri->data; 27 | data->entry_stamp = ktime_get(); 28 | return 0; 29 | } 30 | 31 | /* 32 | * Return-probe handler: Log the return value and duration. Duration may turn 33 | * out to be zero consistently, depending upon the granularity of time 34 | * accounting on the platform. 35 | */ 36 | static int ret_handler(struct kretprobe_instance *ri, struct pt_regs *regs) 37 | { 38 | int retval = regs_return_value(regs); 39 | struct my_data *data = (struct my_data *)ri->data; 40 | s64 delta; 41 | ktime_t now; 42 | 43 | now = ktime_get(); 44 | delta = ktime_to_ns(ktime_sub(now, data->entry_stamp)); 45 | printk(KERN_INFO "calc_load_account_active returned %d and took %lld ns to execute\n", 46 | retval, (long long)delta); 47 | return 0; 48 | } 49 | 50 | static struct kretprobe my_kretprobe = { 51 | .handler = ret_handler, 52 | .entry_handler = entry_handler, 53 | .data_size = sizeof(struct my_data), 54 | /* Probe up to 20 instances concurrently. */ 55 | .maxactive = 20, 56 | }; 57 | 58 | static int __init calc_load_account_active_init(void) 59 | { 60 | 61 | int ret; 62 | 63 | //my_kretprobe.kp.symbol_name = "calc_load_account_active"; 64 | my_kretprobe.kp.symbol_name = "scheduler_tick"; 65 | ret = register_kretprobe(&my_kretprobe); 66 | if (ret < 0) { 67 | printk(KERN_INFO "register_kretprobe failed, returned %d\n", 68 | ret); 69 | return -1; 70 | } 71 | printk(KERN_INFO "Planted return probe at %s: %p\n", 72 | my_kretprobe.kp.symbol_name, my_kretprobe.kp.addr); 73 | return 0; 74 | } 75 | 76 | static void __exit calc_load_account_active_exit(void) 77 | { 78 | unregister_kretprobe(&my_kretprobe); 79 | printk(KERN_INFO "kretprobe at %p unregistered\n", 80 | my_kretprobe.kp.addr); 81 | 82 | /* nmissed > 0 suggests that maxactive was set too low. */ 83 | printk(KERN_INFO "Missed probing %d instances of %s\n", 84 | my_kretprobe.nmissed, my_kretprobe.kp.symbol_name); 85 | 86 | } 87 | 88 | module_init(calc_load_account_active_init); 89 | module_exit(calc_load_account_active_exit); 90 | MODULE_LICENSE("GPL"); 91 | MODULE_AUTHOR("datawolf"); 92 | -------------------------------------------------------------------------------- /h011_proc_mytasks/Makefile: -------------------------------------------------------------------------------- 1 | ifneq ($(KERNELRELEASE), ) 2 | obj-m := proc_mytasks.o 3 | else 4 | KERNELDIR ?=/lib/modules/$(shell uname -r)/build 5 | PWD := $(shell pwd) 6 | all: 7 | $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 8 | clean: 9 | $(MAKE) -C $(KERNELDIR) M=$(PWD) clean 10 | load: 11 | @sudo dmesg -c > /dev/null 12 | @echo "#############[START] #################" 13 | @sudo insmod proc_mytasks.ko 14 | @sudo dmesg 15 | unload: 16 | @sudo dmesg -c > /dev/null 17 | @sudo rmmod proc_mytasks 18 | @sudo dmesg 19 | @echo "#############[ END ] #################" 20 | test: 21 | @make load 22 | @make unload 23 | endif 24 | -------------------------------------------------------------------------------- /h011_proc_mytasks/README.md: -------------------------------------------------------------------------------- 1 | ## 说明 2 | 3 | 该模块在`/proc`下创建了文件`mytasks`,它输出了当前系统上所有的进程 4 | 5 | 6 | ## 示例输出 7 | 8 | ``` 9 | # cat /proc/mytasks 10 | All processes in system: 11 | name pid 12 | swapper/0 0 13 | systemd 1 14 | kthreadd 2 15 | ksoftirqd/0 3 16 | kworker/0:0H 5 17 | migration/0 7 18 | rcu_bh 8 19 | rcuob/0 9 20 | rcuob/1 10 21 | rcu_sched 11 22 | rcuos/0 12 23 | rcuos/1 13 24 | watchdog/0 14 25 | watchdog/1 15 26 | migration/1 16 27 | ksoftirqd/1 17 28 | kworker/1:0H 19 29 | khelper 20 30 | kdevtmpfs 21 31 | netns 22 32 | writeback 23 33 | kintegrityd 24 34 | bioset 25 35 | kblockd 26 36 | khubd 27 37 | md 28 38 | khungtaskd 32 39 | kswapd0 33 40 | ksmd 34 41 | khugepaged 35 42 | fsnotify_mark 36 43 | crypto 37 44 | kthrotld 46 45 | kworker/u4:1 47 46 | kmpath_rdacd 48 47 | ... 48 | ... 49 | ... 50 | ``` 51 | -------------------------------------------------------------------------------- /h011_proc_mytasks/proc_mytasks.c: -------------------------------------------------------------------------------- 1 | /*********************************************** 2 | * module : proc_mytasks 3 | * 4 | * Wang Long (wanglong@laoqinren.net) 5 | **********************************************/ 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | 14 | static void *tasks_seq_start(struct seq_file *s, loff_t *pos) 15 | { 16 | if (*pos == 0) { 17 | seq_printf(s, "All processes in system:\n%-24s%-5s\n", "name", "pid"); 18 | return &init_task; 19 | } else { 20 | return NULL; 21 | } 22 | } 23 | 24 | static void *tasks_seq_next(struct seq_file *s, void *v, loff_t *pos) 25 | { 26 | struct task_struct *task = (struct task_struct *)v; 27 | 28 | task = next_task(task); 29 | if ((*pos != 0) && (task == &init_task)) { 30 | return NULL; 31 | } 32 | ++*pos; 33 | return task; 34 | } 35 | 36 | static void tasks_seq_stop(struct seq_file *s, void *v) 37 | { 38 | } 39 | 40 | /* 41 | * The show function. 42 | */ 43 | static int tasks_seq_show(struct seq_file *s, void *v) 44 | { 45 | struct task_struct *task = (struct task_struct *)v; 46 | 47 | seq_printf(s, "%-24s%-5d\n", task->comm, task->pid); 48 | 49 | return 0; 50 | } 51 | 52 | static struct seq_operations tasks_seq_ops = { 53 | .start = tasks_seq_start, 54 | .next = tasks_seq_next, 55 | .stop = tasks_seq_stop, 56 | .show = tasks_seq_show 57 | }; 58 | 59 | static int tasks_open(struct inode *inode, struct file *file) 60 | { 61 | return seq_open(file, &tasks_seq_ops); 62 | } 63 | 64 | static struct file_operations tasks_file_ops = { 65 | .owner = THIS_MODULE, 66 | .open = tasks_open, 67 | .read = seq_read, 68 | .llseek = seq_lseek, 69 | .release = seq_release 70 | }; 71 | 72 | static int __init proc_mytasks_init(void) 73 | { 74 | struct proc_dir_entry *pe; 75 | pe = proc_create("mytasks", 0, NULL, &tasks_file_ops); 76 | if (pe == NULL) { 77 | pr_err("proc_create failed\n"); 78 | return -1; 79 | } 80 | return 0; 81 | } 82 | 83 | static void __exit proc_mytasks_exit(void) 84 | { 85 | remove_proc_entry("mytasks", NULL); 86 | } 87 | 88 | module_init(proc_mytasks_init); 89 | module_exit(proc_mytasks_exit); 90 | MODULE_LICENSE("GPL"); 91 | MODULE_AUTHOR("datawolf"); 92 | -------------------------------------------------------------------------------- /h012_inspect_task_struct/Makefile: -------------------------------------------------------------------------------- 1 | ifneq ($(KERNELRELEASE), ) 2 | obj-m := inspect_task_struct.o 3 | else 4 | KERNELDIR ?=/lib/modules/$(shell uname -r)/build 5 | PWD := $(shell pwd) 6 | all: 7 | $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 8 | clean: 9 | $(MAKE) -C $(KERNELDIR) M=$(PWD) clean 10 | load: 11 | @sudo dmesg -c > /dev/null 12 | @echo "#############[START] #################" 13 | @sudo insmod inspect_task_struct.ko 14 | @sudo dmesg 15 | unload: 16 | @sudo dmesg -c > /dev/null 17 | @sudo rmmod inspect_task_struct 18 | @sudo dmesg 19 | @echo "#############[ END ] #################" 20 | test: 21 | @make load 22 | @make unload 23 | endif 24 | -------------------------------------------------------------------------------- /h012_inspect_task_struct/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawolf/dive-in-kernel/663175ee02d5d976b289bdc64a23f70fefc4368f/h012_inspect_task_struct/README.md -------------------------------------------------------------------------------- /h012_inspect_task_struct/inspect_task_struct.c: -------------------------------------------------------------------------------- 1 | /*********************************************** 2 | * module : inspect_task_struct 3 | * 4 | * Wang Long (wanglong@laoqinren.net) 5 | **********************************************/ 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | static int pid = 1; 14 | module_param(pid, int, 1); 15 | 16 | static int __init inspect_task_struct_init(void) 17 | { 18 | pid_t p = (pid_t)pid; 19 | struct task_struct *task = get_pid_task(find_get_pid(p), PIDTYPE_PID); 20 | struct cred *tcred; 21 | 22 | printk(KERN_ALERT "[Hello] inspect_task_struct \n"); 23 | tcred = (struct cred *)(task->real_cred); 24 | printk("pid = %d, euid = %d\n", task->pid, tcred->euid); 25 | printk("pid = %d, suid = %d\n", task->pid, tcred->suid); 26 | printk("pid = %d, uid = %d\n", task->pid, tcred->uid); 27 | printk("pid = %d, egid = %d\n", task->pid, tcred->egid); 28 | printk("pid = %d, sgid = %d\n", task->pid, tcred->sgid); 29 | printk("pid = %d, gid = %d\n", task->pid, tcred->gid); 30 | printk("pid = %d, task->mm->flags = %lx\n", task->pid, task->mm->flags); 31 | return 0; 32 | } 33 | 34 | static void __exit inspect_task_struct_exit(void) 35 | { 36 | printk(KERN_ALERT "[Goodbye] inspect_task_struct\n"); 37 | } 38 | 39 | module_init(inspect_task_struct_init); 40 | module_exit(inspect_task_struct_exit); 41 | MODULE_LICENSE("GPL"); 42 | MODULE_AUTHOR("datawolf"); 43 | -------------------------------------------------------------------------------- /h013_list_all_workqueues/Makefile: -------------------------------------------------------------------------------- 1 | ifneq ($(KERNELRELEASE), ) 2 | obj-m := list_all_workqueues.o 3 | else 4 | KERNELDIR ?=/lib/modules/$(shell uname -r)/build 5 | PWD := $(shell pwd) 6 | all: 7 | $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 8 | clean: 9 | $(MAKE) -C $(KERNELDIR) M=$(PWD) clean 10 | load: 11 | @sudo dmesg -c > /dev/null 12 | @echo "#############[START] #################" 13 | @sudo insmod list_all_workqueues.ko 14 | @sudo dmesg 15 | unload: 16 | @sudo dmesg -c > /dev/null 17 | @sudo rmmod list_all_workqueues 18 | @sudo dmesg 19 | @echo "#############[ END ] #################" 20 | test: 21 | @make load 22 | @make unload 23 | endif 24 | -------------------------------------------------------------------------------- /h013_list_all_workqueues/README.md: -------------------------------------------------------------------------------- 1 | ## 说明 2 | 3 | 该模块列出了系统上所有的workqueue的个数。由于数据结构位未导出,暂时无法获取 4 | workqueue的名称。 5 | 6 | 7 | ## TODO 8 | 9 | 修改代码,打印workqueue的名称。 10 | -------------------------------------------------------------------------------- /h013_list_all_workqueues/list_all_workqueues.c: -------------------------------------------------------------------------------- 1 | /*********************************************** 2 | * module : list_all_workqueues 3 | * 4 | * Wang Long (wanglong@laoqinren.net) 5 | **********************************************/ 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | // 由于workqueue_struct 结构体没有导出,所以只能打印出队列的个数 14 | struct workqueue_struct_x { 15 | struct list_head pwqs; /* WR: all pwqs of this wq */ 16 | struct list_head list; /* PL: list of all workqueues */ // 将系统上所有的workqueue串到一起 17 | }; 18 | 19 | static int __init list_all_workqueues_init(void) 20 | { 21 | struct workqueue_struct_x *wqx; 22 | int count = 0; 23 | struct list_head *workqueues = (struct list_head *)kallsyms_lookup_name("workqueues"); 24 | 25 | printk(KERN_ALERT "[Hello] list_all_workqueues \n"); 26 | list_for_each_entry(wqx, workqueues, list) { 27 | count++; 28 | printk(KERN_INFO "[workqueue %d]: name\n", 29 | count); 30 | } 31 | return 0; 32 | } 33 | 34 | static void __exit list_all_workqueues_exit(void) 35 | { 36 | printk(KERN_ALERT "[Goodbye] list_all_workqueues\n"); 37 | } 38 | 39 | module_init(list_all_workqueues_init); 40 | module_exit(list_all_workqueues_exit); 41 | MODULE_LICENSE("GPL"); 42 | MODULE_AUTHOR("datawolf"); 43 | -------------------------------------------------------------------------------- /h014_list_all_bdi/Makefile: -------------------------------------------------------------------------------- 1 | ifneq ($(KERNELRELEASE), ) 2 | obj-m := list_all_bdi.o 3 | else 4 | KERNELDIR ?=/lib/modules/$(shell uname -r)/build 5 | PWD := $(shell pwd) 6 | all: 7 | $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 8 | clean: 9 | $(MAKE) -C $(KERNELDIR) M=$(PWD) clean 10 | load: 11 | @sudo dmesg -c > /dev/null 12 | @echo "#############[START] #################" 13 | @sudo insmod list_all_bdi.ko 14 | @sudo dmesg 15 | unload: 16 | @sudo dmesg -c > /dev/null 17 | @sudo rmmod list_all_bdi 18 | @sudo dmesg 19 | @echo "#############[ END ] #################" 20 | test: 21 | @make load 22 | @make unload 23 | endif 24 | -------------------------------------------------------------------------------- /h014_list_all_bdi/README.md: -------------------------------------------------------------------------------- 1 | ## 说明 2 | 3 | 该模块查看了系统上bdi设备。 4 | -------------------------------------------------------------------------------- /h014_list_all_bdi/list_all_bdi.c: -------------------------------------------------------------------------------- 1 | /*********************************************** 2 | * module : list_all_bdi 3 | * 4 | * Wang Long (wanglong@laoqinren.net) 5 | **********************************************/ 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #define K(x) ((x) << ( 12 - 10)) 16 | 17 | static int __init list_all_bdi_init(void) 18 | { 19 | struct list_head *list_bdi; 20 | struct backing_dev_info *bdi; 21 | atomic_long_t *num; 22 | 23 | spinlock_t * lock = (spinlock_t *)kallsyms_lookup_name("bdi_lock"); 24 | list_bdi = (struct list_head *)kallsyms_lookup_name("bdi_list"); 25 | num = (atomic_long_t *)kallsyms_lookup_name("bdi_seq"); 26 | 27 | printk(KERN_ALERT "[Hello] list_all_bdi \n"); 28 | printk(KERN_ALERT "The number of bdi is %ld\n", atomic_long_read(num)); //一般为0 29 | spin_lock(lock); 30 | list_for_each_entry(bdi, list_bdi, bdi_list) { 31 | // device id 32 | printk(KERN_INFO "%s\n", bdi->name); 33 | printk(KERN_INFO "\tra_pages = %lu\n", bdi->ra_pages); 34 | printk(KERN_INFO "\tstate = 0x%lx\n", bdi->state); 35 | printk(KERN_INFO "\tbandwith = %lu kBps\n", (unsigned long) K(bdi->write_bandwidth)); 36 | } 37 | spin_unlock(lock); 38 | return 0; 39 | } 40 | 41 | static void __exit list_all_bdi_exit(void) 42 | { 43 | printk(KERN_ALERT "[Goodbye] list_all_bdi\n"); 44 | } 45 | 46 | module_init(list_all_bdi_init); 47 | module_exit(list_all_bdi_exit); 48 | MODULE_LICENSE("GPL"); 49 | MODULE_AUTHOR("datawolf"); 50 | -------------------------------------------------------------------------------- /h015_workqueue/Makefile: -------------------------------------------------------------------------------- 1 | ifneq ($(KERNELRELEASE), ) 2 | obj-m := myworkqueue.o 3 | else 4 | KERNELDIR ?=/lib/modules/$(shell uname -r)/build 5 | PWD := $(shell pwd) 6 | all: 7 | $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 8 | clean: 9 | $(MAKE) -C $(KERNELDIR) M=$(PWD) clean 10 | load: 11 | @sudo dmesg -c > /dev/null 12 | @echo "#############[START] #################" 13 | @sudo insmod myworkqueue.ko 14 | @sudo dmesg 15 | unload: 16 | @sudo dmesg -c > /dev/null 17 | @sudo rmmod myworkqueue 18 | @sudo dmesg 19 | @echo "#############[ END ] #################" 20 | endif 21 | -------------------------------------------------------------------------------- /h015_workqueue/README.md: -------------------------------------------------------------------------------- 1 | ## 说明 2 | 3 | 该模块演示了linux内核中 workqueue的用法。 4 | -------------------------------------------------------------------------------- /h015_workqueue/myworkqueue.c: -------------------------------------------------------------------------------- 1 | /*********************************************** 2 | * module : workqueue 3 | * 4 | * Wang Long (wanglong@laoqinren.net) 5 | **********************************************/ 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | static struct delayed_work dwork; 12 | static struct workqueue_struct *wq = NULL; 13 | 14 | static void work_handler(struct work_struct *data) 15 | { 16 | printk(KERN_ALERT "work handler for work_item in queue helloworkqueue\n"); 17 | queue_delayed_work(wq, &dwork, 3*HZ); 18 | } 19 | 20 | static int __init workqueue_init(void) 21 | { 22 | printk(KERN_ALERT "[Hello] workqueue \n"); 23 | 24 | wq = create_singlethread_workqueue("helloworkqueue"); 25 | 26 | if (!wq) 27 | goto err; 28 | INIT_DELAYED_WORK(&dwork, work_handler); 29 | queue_delayed_work(wq, &dwork, 3*HZ); 30 | 31 | return 0; 32 | err: 33 | return -1; 34 | } 35 | 36 | static void __exit workqueue_exit(void) 37 | { 38 | cancel_delayed_work(&dwork); 39 | destroy_workqueue(wq); 40 | printk(KERN_ALERT "[Goodbye] workqueue\n"); 41 | } 42 | 43 | module_init(workqueue_init); 44 | module_exit(workqueue_exit); 45 | MODULE_LICENSE("GPL"); 46 | MODULE_AUTHOR("datawolf"); 47 | -------------------------------------------------------------------------------- /h016_list_all_percpu_counter/Makefile: -------------------------------------------------------------------------------- 1 | ifneq ($(KERNELRELEASE), ) 2 | obj-m := list_all_percpu_counter.o 3 | else 4 | KERNELDIR ?=/lib/modules/$(shell uname -r)/build 5 | PWD := $(shell pwd) 6 | all: 7 | $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 8 | clean: 9 | $(MAKE) -C $(KERNELDIR) M=$(PWD) clean 10 | load: 11 | @sudo dmesg -c > /dev/null 12 | @echo "#############[START] #################" 13 | @sudo insmod list_all_percpu_counter.ko 14 | @sudo dmesg 15 | unload: 16 | @sudo dmesg -c > /dev/null 17 | @sudo rmmod list_all_percpu_counter 18 | @sudo dmesg 19 | @echo "#############[ END ] #################" 20 | test: 21 | @make load 22 | @make unload 23 | endif 24 | -------------------------------------------------------------------------------- /h016_list_all_percpu_counter/list_all_percpu_counter.c: -------------------------------------------------------------------------------- 1 | /*********************************************** 2 | * module : list_all_percpu_counter 3 | * 4 | * Wang Long (wanglong@laoqinren.net) 5 | **********************************************/ 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | static int __init list_all_percpu_counter_init(void) 15 | { 16 | struct list_head *percpu_counters = NULL; 17 | spinlock_t *percpu_counters_lock = NULL; 18 | struct percpu_counter *fbc; 19 | int count = 0; 20 | 21 | percpu_counters = (struct list_head *)kallsyms_lookup_name("percpu_counters"); 22 | percpu_counters_lock = (spinlock_t *)kallsyms_lookup_name("percpu_counters_lock"); 23 | 24 | printk(KERN_ALERT "[Hello] list_all_percpu_counter \n"); 25 | 26 | spin_lock_irq(percpu_counters_lock); 27 | list_for_each_entry(fbc, percpu_counters, list) { 28 | count++; 29 | printk(KERN_INFO "[%d] %ld\n", count, (long)percpu_counter_sum(fbc)); 30 | } 31 | spin_unlock_irq(percpu_counters_lock); 32 | 33 | return 0; 34 | } 35 | 36 | static void __exit list_all_percpu_counter_exit(void) 37 | { 38 | printk(KERN_ALERT "[Goodbye] list_all_percpu_counter\n"); 39 | } 40 | 41 | module_init(list_all_percpu_counter_init); 42 | module_exit(list_all_percpu_counter_exit); 43 | MODULE_LICENSE("GPL"); 44 | MODULE_AUTHOR("datawolf"); 45 | -------------------------------------------------------------------------------- /h017_roundup_pow_of_two/Makefile: -------------------------------------------------------------------------------- 1 | ifneq ($(KERNELRELEASE), ) 2 | obj-m := roundup_pow_of_two.o 3 | else 4 | KERNELDIR ?=/lib/modules/$(shell uname -r)/build 5 | PWD := $(shell pwd) 6 | all: 7 | $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 8 | clean: 9 | $(MAKE) -C $(KERNELDIR) M=$(PWD) clean 10 | load: 11 | @sudo dmesg -c > /dev/null 12 | @echo "#############[START] #################" 13 | @sudo insmod roundup_pow_of_two.ko 14 | @sudo dmesg 15 | unload: 16 | @sudo dmesg -c > /dev/null 17 | @sudo rmmod roundup_pow_of_two 18 | @sudo dmesg 19 | @echo "#############[ END ] #################" 20 | test: 21 | @make load 22 | @make unload 23 | endif 24 | -------------------------------------------------------------------------------- /h017_roundup_pow_of_two/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawolf/dive-in-kernel/663175ee02d5d976b289bdc64a23f70fefc4368f/h017_roundup_pow_of_two/README.md -------------------------------------------------------------------------------- /h017_roundup_pow_of_two/roundup_pow_of_two.c: -------------------------------------------------------------------------------- 1 | /*********************************************** 2 | * module : roundup_pow_of_two 3 | * 4 | * Wang Long (wanglong@laoqinren.net) 5 | **********************************************/ 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | static int __init roundup_pow_of_two_init(void) 12 | { 13 | const unsigned long period = roundup_pow_of_two(3 * HZ); 14 | 15 | printk(KERN_ALERT "[Hello] roundup_pow_of_two \n"); 16 | printk(KERN_INFO "HZ = %d\n", HZ); 17 | printk(KERN_INFO "roundup_pow_of_two(3 * HZ) = %lu\n", period); 18 | printk(KERN_INFO "rounddown_pow_of_two(3 * HZ) = %lu\n", rounddown_pow_of_two(3 * HZ)); 19 | printk(KERN_INFO "ilog2(period) = %d\n", ilog2(period)); 20 | return 0; 21 | } 22 | 23 | static void __exit roundup_pow_of_two_exit(void) 24 | { 25 | printk(KERN_ALERT "[Goodbye] roundup_pow_of_two\n"); 26 | } 27 | 28 | module_init(roundup_pow_of_two_init); 29 | module_exit(roundup_pow_of_two_exit); 30 | MODULE_LICENSE("GPL"); 31 | MODULE_AUTHOR("datawolf"); 32 | -------------------------------------------------------------------------------- /h018_percpu_refcount/Makefile: -------------------------------------------------------------------------------- 1 | ifneq ($(KERNELRELEASE), ) 2 | obj-m := percpu_refcount.o 3 | else 4 | KERNELDIR ?=/lib/modules/$(shell uname -r)/build 5 | PWD := $(shell pwd) 6 | all: 7 | $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 8 | clean: 9 | $(MAKE) -C $(KERNELDIR) M=$(PWD) clean 10 | load: 11 | @sudo dmesg -c > /dev/null 12 | @echo "#############[START] #################" 13 | @sudo insmod percpu_refcount.ko 14 | @sudo dmesg 15 | unload: 16 | @sudo dmesg -c > /dev/null 17 | @sudo rmmod percpu_refcount 18 | @sudo dmesg 19 | @echo "#############[ END ] #################" 20 | test: 21 | @make load 22 | @make unload 23 | endif 24 | -------------------------------------------------------------------------------- /h018_percpu_refcount/README.md: -------------------------------------------------------------------------------- 1 | ## 说明 2 | 3 | 只有调用了`percpu_ref_kill`后,后续的`percpu_ref_put`才会检测引用计数是否为0; 4 | 当引用计数为0时,才会调用`release`方法。 5 | -------------------------------------------------------------------------------- /h018_percpu_refcount/percpu_refcount.c: -------------------------------------------------------------------------------- 1 | /*********************************************** 2 | * module : percpu_refcount 3 | * 4 | * Wang Long (wanglong@laoqinren.net) 5 | **********************************************/ 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | static void test_release(struct percpu_ref *ref) 12 | { 13 | printk(KERN_INFO "percpu_refcount release called\n"); 14 | } 15 | 16 | struct test { 17 | struct percpu_ref refcnt; 18 | int flags; 19 | }; 20 | 21 | static struct test test; 22 | 23 | static int __init percpu_refcount_init(void) 24 | { 25 | int ret; 26 | 27 | ret = percpu_ref_init(&test.refcnt, test_release, 0, GFP_KERNEL); 28 | if (ret) 29 | goto out_free_ref; 30 | 31 | percpu_ref_get(&test.refcnt); 32 | percpu_ref_get(&test.refcnt); 33 | 34 | //percpu_ref_kill(&test.refcnt); 35 | //只有调用了percpu_ref_kill后,后续的percpu_ref_put才会检测是否为0 36 | // 只有为0时,才会调用test_release方法。 37 | percpu_ref_put(&test.refcnt); 38 | percpu_ref_put(&test.refcnt); 39 | out_free_ref: 40 | printk(KERN_ALERT "[Hello] percpu_refcount \n"); 41 | return ret;; 42 | } 43 | 44 | static void __exit percpu_refcount_exit(void) 45 | { 46 | 47 | percpu_ref_exit(&test.refcnt); 48 | printk(KERN_ALERT "[Goodbye] percpu_refcount\n"); 49 | } 50 | 51 | module_init(percpu_refcount_init); 52 | module_exit(percpu_refcount_exit); 53 | MODULE_LICENSE("GPL"); 54 | MODULE_AUTHOR("datawolf"); 55 | -------------------------------------------------------------------------------- /h019_hweight/Makefile: -------------------------------------------------------------------------------- 1 | ifneq ($(KERNELRELEASE), ) 2 | obj-m := hweight.o 3 | else 4 | KERNELDIR ?=/lib/modules/$(shell uname -r)/build 5 | PWD := $(shell pwd) 6 | all: 7 | $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 8 | clean: 9 | $(MAKE) -C $(KERNELDIR) M=$(PWD) clean 10 | load: 11 | @sudo dmesg -c > /dev/null 12 | @echo "#############[START] #################" 13 | @sudo insmod hweight.ko 14 | @sudo dmesg 15 | unload: 16 | @sudo dmesg -c > /dev/null 17 | @sudo rmmod hweight 18 | @sudo dmesg 19 | @echo "#############[ END ] #################" 20 | test: 21 | @make load 22 | @make unload 23 | endif 24 | -------------------------------------------------------------------------------- /h019_hweight/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawolf/dive-in-kernel/663175ee02d5d976b289bdc64a23f70fefc4368f/h019_hweight/README.md -------------------------------------------------------------------------------- /h019_hweight/hweight.c: -------------------------------------------------------------------------------- 1 | /*********************************************** 2 | * module : hweight 3 | * 4 | * Wang Long (wanglong@laoqinren.net) 5 | **********************************************/ 6 | #include 7 | #include 8 | #include 9 | 10 | static int __init hweight_init(void) 11 | { 12 | printk(KERN_ALERT "[Hello] hweight \n"); 13 | printk(KERN_INFO "hweight_long(33) = %ld\n", hweight_long(33)); 14 | printk(KERN_INFO "hweight_long(32) = %ld\n", hweight_long(32)); 15 | printk(KERN_INFO "hweight_long(52) = %ld\n", hweight_long(52)); 16 | return 0; 17 | } 18 | 19 | static void __exit hweight_exit(void) 20 | { 21 | printk(KERN_ALERT "[Goodbye] hweight\n"); 22 | } 23 | 24 | module_init(hweight_init); 25 | module_exit(hweight_exit); 26 | MODULE_LICENSE("GPL"); 27 | MODULE_AUTHOR("datawolf"); 28 | -------------------------------------------------------------------------------- /h020_rw_semaphore/Makefile: -------------------------------------------------------------------------------- 1 | ifneq ($(KERNELRELEASE), ) 2 | obj-m := semaphore_test.o 3 | else 4 | KERNELDIR ?=/lib/modules/$(shell uname -r)/build 5 | PWD := $(shell pwd) 6 | all: 7 | $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 8 | clean: 9 | $(MAKE) -C $(KERNELDIR) M=$(PWD) clean 10 | load: 11 | @sudo dmesg -c > /dev/null 12 | @echo "#############[START] #################" 13 | @sudo insmod semaphore_test.ko 14 | @sudo dmesg 15 | unload: 16 | @sudo dmesg -c > /dev/null 17 | @sudo rmmod semaphore_test 18 | @sudo dmesg 19 | @echo "#############[ END ] #################" 20 | test: 21 | @make load 22 | @make unload 23 | endif 24 | -------------------------------------------------------------------------------- /h020_rw_semaphore/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawolf/dive-in-kernel/663175ee02d5d976b289bdc64a23f70fefc4368f/h020_rw_semaphore/README.md -------------------------------------------------------------------------------- /h021_proc_write/Makefile: -------------------------------------------------------------------------------- 1 | ifneq ($(KERNELRELEASE), ) 2 | obj-m := proc_write.o 3 | else 4 | KERNELDIR ?=/lib/modules/$(shell uname -r)/build 5 | PWD := $(shell pwd) 6 | all: 7 | $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 8 | clean: 9 | $(MAKE) -C $(KERNELDIR) M=$(PWD) clean 10 | load: 11 | @sudo dmesg -c > /dev/null 12 | @echo "#############[START] #################" 13 | @sudo insmod proc_write.ko 14 | @sudo dmesg 15 | unload: 16 | @sudo dmesg -c > /dev/null 17 | @sudo rmmod proc_write 18 | @sudo dmesg 19 | @echo "#############[ END ] #################" 20 | test: 21 | @make load 22 | @make unload 23 | endif 24 | -------------------------------------------------------------------------------- /h021_proc_write/README.md: -------------------------------------------------------------------------------- 1 | ## 说明 2 | 3 | 本模块用来验证 proc中的write接口中count值的含义,并验证其正确的处理方法。 4 | 5 | 6 | ### 不进行 cmd[count-1] = '\0'; 处理 7 | 8 | ``` 9 | ~/dive-in-kernel/h021_proc_write (master) # echo "helloworld" > /proc/proc_write 10 | root@127.0.0.1::[00:29:58]::[Exit Code: 0] -> 11 | ~/dive-in-kernel/h021_proc_write (master) # cat /proc/proc_write 12 | helloworld 13 | (11) 14 | root@127.0.0.1::[00:30:04]::[Exit Code: 0] -> 15 | ~/dive-in-kernel/h021_proc_write (master) # echo "12" > /proc/proc_write 16 | root@127.0.0.1::[00:30:19]::[Exit Code: 0] -> 17 | ~/dive-in-kernel/h021_proc_write (master) # cat /proc/proc_write 18 | 12 19 | loworld 20 | (11) 21 | root@127.0.0.1::[00:30:23]::[Exit Code: 0] -> 22 | ``` 23 | 24 | ### 进行 cmd[count-1] = '\0'; 处理 25 | 26 | ``` 27 | root@127.0.0.1::[00:33:59]::[Exit Code: 0] -> 28 | ~/dive-in-kernel/h021_proc_write (master) # echo "helloworld" > /proc/proc_write 29 | root@127.0.0.1::[00:34:11]::[Exit Code: 0] -> 30 | ~/dive-in-kernel/h021_proc_write (master) # cat /proc/proc_write 31 | helloworld(10) 32 | root@127.0.0.1::[00:34:18]::[Exit Code: 0] -> 33 | ~/dive-in-kernel/h021_proc_write (master) # echo "12" > /proc/proc_write 34 | root@127.0.0.1::[00:34:33]::[Exit Code: 0] -> 35 | ~/dive-in-kernel/h021_proc_write (master) # cat /proc/proc_write 36 | 12(2) 37 | root@127.0.0.1::[00:34:35]::[Exit Code: 0] -> 38 | ~/dive-in-kernel/h021_proc_write (master) # 39 | ``` 40 | 41 | 所以,当将输入当做字符串处理时,需要将末尾的`\n`换成`\0`. 42 | -------------------------------------------------------------------------------- /h021_proc_write/proc_write.c: -------------------------------------------------------------------------------- 1 | /*********************************************** 2 | * module : proc_write 3 | * 4 | * Wang Long (wanglong@laoqinren.net) 5 | **********************************************/ 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #define PROC_FILE "proc_write" 15 | 16 | char cmd[20]; 17 | 18 | static int cmd_show(struct seq_file *m, void *v) 19 | { 20 | seq_printf(m, "%s(%zu)\n", cmd, strlen(cmd)); 21 | return 0; 22 | } 23 | 24 | static ssize_t cmd_write(struct file *file, const char __user *buf, 25 | size_t count, loff_t *offs) 26 | { 27 | // count 的值为输入字符串的长度+1,即字符串后面会添加一个`\n` 28 | if (count < 1 || count > 20 || *offs) 29 | return -EINVAL; 30 | 31 | if (copy_from_user(cmd, buf, count)) 32 | return -EFAULT; 33 | 34 | // 在处理字符串时,需要将`\n`替换成`\0` 35 | cmd[count-1] = '\0'; 36 | 37 | printk(KERN_ALERT "count = %zu\n", count); 38 | return count; 39 | } 40 | 41 | static int cmd_open(struct inode *inode, struct file *filp) 42 | { 43 | return single_open(filp, cmd_show, NULL); 44 | } 45 | 46 | static const struct file_operations cmd_fops = { 47 | .open = cmd_open, 48 | .read = seq_read, 49 | .write = cmd_write, 50 | .llseek = seq_lseek, 51 | .release = single_release, 52 | }; 53 | 54 | static int __init proc_write_init(void) 55 | { 56 | struct proc_dir_entry *pe; 57 | printk(KERN_ALERT "[Hello] proc_write \n"); 58 | 59 | pe = proc_create(PROC_FILE, 0644, NULL, &cmd_fops); 60 | if (!pe) 61 | return -ENOMEM; 62 | 63 | return 0; 64 | } 65 | 66 | static void __exit proc_write_exit(void) 67 | { 68 | printk(KERN_ALERT "[Goodbye] proc_write\n"); 69 | remove_proc_entry(PROC_FILE, NULL); 70 | } 71 | 72 | module_init(proc_write_init); 73 | module_exit(proc_write_exit); 74 | MODULE_LICENSE("GPL"); 75 | MODULE_AUTHOR("datawolf"); 76 | -------------------------------------------------------------------------------- /h022_mem_section/Makefile: -------------------------------------------------------------------------------- 1 | ifneq ($(KERNELRELEASE), ) 2 | obj-m := mem_section_test.o 3 | else 4 | KERNELDIR ?=/lib/modules/$(shell uname -r)/build 5 | PWD := $(shell pwd) 6 | all: 7 | $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 8 | clean: 9 | $(MAKE) -C $(KERNELDIR) M=$(PWD) clean 10 | load: 11 | @sudo dmesg -c > /dev/null 12 | @echo "#############[START] #################" 13 | @sudo insmod mem_section_test.ko 14 | @sudo dmesg 15 | unload: 16 | @sudo dmesg -c > /dev/null 17 | @sudo rmmod mem_section_test 18 | @sudo dmesg 19 | @echo "#############[ END ] #################" 20 | test: 21 | @make load 22 | @make unload 23 | endif 24 | -------------------------------------------------------------------------------- /h022_mem_section/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawolf/dive-in-kernel/663175ee02d5d976b289bdc64a23f70fefc4368f/h022_mem_section/README.md -------------------------------------------------------------------------------- /h022_mem_section/mem_section_test.c: -------------------------------------------------------------------------------- 1 | /*********************************************** 2 | * module : mem_section_test 3 | * 4 | * Wang Long (wanglong@laoqinren.net) 5 | **********************************************/ 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | static int __init mem_section_test_init(void) 13 | { 14 | struct page *page = (struct page *)0xffffea00b2e65140; 15 | struct page_cgroup *pc = (struct page_cgroup *)0xffff8818bec80000; 16 | 17 | unsigned long pfn = page_to_pfn(page); 18 | 19 | printk(KERN_ALERT "[Hello] mem_section_test \n"); 20 | printk(KERN_ALERT "pfn = 0x%lx\n", pfn); 21 | printk(KERN_ALERT "pc = 0x%p\n", (pc+pfn)); 22 | 23 | return 0; 24 | } 25 | 26 | static void __exit mem_section_test_exit(void) 27 | { 28 | printk(KERN_ALERT "[Goodbye] mem_section_test\n"); 29 | } 30 | 31 | module_init(mem_section_test_init); 32 | module_exit(mem_section_test_exit); 33 | MODULE_LICENSE("GPL"); 34 | MODULE_AUTHOR("datawolf"); 35 | -------------------------------------------------------------------------------- /h023_spin_lock_irq/Makefile: -------------------------------------------------------------------------------- 1 | ifneq ($(KERNELRELEASE), ) 2 | obj-m := spin_lock_irq_test.o 3 | else 4 | KERNELDIR ?=/lib/modules/$(shell uname -r)/build 5 | PWD := $(shell pwd) 6 | all: 7 | $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 8 | clean: 9 | $(MAKE) -C $(KERNELDIR) M=$(PWD) clean 10 | load: 11 | @sudo dmesg -c > /dev/null 12 | @echo "#############[START] #################" 13 | @sudo insmod spin_lock_irq_test.ko 14 | @sudo dmesg 15 | unload: 16 | @sudo dmesg -c > /dev/null 17 | @sudo rmmod spin_lock_irq_test 18 | @sudo dmesg 19 | @echo "#############[ END ] #################" 20 | test: 21 | @make load 22 | @make unload 23 | endif 24 | -------------------------------------------------------------------------------- /h023_spin_lock_irq/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawolf/dive-in-kernel/663175ee02d5d976b289bdc64a23f70fefc4368f/h023_spin_lock_irq/README.md -------------------------------------------------------------------------------- /h023_spin_lock_irq/spin_lock_irq_test.c: -------------------------------------------------------------------------------- 1 | /*********************************************** 2 | * module : spin_lock_irq_test 3 | * 4 | * Wang Long (wanglong@laoqinren.net) 5 | **********************************************/ 6 | #include 7 | #include 8 | #include 9 | 10 | static inline unsigned long get_flag(void) 11 | { 12 | unsigned long flags; 13 | 14 | /* 15 | * "=rm" is safe here, because "pop" adjusts the stack before 16 | * it evaluates its effective address -- this is part of the 17 | * documented behavior of the "pop" instruction. 18 | */ 19 | asm volatile("# __raw_save_flags\n\t" 20 | "pushf ; pop %0" 21 | : "=rm" (flags) 22 | : /* no input */ 23 | : "memory"); 24 | 25 | return flags; 26 | } 27 | 28 | spinlock_t mytest1_spinlock; 29 | spinlock_t mytest2_spinlock; 30 | unsigned long flag1; 31 | unsigned long flag2; 32 | 33 | static int __init spin_lock_irq_test_init(void) 34 | { 35 | printk(KERN_ALERT "[Hello] spin_lock_irq_test \n"); 36 | 37 | spin_lock_init(&mytest1_spinlock); 38 | spin_lock_init(&mytest2_spinlock); 39 | 40 | printk(KERN_ALERT "begin\n"); 41 | printk(KERN_ALERT "mytest1 0x%x, flag1 = 0x%lx\n",mytest1_spinlock.rlock.raw_lock.val.counter, flag1); 42 | printk(KERN_ALERT "mytest2 0x%x, flag2 = 0x%lx\n",mytest2_spinlock.rlock.raw_lock.val.counter, flag2); 43 | printk(KERN_ALERT "flag = 0x%lx\n", get_flag()); 44 | spin_lock_irqsave(&mytest1_spinlock, flag1); 45 | printk(KERN_ALERT "lock mytest1 0x%x, flag1 = 0x%lx\n",mytest1_spinlock.rlock.raw_lock.val.counter, flag1); 46 | printk(KERN_ALERT "flag = 0x%lx\n", get_flag()); 47 | // spin_lock_irqsave(&mytest2_spinlock, flag2); 48 | spin_lock_irq(&mytest2_spinlock); 49 | printk(KERN_ALERT "lock mytest2 0x%x, flag2 = 0x%lx\n",mytest2_spinlock.rlock.raw_lock.val.counter, flag2); 50 | printk(KERN_ALERT "flag = 0x%lx\n", get_flag()); 51 | // spin_unlock_irqrestore(&mytest2_spinlock, flag2); 52 | spin_unlock_irq(&mytest2_spinlock); 53 | printk(KERN_ALERT "unlock mytest2 0x%x, flag2 = 0x%lx\n",mytest2_spinlock.rlock.raw_lock.val.counter, flag2); 54 | printk(KERN_ALERT "flag = 0x%lx\n", get_flag()); 55 | spin_unlock_irqrestore(&mytest1_spinlock, flag1); 56 | printk(KERN_ALERT "unlock mytest1 0x%x, flag1 = 0x%lx\n",mytest1_spinlock.rlock.raw_lock.val.counter, flag1); 57 | printk(KERN_ALERT "flag = 0x%lx\n", get_flag()); 58 | 59 | return 0; 60 | } 61 | 62 | static void __exit spin_lock_irq_test_exit(void) 63 | { 64 | printk(KERN_ALERT "[Goodbye] spin_lock_irq_test\n"); 65 | } 66 | 67 | module_init(spin_lock_irq_test_init); 68 | module_exit(spin_lock_irq_test_exit); 69 | MODULE_LICENSE("GPL"); 70 | MODULE_AUTHOR("datawolf"); 71 | 72 | -------------------------------------------------------------------------------- /h023_spin_lock_proc/Makefile: -------------------------------------------------------------------------------- 1 | ifneq ($(KERNELRELEASE), ) 2 | obj-m := spin_lock_proc.o 3 | else 4 | KERNELDIR ?=/lib/modules/$(shell uname -r)/build 5 | PWD := $(shell pwd) 6 | all: 7 | $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 8 | clean: 9 | $(MAKE) -C $(KERNELDIR) M=$(PWD) clean 10 | load: 11 | @sudo dmesg -c > /dev/null 12 | @echo "#############[START] #################" 13 | @sudo insmod spin_lock_proc.ko 14 | @sudo dmesg 15 | unload: 16 | @sudo dmesg -c > /dev/null 17 | @sudo rmmod spin_lock_proc 18 | @sudo dmesg 19 | @echo "#############[ END ] #################" 20 | test: 21 | @make load 22 | @make unload 23 | endif 24 | -------------------------------------------------------------------------------- /h023_spin_lock_proc/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawolf/dive-in-kernel/663175ee02d5d976b289bdc64a23f70fefc4368f/h023_spin_lock_proc/README.md -------------------------------------------------------------------------------- /h023_spin_lock_proc/spin_lock_proc.c: -------------------------------------------------------------------------------- 1 | /*********************************************** 2 | * module : spin_lock_proc 3 | * 4 | * Wang Long (wanglong@laoqinren.net) 5 | **********************************************/ 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #define PROC_FILE "spinlock" 14 | 15 | spinlock_t mytest_spinlock; 16 | EXPORT_SYMBOL(mytest_spinlock); 17 | 18 | static int spinlock_proc_show(struct seq_file *m, void *v) 19 | { 20 | seq_printf(m, "0x%x\n",mytest_spinlock.rlock.raw_lock.val.counter ); 21 | return 0; 22 | } 23 | 24 | static int spinlock_proc_open(struct inode *inode, struct file *file) 25 | { 26 | return single_open(file, spinlock_proc_show, NULL); 27 | } 28 | 29 | static const struct file_operations spinlock_proc_fops = { 30 | .open = spinlock_proc_open, 31 | .read = seq_read, 32 | .llseek = seq_lseek, 33 | .release = single_release, 34 | }; 35 | 36 | static int __init spin_lock_proc_init(void) 37 | { 38 | struct proc_dir_entry *pe; 39 | printk(KERN_ALERT "[Hello] spin_lock_proc \n"); 40 | 41 | spin_lock_init(&mytest_spinlock); 42 | pe = proc_create(PROC_FILE, 0644, NULL, &spinlock_proc_fops); 43 | if (!pe) 44 | return -ENOMEM; 45 | return 0; 46 | } 47 | 48 | static void __exit spin_lock_proc_exit(void) 49 | { 50 | printk(KERN_ALERT "[Goodbye] spin_lock_proc\n"); 51 | remove_proc_entry(PROC_FILE, NULL); 52 | } 53 | 54 | module_init(spin_lock_proc_init); 55 | module_exit(spin_lock_proc_exit); 56 | MODULE_LICENSE("GPL"); 57 | MODULE_AUTHOR("datawolf"); 58 | -------------------------------------------------------------------------------- /h024_shrink_zone_test/Makefile: -------------------------------------------------------------------------------- 1 | ifneq ($(KERNELRELEASE), ) 2 | obj-m := shrink_zone_test.o 3 | else 4 | KERNELDIR ?=/lib/modules/$(shell uname -r)/build 5 | PWD := $(shell pwd) 6 | all: 7 | $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 8 | clean: 9 | $(MAKE) -C $(KERNELDIR) M=$(PWD) clean 10 | load: 11 | @sudo dmesg -c > /dev/null 12 | @echo "#############[START] #################" 13 | @sudo insmod shrink_zone_test.ko 14 | @sudo dmesg 15 | unload: 16 | @sudo dmesg -c > /dev/null 17 | @sudo rmmod shrink_zone_test 18 | @sudo dmesg 19 | @echo "#############[ END ] #################" 20 | test: 21 | @make load 22 | @make unload 23 | endif 24 | -------------------------------------------------------------------------------- /h024_shrink_zone_test/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawolf/dive-in-kernel/663175ee02d5d976b289bdc64a23f70fefc4368f/h024_shrink_zone_test/README.md -------------------------------------------------------------------------------- /h024_shrink_zone_test/shrink_zone_test.c: -------------------------------------------------------------------------------- 1 | /*********************************************** 2 | * module : shrink_zone_test 3 | * 4 | * Wang Long (wanglong@laoqinren.net) 5 | **********************************************/ 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #define for_each_zone1(zone) \ 13 | for (zone = (first_online_pgdat2())->node_zones; \ 14 | zone; \ 15 | zone = next_zone2(zone)) 16 | 17 | typedef struct pglist_data* (*first_online_pgdat1)(void); 18 | typedef struct zone* (*next_zone1)(struct zone *zone); 19 | typedef int(*zone_reclaim)(struct zone *zone, gfp_t gfp_mask, unsigned int order); 20 | 21 | static int __init shrink_zone_test_init(void) 22 | { 23 | struct zone *z; 24 | printk(KERN_ALERT "[Hello] shrink_zone_test \n"); 25 | first_online_pgdat1 first_online_pgdat2; 26 | next_zone1 next_zone2; 27 | zone_reclaim zone_reclaim2; 28 | next_zone2 = kallsyms_lookup_name("next_zone"); 29 | first_online_pgdat2 = kallsyms_lookup_name("first_online_pgdat"); 30 | zone_reclaim2 = kallsyms_lookup_name("zone_reclaim"); 31 | 32 | for_each_zone1(z) { 33 | printk(KERN_ALERT "node= %d, name = %s \n", z->node, z->name); 34 | zone_reclaim2(z, GFP_KERNEL, 2); 35 | } 36 | 37 | return 0; 38 | } 39 | 40 | static void __exit shrink_zone_test_exit(void) 41 | { 42 | printk(KERN_ALERT "[Goodbye] shrink_zone_test\n"); 43 | } 44 | 45 | module_init(shrink_zone_test_init); 46 | module_exit(shrink_zone_test_exit); 47 | MODULE_LICENSE("GPL"); 48 | MODULE_AUTHOR("datawolf"); 49 | -------------------------------------------------------------------------------- /h025_waitqueue/Makefile: -------------------------------------------------------------------------------- 1 | ifneq ($(KERNELRELEASE), ) 2 | obj-m := mywaitqueue.o 3 | else 4 | KERNELDIR ?=/lib/modules/$(shell uname -r)/build 5 | PWD := $(shell pwd) 6 | all: 7 | $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 8 | clean: 9 | $(MAKE) -C $(KERNELDIR) M=$(PWD) clean 10 | load: 11 | @sudo dmesg -c > /dev/null 12 | @echo "#############[START] #################" 13 | @sudo insmod mywaitqueue.ko 14 | @sudo dmesg 15 | unload: 16 | @sudo dmesg -c > /dev/null 17 | @sudo rmmod mywaitqueue 18 | @sudo dmesg 19 | @echo "#############[ END ] #################" 20 | test: 21 | @make load 22 | @make unload 23 | endif 24 | -------------------------------------------------------------------------------- /h025_waitqueue/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawolf/dive-in-kernel/663175ee02d5d976b289bdc64a23f70fefc4368f/h025_waitqueue/README.md -------------------------------------------------------------------------------- /h025_waitqueue/mywaitqueue.c: -------------------------------------------------------------------------------- 1 | /*********************************************** 2 | * module : mywaitqueue 3 | * 4 | * Wang Long (w@laoqinren.net) 5 | **********************************************/ 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | static int read_count = 0; 15 | static struct task_struct *wait_thread; 16 | // Initializing waitqueue statically 17 | DECLARE_WAIT_QUEUE_HEAD(test_waitqueue); 18 | static int wait_queue_flag = 0; 19 | 20 | static int my_waitqueue_show(struct seq_file *m, void *v) 21 | { 22 | printk(KERN_ALERT "Read function\n"); 23 | seq_printf(m, "read_count = %d\n", read_count); 24 | wait_queue_flag = 1; 25 | wake_up_interruptible(&test_waitqueue); // wake up only one process from wait queue 26 | return 0; 27 | } 28 | 29 | static int my_waitqueue_open(struct inode *inode, struct file *filp) 30 | { 31 | return single_open(filp, my_waitqueue_show, NULL); 32 | } 33 | 34 | static struct file_operations test_wait_queue_fops = { 35 | .open = my_waitqueue_open, 36 | .read = seq_read, 37 | .llseek = seq_lseek, 38 | .release = single_release, 39 | }; 40 | 41 | static int wait_function(void *unused) 42 | { 43 | while(1) { 44 | printk(KERN_ALERT "Waiting For Event...\n"); 45 | // sleep until wait_queue_flag != 0 46 | wait_event_interruptible(test_waitqueue, wait_queue_flag != 0); 47 | if (wait_queue_flag == 2) { 48 | printk(KERN_ALERT "Event Came From Exit Function\n"); 49 | return 0; 50 | } 51 | printk(KERN_ALERT "Event Came From Read Function - %d\n", ++read_count); 52 | wait_queue_flag = 0; 53 | } 54 | 55 | return 0; 56 | } 57 | 58 | static int __init mywaitqueue_init(void) 59 | { 60 | struct proc_dir_entry *pe; 61 | 62 | printk(KERN_ALERT "[Hello] mywaitqueue \n"); 63 | pe = proc_create("test_wait_queue", 0644, NULL, &test_wait_queue_fops); 64 | if (!pe) 65 | return -ENOMEM; 66 | 67 | // Create the kernel thread with name "MyWaitThread" 68 | wait_thread = kthread_create(wait_function, NULL, "MyWaitThread"); 69 | if (wait_thread) { 70 | printk(KERN_ALERT "Thread created successfully\n"); 71 | wake_up_process(wait_thread); 72 | } else { 73 | printk(KERN_ALERT "Thread creation failed\n"); 74 | } 75 | 76 | return 0; 77 | } 78 | 79 | static void __exit mywaitqueue_exit(void) 80 | { 81 | wait_queue_flag = 2; 82 | wake_up_interruptible(&test_waitqueue); 83 | printk(KERN_ALERT "[Goodbye] mywaitqueue\n"); 84 | remove_proc_entry("test_wait_queue", NULL); 85 | } 86 | 87 | module_init(mywaitqueue_init); 88 | module_exit(mywaitqueue_exit); 89 | MODULE_LICENSE("GPL"); 90 | 91 | 92 | -------------------------------------------------------------------------------- /h026_css_set_cg_links/Makefile: -------------------------------------------------------------------------------- 1 | ifneq ($(KERNELRELEASE), ) 2 | obj-m := css_set_cg_links.o 3 | else 4 | KERNELDIR ?=/lib/modules/$(shell uname -r)/build 5 | PWD := $(shell pwd) 6 | all: 7 | $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 8 | clean: 9 | $(MAKE) -C $(KERNELDIR) M=$(PWD) clean 10 | load: 11 | @sudo dmesg -c > /dev/null 12 | @echo "#############[START] #################" 13 | @sudo insmod css_set_cg_links.ko 14 | @sudo dmesg 15 | unload: 16 | @sudo dmesg -c > /dev/null 17 | @sudo rmmod css_set_cg_links 18 | @sudo dmesg 19 | @echo "#############[ END ] #################" 20 | test: 21 | @make load 22 | @make unload 23 | endif 24 | -------------------------------------------------------------------------------- /h026_css_set_cg_links/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawolf/dive-in-kernel/663175ee02d5d976b289bdc64a23f70fefc4368f/h026_css_set_cg_links/README.md -------------------------------------------------------------------------------- /h026_css_set_cg_links/css_set_cg_links.c: -------------------------------------------------------------------------------- 1 | /*********************************************** 2 | * module : css_set_cg_links 3 | * 4 | * Wang Long (w@laoqinren.net) 5 | **********************************************/ 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | 16 | static int pid = 1; 17 | module_param(pid, int, 1); 18 | 19 | 20 | struct cg_cgroup_link { 21 | struct list_head cgrp_link_list; 22 | struct cgroup *cgrp; 23 | struct list_head cg_link_list; 24 | struct css_set *cg; 25 | }; 26 | 27 | static int __init css_set_cg_links_init(void) 28 | { 29 | pid_t p = (pid_t)pid; 30 | struct task_struct *tk = get_pid_task(find_get_pid(p), PIDTYPE_PID); 31 | struct css_set *init_css = (struct css_set*)kallsyms_lookup_name("init_css_set"); 32 | struct css_set *cg; 33 | struct cg_cgroup_link *link; 34 | 35 | printk(KERN_ALERT "[Hello] css_set_cg_links \n"); 36 | printk("task name: %s[%d]\n", tk->comm, tk->pid); 37 | 38 | cg = tk->cgroups; 39 | printk("###### css_set info #######\n"); 40 | printk("css_set.refcount = %d\n", cg->refcount.counter); 41 | 42 | if (cg == init_css) 43 | printk("@@@@@ in init cgroup @@@@@\n"); 44 | else 45 | printk("@@@@@ NOT in init cgroup @@@@@\n"); 46 | 47 | list_for_each_entry(link, &cg->cg_links, cg_link_list) { 48 | struct cgroup *c = link->cgrp; 49 | const char *name; 50 | 51 | if (c->dentry) 52 | name = c->dentry->d_name.name; 53 | else 54 | name = "?"; 55 | printk("Root %d(%s) group %s\n", c->root->hierarchy_id, c->root->name, name); 56 | } 57 | 58 | return 0; 59 | } 60 | 61 | static void __exit css_set_cg_links_exit(void) 62 | { 63 | printk(KERN_ALERT "[Goodbye] css_set_cg_links\n"); 64 | } 65 | 66 | module_init(css_set_cg_links_init); 67 | module_exit(css_set_cg_links_exit); 68 | MODULE_LICENSE("GPL"); 69 | -------------------------------------------------------------------------------- /h027_cgroup_css_links/Makefile: -------------------------------------------------------------------------------- 1 | ifneq ($(KERNELRELEASE), ) 2 | obj-m := cgroup_css_links.o 3 | else 4 | KERNELDIR ?=/lib/modules/$(shell uname -r)/build 5 | PWD := $(shell pwd) 6 | all: 7 | $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 8 | clean: 9 | $(MAKE) -C $(KERNELDIR) M=$(PWD) clean 10 | load: 11 | @sudo dmesg -c > /dev/null 12 | @echo "#############[START] #################" 13 | @sudo insmod cgroup_css_links.ko 14 | @sudo dmesg 15 | unload: 16 | @sudo dmesg -c > /dev/null 17 | @sudo rmmod cgroup_css_links 18 | @sudo dmesg 19 | @echo "#############[ END ] #################" 20 | test: 21 | @make load 22 | @make unload 23 | endif 24 | -------------------------------------------------------------------------------- /h027_cgroup_css_links/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawolf/dive-in-kernel/663175ee02d5d976b289bdc64a23f70fefc4368f/h027_cgroup_css_links/README.md -------------------------------------------------------------------------------- /h027_cgroup_css_links/cgroup_css_links.c: -------------------------------------------------------------------------------- 1 | /*********************************************** 2 | * module : cgroup_css_links 3 | * 4 | * Wang Long (w@laoqinren.net) 5 | **********************************************/ 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | struct cg_cgroup_link { 16 | struct list_head cgrp_link_list; 17 | struct cgroup *cgrp; 18 | struct list_head cg_link_list; 19 | struct css_set *cg; 20 | }; 21 | 22 | static int __init cgroup_css_links_init(void) 23 | { 24 | // find the "rootnode" hierarchy, it is the "dummy hierarchy" 25 | struct cgroupfs_root *rootnode = (struct cgroupfs_root*)kallsyms_lookup_name("rootnode"); 26 | // the dummy hierarchy only have on cgroup. 27 | // All tasks in system are under this cgroup. 28 | struct cgroup *cgrp = &rootnode->top_cgroup; 29 | struct cg_cgroup_link *link; 30 | 31 | printk(KERN_ALERT "[Hello] cgroup_css_links \n"); 32 | 33 | list_for_each_entry(link, &cgrp->css_sets, cgrp_link_list) { 34 | struct css_set *cg = link->cg; 35 | struct task_struct *task; 36 | printk("css_set %p\n", cg); 37 | list_for_each_entry(task, &cg->tasks, cg_list) { 38 | printk("\ttask %d\n", task_pid_vnr(task)); 39 | } 40 | } 41 | 42 | return 0; 43 | } 44 | 45 | static void __exit cgroup_css_links_exit(void) 46 | { 47 | printk(KERN_ALERT "[Goodbye] cgroup_css_links\n"); 48 | } 49 | 50 | module_init(cgroup_css_links_init); 51 | module_exit(cgroup_css_links_exit); 52 | MODULE_LICENSE("GPL"); 53 | -------------------------------------------------------------------------------- /h028_debug_mem_cgroup_low/Makefile: -------------------------------------------------------------------------------- 1 | ifneq ($(KERNELRELEASE), ) 2 | obj-m := debug_mem_cgroup_low.o 3 | else 4 | KERNELDIR ?=/lib/modules/$(shell uname -r)/build 5 | PWD := $(shell pwd) 6 | all: 7 | $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 8 | clean: 9 | $(MAKE) -C $(KERNELDIR) M=$(PWD) clean 10 | load: 11 | @sudo dmesg -c > /dev/null 12 | @echo "#############[START] #################" 13 | @sudo insmod debug_mem_cgroup_low.ko 14 | @sudo dmesg 15 | unload: 16 | @sudo dmesg -c > /dev/null 17 | @sudo rmmod debug_mem_cgroup_low 18 | @sudo dmesg 19 | @echo "#############[ END ] #################" 20 | test: 21 | @make load 22 | @make unload 23 | endif 24 | -------------------------------------------------------------------------------- /h028_debug_mem_cgroup_low/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawolf/dive-in-kernel/663175ee02d5d976b289bdc64a23f70fefc4368f/h028_debug_mem_cgroup_low/README.md -------------------------------------------------------------------------------- /h028_debug_mem_cgroup_low/debug_mem_cgroup_low.c: -------------------------------------------------------------------------------- 1 | /*********************************************** 2 | * module : debug_mem_cgroup_low 3 | * 4 | * Wang Long (w@laoqinren.net) 5 | **********************************************/ 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | static bool j_mem_cgroup_low(struct mem_cgroup *root, struct mem_cgroup *memcg) 12 | { 13 | pr_info("jprobe: root = %p, memcg = %p\n", root, memcg); 14 | jprobe_return(); 15 | return 0; 16 | } 17 | 18 | static struct jprobe my_jprobe = { 19 | .entry = j_mem_cgroup_low, 20 | .kp = { 21 | .symbol_name = "mem_cgroup_low", 22 | }, 23 | }; 24 | 25 | static int __init debug_mem_cgroup_low_init(void) 26 | { 27 | int ret; 28 | 29 | ret = register_jprobe(&my_jprobe); 30 | if (ret < 0) { 31 | printk(KERN_INFO "register_jprobe failed, returned %d\n", ret); 32 | return -1; 33 | } 34 | 35 | printk(KERN_ALERT "[Hello] debug_mem_cgroup_low \n"); 36 | printk(KERN_INFO "Planted jprobe at %p, handler addr %p\n", 37 | my_jprobe.kp.addr, my_jprobe.entry); 38 | return 0; 39 | } 40 | 41 | static void __exit debug_mem_cgroup_low_exit(void) 42 | { 43 | unregister_jprobe(&my_jprobe); 44 | printk(KERN_ALERT "[Goodbye] debug_mem_cgroup_low\n"); 45 | } 46 | 47 | module_init(debug_mem_cgroup_low_init); 48 | module_exit(debug_mem_cgroup_low_exit); 49 | MODULE_LICENSE("GPL"); 50 | -------------------------------------------------------------------------------- /h029_hlist/Makefile: -------------------------------------------------------------------------------- 1 | ifneq ($(KERNELRELEASE), ) 2 | obj-m := hlist_test.o 3 | else 4 | KERNELDIR ?=/lib/modules/$(shell uname -r)/build 5 | PWD := $(shell pwd) 6 | all: 7 | $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 8 | clean: 9 | $(MAKE) -C $(KERNELDIR) M=$(PWD) clean 10 | load: 11 | @sudo dmesg -c > /dev/null 12 | @echo "#############[START] #################" 13 | @sudo insmod hlist_test.ko 14 | @sudo dmesg 15 | unload: 16 | @sudo dmesg -c > /dev/null 17 | @sudo rmmod hlist_test 18 | @sudo dmesg 19 | @echo "#############[ END ] #################" 20 | test: 21 | @make load 22 | @make unload 23 | endif 24 | -------------------------------------------------------------------------------- /h029_hlist/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawolf/dive-in-kernel/663175ee02d5d976b289bdc64a23f70fefc4368f/h029_hlist/README.md -------------------------------------------------------------------------------- /h029_hlist/hlist_test.c: -------------------------------------------------------------------------------- 1 | /*********************************************** 2 | * module : hlist_test 3 | * 4 | * Wang Long (w@laoqinren.net) 5 | **********************************************/ 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | struct node { 12 | int val; 13 | struct hlist_node list; 14 | }; 15 | 16 | static int __init hlist_test_init(void) 17 | { 18 | struct hlist_head head; 19 | struct node a, b, c, d, e; 20 | struct node *pos; 21 | struct hlist_node *p; 22 | 23 | printk(KERN_ALERT "[Hello] hlist_test \n"); 24 | 25 | INIT_HLIST_HEAD(&head); //初始化链表头 26 | a.val = 1; 27 | b.val = 2; 28 | c.val = 3; 29 | d.val = 4; 30 | e.val = 5; 31 | 32 | hlist_add_head(&a.list, &head); //添加节点 33 | hlist_add_head(&b.list, &head); 34 | hlist_add_head(&c.list, &head); 35 | 36 | printk(KERN_ALERT "-------------------------------------- \n"); 37 | //遍历链表,打印结果 方法1 38 | hlist_for_each_entry(pos, &head, list) { 39 | printk(KERN_ALERT "node.val = %d\n", pos->val); 40 | } // print 3 2 1 41 | 42 | printk(KERN_ALERT "-------------------------------------- \n"); 43 | // 遍历链表,打印结果 方法2 44 | hlist_for_each(p, &head) { 45 | pos = hlist_entry(p, struct node, list); 46 | printk(KERN_ALERT "node.val = %d\n", pos->val); 47 | } // print 3 2 1 48 | 49 | printk(KERN_ALERT "-------------------------------------- \n"); 50 | hlist_del_init(&b.list); // 删除中间节点 51 | hlist_for_each_entry(pos, &head, list) { 52 | printk(KERN_ALERT "node.val = %d\n", pos->val); 53 | } // print 3 1 54 | 55 | printk(KERN_ALERT "-------------------------------------- \n"); 56 | hlist_add_before(&d.list, &a.list); //在最后一个节点之前添加新节点 57 | hlist_for_each_entry(pos, &head, list) { 58 | printk(KERN_ALERT "node.val = %d\n", pos->val); 59 | } // print 3 4 1 60 | 61 | printk(KERN_ALERT "-------------------------------------- \n"); 62 | hlist_add_behind(&e.list, &a.list);//在最后一个节点之后添加新节点 63 | hlist_for_each_entry(pos, &head, list) { 64 | printk(KERN_ALERT "node.val = %d\n", pos->val); 65 | } // print 3 4 1 5 66 | 67 | return 0; 68 | } 69 | 70 | static void __exit hlist_test_exit(void) 71 | { 72 | printk(KERN_ALERT "[Goodbye] hlist_test\n"); 73 | } 74 | 75 | module_init(hlist_test_init); 76 | module_exit(hlist_test_exit); 77 | MODULE_LICENSE("GPL"); 78 | -------------------------------------------------------------------------------- /h030_radix_tree/Makefile: -------------------------------------------------------------------------------- 1 | ifneq ($(KERNELRELEASE), ) 2 | obj-m := radix_tree_example.o 3 | else 4 | KERNELDIR ?=/lib/modules/$(shell uname -r)/build 5 | PWD := $(shell pwd) 6 | all: 7 | $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 8 | clean: 9 | $(MAKE) -C $(KERNELDIR) M=$(PWD) clean 10 | load: 11 | @sudo dmesg -c > /dev/null 12 | @echo "#############[START] #################" 13 | @sudo insmod radix_tree_example.ko 14 | @sudo dmesg 15 | unload: 16 | @sudo dmesg -c > /dev/null 17 | @sudo rmmod radix_tree_example 18 | @sudo dmesg 19 | @echo "#############[ END ] #################" 20 | test: 21 | @make load 22 | @make unload 23 | endif 24 | -------------------------------------------------------------------------------- /h030_radix_tree/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawolf/dive-in-kernel/663175ee02d5d976b289bdc64a23f70fefc4368f/h030_radix_tree/README.md -------------------------------------------------------------------------------- /h030_radix_tree/radix_tree_example.c: -------------------------------------------------------------------------------- 1 | /*********************************************** 2 | * module : radix_tree_example 3 | * 4 | * Wang Long (w@laoqinren.net) 5 | **********************************************/ 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | //static RADIX_TREE(mytree, GFP_IOFS); 12 | static RADIX_TREE(mytree, GFP_KERNEL); 13 | 14 | static int __init radix_tree_example_init(void) 15 | { 16 | char a[40] = "hello, radix tree"; 17 | 18 | radix_tree_insert(&mytree, 0, (void *)a); 19 | radix_tree_insert(&mytree, 4, (void *)a); 20 | radix_tree_preload(GFP_IOFS); 21 | radix_tree_insert(&mytree, 131, (void *)a); 22 | radix_tree_insert(&mytree, 4096, (void *)a); 23 | radix_tree_preload_end(); 24 | radix_tree_lookup(&mytree, 1); 25 | printk(KERN_ALERT "[Hello] radix_tree_example \n"); 26 | return 0; 27 | } 28 | 29 | static void __exit radix_tree_example_exit(void) 30 | { 31 | radix_tree_delete(&mytree, 0); 32 | radix_tree_delete(&mytree, 4); 33 | radix_tree_delete(&mytree, 131); 34 | radix_tree_delete(&mytree, 4096); 35 | printk(KERN_ALERT "[Goodbye] radix_tree_example\n"); 36 | } 37 | 38 | module_init(radix_tree_example_init); 39 | module_exit(radix_tree_example_exit); 40 | MODULE_LICENSE("GPL"); 41 | -------------------------------------------------------------------------------- /h031_test_thread_info/Makefile: -------------------------------------------------------------------------------- 1 | ifneq ($(KERNELRELEASE), ) 2 | obj-m := test_thread_info.o 3 | else 4 | KERNELDIR ?=/lib/modules/$(shell uname -r)/build 5 | PWD := $(shell pwd) 6 | all: 7 | $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 8 | clean: 9 | $(MAKE) -C $(KERNELDIR) M=$(PWD) clean 10 | load: 11 | @sudo dmesg -c > /dev/null 12 | @echo "#############[START] #################" 13 | @sudo insmod test_thread_info.ko 14 | @sudo dmesg 15 | unload: 16 | @sudo dmesg -c > /dev/null 17 | @sudo rmmod test_thread_info 18 | @sudo dmesg 19 | @echo "#############[ END ] #################" 20 | test: 21 | @make load 22 | @make unload 23 | endif 24 | -------------------------------------------------------------------------------- /h031_test_thread_info/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawolf/dive-in-kernel/663175ee02d5d976b289bdc64a23f70fefc4368f/h031_test_thread_info/README.md -------------------------------------------------------------------------------- /h031_test_thread_info/test_thread_info.c: -------------------------------------------------------------------------------- 1 | /*********************************************** 2 | * module : test_thread_info 3 | * 4 | * Wang Long (w@laoqinren.net) 5 | **********************************************/ 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | static int __init test_thread_info_init(void) 12 | { 13 | struct thread_info *ti = NULL; 14 | struct task_struct *head = NULL; 15 | struct task_struct *tmp = NULL; 16 | 17 | printk(KERN_ALERT "[Hello] test_thread_info \n"); 18 | ti = (struct thread_info*)((unsigned long)&ti & ~(THREAD_SIZE - 1)); 19 | head = ti->task; 20 | tmp = head; 21 | 22 | printk("kernel stack size = %lx\n", THREAD_SIZE); 23 | do { 24 | printk("name is %s\n", tmp->comm); 25 | tmp = container_of(tmp->tasks.next, struct task_struct, tasks); 26 | }while(tmp != head); 27 | 28 | return 0; 29 | } 30 | 31 | static void __exit test_thread_info_exit(void) 32 | { 33 | printk(KERN_ALERT "[Goodbye] test_thread_info\n"); 34 | } 35 | 36 | module_init(test_thread_info_init); 37 | module_exit(test_thread_info_exit); 38 | MODULE_LICENSE("GPL"); 39 | -------------------------------------------------------------------------------- /h032_test_current/Makefile: -------------------------------------------------------------------------------- 1 | ifneq ($(KERNELRELEASE), ) 2 | obj-m := test_current.o 3 | else 4 | KERNELDIR ?=/lib/modules/$(shell uname -r)/build 5 | PWD := $(shell pwd) 6 | all: 7 | $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 8 | clean: 9 | $(MAKE) -C $(KERNELDIR) M=$(PWD) clean 10 | load: 11 | @sudo dmesg -c > /dev/null 12 | @echo "#############[START] #################" 13 | @sudo insmod test_current.ko 14 | @sudo dmesg 15 | unload: 16 | @sudo dmesg -c > /dev/null 17 | @sudo rmmod test_current 18 | @sudo dmesg 19 | @echo "#############[ END ] #################" 20 | test: 21 | @make load 22 | @make unload 23 | endif 24 | -------------------------------------------------------------------------------- /h032_test_current/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawolf/dive-in-kernel/663175ee02d5d976b289bdc64a23f70fefc4368f/h032_test_current/README.md -------------------------------------------------------------------------------- /h032_test_current/test_current.c: -------------------------------------------------------------------------------- 1 | /*********************************************** 2 | * module : test_current 3 | * 4 | * Wang Long (w@laoqinren.net) 5 | **********************************************/ 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | static int __init test_current_init(void) 12 | { 13 | printk(KERN_ERR "[err] test_current \n"); 14 | printk(KERN_WARNING "[warnning] test_current \n"); 15 | printk(KERN_NOTICE "[notice] test_current \n"); 16 | printk(KERN_ALERT "[alert] test_current \n"); 17 | printk(KERN_INFO "[info] test_current \n"); 18 | printk(KERN_DEBUG "[debug] test_current \n"); 19 | printk(KERN_ALERT "comm = %s \n", current->comm); 20 | return 0; 21 | } 22 | 23 | static void __exit test_current_exit(void) 24 | { 25 | printk(KERN_ALERT "[Goodbye] test_current\n"); 26 | } 27 | 28 | module_init(test_current_init); 29 | module_exit(test_current_exit); 30 | MODULE_LICENSE("GPL"); 31 | -------------------------------------------------------------------------------- /h033_mem_cgroup_iter/Makefile: -------------------------------------------------------------------------------- 1 | ifneq ($(KERNELRELEASE), ) 2 | obj-m := mem_cgroup_iter_test.o 3 | else 4 | KERNELDIR ?=/lib/modules/$(shell uname -r)/build 5 | PWD := $(shell pwd) 6 | all: 7 | $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 8 | clean: 9 | $(MAKE) -C $(KERNELDIR) M=$(PWD) clean 10 | load: 11 | @sudo dmesg -c > /dev/null 12 | @echo "#############[START] #################" 13 | @sudo insmod mem_cgroup_iter_test.ko 14 | @sudo dmesg 15 | unload: 16 | @sudo dmesg -c > /dev/null 17 | @sudo rmmod mem_cgroup_iter_test 18 | @sudo dmesg 19 | @echo "#############[ END ] #################" 20 | test: 21 | @make load 22 | @make unload 23 | endif 24 | -------------------------------------------------------------------------------- /h033_mem_cgroup_iter/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawolf/dive-in-kernel/663175ee02d5d976b289bdc64a23f70fefc4368f/h033_mem_cgroup_iter/README.md -------------------------------------------------------------------------------- /h033_mem_cgroup_iter/mem_cgroup_iter_test.c: -------------------------------------------------------------------------------- 1 | /*********************************************** 2 | * module : mem_cgroup_iter_test 3 | * 4 | * Wang Long (w@laoqinren.net) 5 | **********************************************/ 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | struct mem_cgroup { 14 | struct cgroup_subsys_state css; 15 | }; 16 | 17 | 18 | typedef struct mem_cgroup * (*mymem_cgroup_iter)(struct mem_cgroup *, 19 | struct mem_cgroup *, 20 | struct mem_cgroup_reclaim_cookie *); 21 | 22 | static mymem_cgroup_iter mem_cgroup_iter1; 23 | 24 | 25 | #define for_each_mem_cgroup(iter) \ 26 | for (iter = mem_cgroup_iter1(NULL, NULL, NULL); \ 27 | iter != NULL; \ 28 | iter = mem_cgroup_iter1(NULL, iter, NULL)) 29 | 30 | static int __init mem_cgroup_iter_test_init(void) 31 | { 32 | struct mem_cgroup *iter; 33 | static char memcg_name[PATH_MAX]; 34 | int ret; 35 | 36 | printk(KERN_ALERT "[Hello] mem_cgroup_iter_test \n"); 37 | 38 | mem_cgroup_iter1 = (mymem_cgroup_iter)kallsyms_lookup_name("mem_cgroup_iter"); 39 | for_each_mem_cgroup(iter) { 40 | rcu_read_lock(); 41 | ret = cgroup_path(iter->css.cgroup, memcg_name, PATH_MAX); 42 | if (!ret) 43 | printk(KERN_DEBUG "%s", memcg_name); 44 | rcu_read_unlock(); 45 | } 46 | return 0; 47 | } 48 | 49 | static void __exit mem_cgroup_iter_test_exit(void) 50 | { 51 | printk(KERN_ALERT "[Goodbye] mem_cgroup_iter_test\n"); 52 | } 53 | 54 | module_init(mem_cgroup_iter_test_init); 55 | module_exit(mem_cgroup_iter_test_exit); 56 | MODULE_LICENSE("GPL"); 57 | -------------------------------------------------------------------------------- /h034_my_crash/Makefile: -------------------------------------------------------------------------------- 1 | ifneq ($(KERNELRELEASE), ) 2 | obj-m := my_crash.o 3 | else 4 | KERNELDIR ?=/lib/modules/$(shell uname -r)/build 5 | PWD := $(shell pwd) 6 | all: 7 | $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 8 | clean: 9 | $(MAKE) -C $(KERNELDIR) M=$(PWD) clean 10 | load: 11 | @sudo dmesg -c > /dev/null 12 | @echo "#############[START] #################" 13 | @sudo insmod my_crash.ko 14 | @sudo dmesg 15 | unload: 16 | @sudo dmesg -c > /dev/null 17 | @sudo rmmod my_crash 18 | @sudo dmesg 19 | @echo "#############[ END ] #################" 20 | test: 21 | @make load 22 | @make unload 23 | endif 24 | -------------------------------------------------------------------------------- /h034_my_crash/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawolf/dive-in-kernel/663175ee02d5d976b289bdc64a23f70fefc4368f/h034_my_crash/README.md -------------------------------------------------------------------------------- /h034_my_crash/my_crash.c: -------------------------------------------------------------------------------- 1 | /*********************************************** 2 | * module : my_crash 3 | * 4 | * Wang Long (w@laoqinren.net) 5 | **********************************************/ 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | static unsigned long dram_size = 0; 17 | /* 18 | * These are the file operation functions that allow crash utility 19 | * access to physical memory. 20 | */ 21 | 22 | static loff_t 23 | crash_llseek(struct file * file, loff_t offset, int orig) 24 | { 25 | unsigned long newpos = -1; 26 | switch (orig) { 27 | case 0: 28 | newpos = offset; 29 | break; 30 | case 1: 31 | newpos = file->f_pos + offset; 32 | break; 33 | case 2: 34 | newpos = dram_size + offset; 35 | break; 36 | } 37 | 38 | if ((newpos < 0) || (newpos > dram_size)) 39 | return -EINVAL; 40 | 41 | file->f_pos = newpos; 42 | 43 | return newpos; 44 | } 45 | 46 | /* 47 | * Determine the page address for an address offset value, 48 | * get a virtual address for it, and copy it out. 49 | * Accesses must fit within a page. 50 | */ 51 | static ssize_t 52 | crash_read(struct file *file, char *buf, size_t count, loff_t *poff) 53 | { 54 | void *vaddr; 55 | struct page *page; 56 | u64 offset; 57 | ssize_t read; 58 | 59 | offset = *poff; 60 | if (offset >> PAGE_SHIFT != (offset+count-1) >> PAGE_SHIFT) 61 | return -EINVAL; 62 | 63 | vaddr = map_virtual(offset, &page); 64 | if (!vaddr) 65 | return -EFAULT; 66 | 67 | if (copy_to_user(buf, vaddr, count)) { 68 | unmap_virtual(page); 69 | return -EFAULT; 70 | } 71 | unmap_virtual(page); 72 | 73 | read = count; 74 | *poff += read; 75 | return read; 76 | } 77 | 78 | static int 79 | crash_open(struct inode * inode, struct file * filp) 80 | { 81 | return capable(CAP_SYS_RAWIO) ? 0 : -EPERM; 82 | } 83 | 84 | static struct file_operations crash_fops = { 85 | .owner = THIS_MODULE, 86 | .llseek = crash_llseek, 87 | .read = crash_read, 88 | .open = crash_open, 89 | }; 90 | 91 | static struct miscdevice crash_dev = { 92 | MISC_DYNAMIC_MINOR, 93 | "mycrash", 94 | &crash_fops 95 | }; 96 | 97 | 98 | static inline unsigned long get_total_physpages(void) 99 | { 100 | int nid; 101 | unsigned long phys_pages = 0; 102 | 103 | for_each_online_node(nid) 104 | phys_pages += node_spanned_pages(nid); 105 | 106 | return phys_pages; 107 | } 108 | 109 | 110 | static int __init my_crash_init(void) 111 | { 112 | int ret; 113 | 114 | dram_size = (unsigned long )get_total_physpages() << PAGE_SHIFT; 115 | 116 | printk(KERN_ALERT "[Hello] my_crash, ramtop = %08lx(%lu MB)\n", dram_size, dram_size >> 20); 117 | ret = misc_register(&crash_dev); 118 | if (ret) { 119 | printk(KERN_ERR 120 | "crash memory driver: cannot misc_register (MISC_DYNAMIC_MINOR)\n"); 121 | goto out; 122 | } 123 | 124 | ret = 0; 125 | out: 126 | return ret; 127 | 128 | return 0; 129 | } 130 | 131 | static void __exit my_crash_exit(void) 132 | { 133 | misc_deregister(&crash_dev); 134 | printk(KERN_ALERT "[Goodbye] my_crash\n"); 135 | } 136 | 137 | module_init(my_crash_init); 138 | module_exit(my_crash_exit); 139 | MODULE_LICENSE("GPL"); 140 | -------------------------------------------------------------------------------- /h035_dynamic_printk/Makefile: -------------------------------------------------------------------------------- 1 | ifneq ($(KERNELRELEASE), ) 2 | obj-m := dynamic_printk.o 3 | else 4 | KERNELDIR ?=/lib/modules/$(shell uname -r)/build 5 | PWD := $(shell pwd) 6 | all: 7 | $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 8 | clean: 9 | $(MAKE) -C $(KERNELDIR) M=$(PWD) clean 10 | load: 11 | @sudo dmesg -c > /dev/null 12 | @echo "#############[START] #################" 13 | @sudo insmod dynamic_printk.ko 14 | @sudo dmesg 15 | unload: 16 | @sudo dmesg -c > /dev/null 17 | @sudo rmmod dynamic_printk 18 | @sudo dmesg 19 | @echo "#############[ END ] #################" 20 | test: 21 | @make load 22 | @make unload 23 | endif 24 | -------------------------------------------------------------------------------- /h035_dynamic_printk/README.md: -------------------------------------------------------------------------------- 1 | ## 说明 2 | 3 | 本模块用来演示内核的dyndbg特性。 4 | -------------------------------------------------------------------------------- /h035_dynamic_printk/dynamic_printk.c: -------------------------------------------------------------------------------- 1 | /*********************************************** 2 | * module : dynamic_printk 3 | * 4 | * Wang Long (w@laoqinren.net) 5 | **********************************************/ 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | static struct task_struct *mythread; 13 | static int exit = 0; 14 | static int my_function(void *unused) 15 | { 16 | while(!exit) { 17 | pr_debug("just print this message\n"); 18 | msleep(2000); 19 | } 20 | 21 | return 0; 22 | } 23 | static int __init dynamic_printk_init(void) 24 | { 25 | printk(KERN_ALERT "[Hello] dynamic_printk \n"); 26 | 27 | // Create the kernel thread with name "MyThread" 28 | mythread = kthread_create(my_function, NULL, "MyThread"); 29 | if (mythread) { 30 | printk(KERN_ALERT "Thread created successfully\n"); 31 | wake_up_process(mythread); 32 | } else { 33 | printk(KERN_ALERT "Thread creation failed\n"); 34 | } 35 | 36 | return 0; 37 | } 38 | 39 | static void __exit dynamic_printk_exit(void) 40 | { 41 | exit = 1; 42 | msleep(3000); 43 | printk(KERN_ALERT "[Goodbye] dynamic_printk\n"); 44 | } 45 | 46 | module_init(dynamic_printk_init); 47 | module_exit(dynamic_printk_exit); 48 | MODULE_LICENSE("GPL"); 49 | -------------------------------------------------------------------------------- /h036_sched_bug/Makefile: -------------------------------------------------------------------------------- 1 | ifneq ($(KERNELRELEASE), ) 2 | obj-m := sched_bug.o 3 | else 4 | KERNELDIR ?=/lib/modules/$(shell uname -r)/build 5 | PWD := $(shell pwd) 6 | all: 7 | $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 8 | clean: 9 | $(MAKE) -C $(KERNELDIR) M=$(PWD) clean 10 | endif 11 | -------------------------------------------------------------------------------- /h036_sched_bug/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawolf/dive-in-kernel/663175ee02d5d976b289bdc64a23f70fefc4368f/h036_sched_bug/README.md -------------------------------------------------------------------------------- /h036_sched_bug/run.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -x 3 | a=0 4 | 5 | while [ $a -lt 2000 ]; 6 | do 7 | insmod ./sched_bug.ko 8 | rmmod ./sched_bug.ko 9 | a=$(($a+1)) 10 | done 11 | -------------------------------------------------------------------------------- /h036_sched_bug/sched_bug.c: -------------------------------------------------------------------------------- 1 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | static int can_attach_handler(struct kretprobe_instance *ri, 8 | struct pt_regs *regs) 9 | { 10 | return 0; 11 | } 12 | 13 | static int attach_handler(struct kretprobe_instance *ri, struct pt_regs *regs) 14 | { 15 | return 0; 16 | } 17 | 18 | static int enqueue_task_fair_handler(struct kretprobe_instance *ri, 19 | struct pt_regs *regs) 20 | { 21 | return 0; 22 | } 23 | 24 | static int dequeue_task_fair_handler(struct kretprobe_instance *ri, 25 | struct pt_regs *regs) 26 | { 27 | return 0; 28 | } 29 | 30 | static struct kretprobe rp1 = { 31 | .entry_handler = attach_handler, 32 | .kp.symbol_name = "cpuacct_attach" 33 | }; 34 | 35 | static struct kretprobe rp2 = { 36 | .entry_handler = can_attach_handler, 37 | .kp.symbol_name = "cpuacct_can_attach" 38 | }; 39 | 40 | static struct kretprobe rp3 = { 41 | .entry_handler = enqueue_task_fair_handler, 42 | .kp.symbol_name = "enqueue_task_fair" 43 | }; 44 | 45 | static struct kretprobe rp4 = { 46 | .entry_handler = dequeue_task_fair_handler, 47 | .kp.symbol_name = "dequeue_task_fair" 48 | }; 49 | 50 | static struct kretprobe *rps[] = {&rp1, &rp2, &rp3, &rp4}; 51 | 52 | static int __init sched_bug_init(void) 53 | { 54 | int ret; 55 | 56 | ret = register_kretprobes(rps, sizeof(rps) / sizeof(*rps)); 57 | if (ret < 0) { 58 | pr_info("register_kretprobes failed, returned %d\n", ret); 59 | return ret; 60 | } 61 | 62 | return 0; 63 | } 64 | 65 | static void __exit sched_bug_exit(void) 66 | { 67 | unregister_kretprobes(rps, sizeof(rps) / sizeof(*rps)); 68 | } 69 | 70 | module_init(sched_bug_init); 71 | module_exit(sched_bug_exit); 72 | MODULE_LICENSE("GPL"); 73 | -------------------------------------------------------------------------------- /h037_my_test_rcu/Makefile: -------------------------------------------------------------------------------- 1 | ifneq ($(KERNELRELEASE), ) 2 | obj-m := my_test_rcu.o 3 | else 4 | KERNELDIR ?=/lib/modules/$(shell uname -r)/build 5 | PWD := $(shell pwd) 6 | all: 7 | $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 8 | clean: 9 | $(MAKE) -C $(KERNELDIR) M=$(PWD) clean 10 | load: 11 | @sudo dmesg -c > /dev/null 12 | @echo "#############[START] #################" 13 | @sudo insmod my_test_rcu.ko 14 | @sudo dmesg 15 | unload: 16 | @sudo dmesg -c > /dev/null 17 | @sudo rmmod my_test_rcu 18 | @sudo dmesg 19 | @echo "#############[ END ] #################" 20 | test: 21 | @make load 22 | @make unload 23 | endif 24 | -------------------------------------------------------------------------------- /h037_my_test_rcu/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawolf/dive-in-kernel/663175ee02d5d976b289bdc64a23f70fefc4368f/h037_my_test_rcu/README.md -------------------------------------------------------------------------------- /h037_my_test_rcu/my_test_rcu.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | struct foo { 11 | int a; 12 | struct rcu_head rcu; 13 | }; 14 | 15 | static struct foo *g_ptr; 16 | static int myrcu_reader_thread1(void *data) //读者线程1 17 | { 18 | struct foo *p1 = NULL; 19 | 20 | while (1) { 21 | if(kthread_should_stop()) 22 | break; 23 | msleep(10); 24 | rcu_read_lock(); 25 | p1 = rcu_dereference(g_ptr); 26 | if (p1) 27 | printk("%s: read a=%d\n", __func__, p1->a); 28 | rcu_read_unlock(); 29 | } 30 | 31 | return 0; 32 | } 33 | 34 | static int myrcu_reader_thread2(void *data) //读者线程2 35 | { 36 | struct foo *p2 = NULL; 37 | 38 | while (1) { 39 | if(kthread_should_stop()) 40 | break; 41 | msleep(100); 42 | rcu_read_lock(); 43 | mdelay(1500); 44 | p2 = rcu_dereference(g_ptr); 45 | if (p2) 46 | printk("%s: read a=%d\n", __func__, p2->a); 47 | 48 | rcu_read_unlock(); 49 | } 50 | 51 | return 0; 52 | } 53 | 54 | static void myrcu_del(struct rcu_head *rh) 55 | { 56 | struct foo *p = container_of(rh, struct foo, rcu); 57 | printk("%s: a=%d\n", __func__, p->a); 58 | kfree(p); 59 | } 60 | 61 | static int myrcu_writer_thread(void *p) //写者线程 62 | { 63 | struct foo *old; 64 | struct foo *new_ptr; 65 | int value = (unsigned long)p; 66 | 67 | while (1) { 68 | if(kthread_should_stop()) 69 | break; 70 | msleep(100); 71 | new_ptr = kmalloc(sizeof (struct foo), GFP_KERNEL); 72 | old = g_ptr; 73 | printk("%s: write to new %d\n", __func__, value); 74 | *new_ptr = *old; 75 | new_ptr->a = value; 76 | rcu_assign_pointer(g_ptr, new_ptr); 77 | call_rcu(&old->rcu, myrcu_del); 78 | value++; 79 | } 80 | return 0; 81 | } 82 | 83 | static struct task_struct *reader_thread1; 84 | static struct task_struct *reader_thread2; 85 | static struct task_struct *writer_thread; 86 | 87 | static int __init my_test_init(void) 88 | { 89 | int value = 5; 90 | 91 | printk("figo: my module init\n"); 92 | g_ptr = kzalloc(sizeof (struct foo), GFP_KERNEL); 93 | 94 | reader_thread1 = kthread_run(myrcu_reader_thread1, NULL, "rcu_reader1"); 95 | reader_thread2 = kthread_run(myrcu_reader_thread2, NULL, "rcu_reader2"); 96 | writer_thread = kthread_run(myrcu_writer_thread, (void *)(unsigned long)value, "rcu_writer"); 97 | 98 | return 0; 99 | } 100 | static void __exit my_test_exit(void) 101 | { 102 | printk("goodbye\n"); 103 | kthread_stop(reader_thread1); 104 | kthread_stop(reader_thread2); 105 | kthread_stop(writer_thread); 106 | if (g_ptr) 107 | kfree(g_ptr); 108 | } 109 | MODULE_LICENSE("GPL"); 110 | module_init(my_test_init); 111 | module_exit(my_test_exit); 112 | -------------------------------------------------------------------------------- /h038_cn_test/Makefile: -------------------------------------------------------------------------------- 1 | ifneq ($(KERNELRELEASE), ) 2 | obj-m := cn_test.o 3 | else 4 | KERNELDIR ?=/lib/modules/$(shell uname -r)/build 5 | PWD := $(shell pwd) 6 | all: 7 | $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 8 | clean: 9 | $(MAKE) -C $(KERNELDIR) M=$(PWD) clean 10 | load: 11 | @sudo dmesg -c > /dev/null 12 | @echo "#############[START] #################" 13 | @sudo insmod cn_test.ko 14 | @sudo dmesg 15 | unload: 16 | @sudo dmesg -c > /dev/null 17 | @sudo rmmod cn_test 18 | @sudo dmesg 19 | @echo "#############[ END ] #################" 20 | test: 21 | @make load 22 | @make unload 23 | endif 24 | -------------------------------------------------------------------------------- /h038_cn_test/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawolf/dive-in-kernel/663175ee02d5d976b289bdc64a23f70fefc4368f/h038_cn_test/README.md -------------------------------------------------------------------------------- /h039_get_cwd_exe/Makefile: -------------------------------------------------------------------------------- 1 | ifneq ($(KERNELRELEASE), ) 2 | obj-m := get_cwd_exe.o 3 | else 4 | KERNELDIR ?=/lib/modules/$(shell uname -r)/build 5 | PWD := $(shell pwd) 6 | all: 7 | $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 8 | clean: 9 | $(MAKE) -C $(KERNELDIR) M=$(PWD) clean 10 | load: 11 | @sudo dmesg -c > /dev/null 12 | @echo "#############[START] #################" 13 | @sudo insmod get_cwd_exe.ko 14 | @sudo dmesg 15 | unload: 16 | @sudo dmesg -c > /dev/null 17 | @sudo rmmod get_cwd_exe 18 | @sudo dmesg 19 | @echo "#############[ END ] #################" 20 | test: 21 | @make load 22 | @make unload 23 | endif 24 | -------------------------------------------------------------------------------- /h039_get_cwd_exe/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawolf/dive-in-kernel/663175ee02d5d976b289bdc64a23f70fefc4368f/h039_get_cwd_exe/README.md -------------------------------------------------------------------------------- /h039_get_cwd_exe/get_cwd_exe.c: -------------------------------------------------------------------------------- 1 | /*********************************************** 2 | * module : get_cwd_exe 3 | * 4 | * Wang Long (w@laoqinren.net) 5 | **********************************************/ 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | 22 | static int pid = 1; 23 | module_param(pid, int, 1); 24 | 25 | static void cn_proc_get_fs_pwd(struct task_struct *task, struct path *path) 26 | { 27 | get_task_struct(task); 28 | task_lock(task); 29 | if (task->fs) 30 | get_fs_pwd(task->fs, path); 31 | task_unlock(task); 32 | put_task_struct(task); 33 | } 34 | 35 | static int get_process_cwd(struct task_struct *task, char *buf, int buflen) 36 | { 37 | struct path path; 38 | char *p, *pathname; 39 | 40 | /* We will allow 11 spaces for ' (deleted)' to be appended */ 41 | pathname = kmalloc(PATH_MAX+11, GFP_KERNEL); 42 | if (!pathname) 43 | return -ENOMEM; 44 | 45 | 46 | cn_proc_get_fs_pwd(task, &path); 47 | p = d_path(&path, pathname, PATH_MAX+11); 48 | if (IS_ERR(p)) 49 | return -ENAMETOOLONG; 50 | 51 | strncpy(buf, p, buflen); 52 | kfree(pathname); 53 | return 0; 54 | } 55 | 56 | static int get_process_exe(struct task_struct *task, char *buf, int buflen) 57 | { 58 | struct file *exe_file; 59 | char *p, *pathname; 60 | 61 | exe_file = get_task_exe_file(task); 62 | if (!exe_file) 63 | return 0; 64 | 65 | /* We will allow 11 spaces for ' (deleted)' to be appended */ 66 | pathname = kmalloc(PATH_MAX+11, GFP_KERNEL); 67 | if (!pathname) 68 | return -ENOMEM; 69 | 70 | p = d_path(&exe_file->f_path, pathname, PATH_MAX+11); 71 | if (IS_ERR(p)) 72 | return -ENAMETOOLONG; 73 | 74 | strncpy(buf, p, buflen); 75 | kfree(pathname); 76 | return 0; 77 | } 78 | 79 | static int __init get_cwd_exe_init(void) 80 | { 81 | pid_t p = (pid_t)pid; 82 | char cwd[64]; 83 | char path[64]; 84 | int ret = 0; 85 | struct task_struct *task = get_pid_task(find_get_pid(p), PIDTYPE_PID); 86 | 87 | printk(KERN_ALERT "[Hello] get_cwd_exe \n"); 88 | ret = get_process_cwd(task, cwd, sizeof(cwd)); 89 | if (ret != 0) { 90 | printk(KERN_ALERT "ERROR: get_process_cwd: %d\n", ret); 91 | }else { 92 | printk(KERN_ALERT "get_process_cwd: %s\n", cwd); 93 | } 94 | 95 | ret = get_process_exe(task, path, sizeof(path)); 96 | if (ret != 0) { 97 | printk(KERN_ALERT "ERROR: get_process_path: %d\n", ret); 98 | }else { 99 | printk(KERN_ALERT "get_process_exe: %s\n", path); 100 | } 101 | return 0; 102 | } 103 | 104 | static void __exit get_cwd_exe_exit(void) 105 | { 106 | printk(KERN_ALERT "[Goodbye] get_cwd_exe\n"); 107 | } 108 | 109 | module_init(get_cwd_exe_init); 110 | module_exit(get_cwd_exe_exit); 111 | MODULE_LICENSE("GPL"); 112 | 113 | -------------------------------------------------------------------------------- /h040_nspid/Makefile: -------------------------------------------------------------------------------- 1 | ifneq ($(KERNELRELEASE), ) 2 | obj-m := nspid.o 3 | else 4 | KERNELDIR ?=/lib/modules/$(shell uname -r)/build 5 | PWD := $(shell pwd) 6 | all: 7 | $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 8 | clean: 9 | $(MAKE) -C $(KERNELDIR) M=$(PWD) clean 10 | load: 11 | @sudo dmesg -c > /dev/null 12 | @echo "#############[START] #################" 13 | @sudo insmod nspid.ko 14 | @sudo dmesg 15 | unload: 16 | @sudo dmesg -c > /dev/null 17 | @sudo rmmod nspid 18 | @sudo dmesg 19 | @echo "#############[ END ] #################" 20 | test: 21 | @make load 22 | @make unload 23 | endif 24 | -------------------------------------------------------------------------------- /h040_nspid/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawolf/dive-in-kernel/663175ee02d5d976b289bdc64a23f70fefc4368f/h040_nspid/README.md -------------------------------------------------------------------------------- /h040_nspid/nspid.c: -------------------------------------------------------------------------------- 1 | /*********************************************** 2 | * module : nspid 3 | * 4 | * Wang Long (w@laoqinren.net) 5 | **********************************************/ 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | static int pid = 1; 22 | module_param(pid, int, 1); 23 | 24 | static int __init nspid_init(void) 25 | { 26 | pid_t p = (pid_t)pid; 27 | struct pid_namespace *ns; 28 | struct task_struct *task = get_pid_task(find_get_pid(p), PIDTYPE_PID); 29 | struct task_struct *parent; 30 | 31 | pid_t pid, tid, ppid, ptid; 32 | 33 | printk(KERN_ALERT "[Hello] nspid \n"); 34 | ns = task_active_pid_ns(task); 35 | 36 | pid = task_tgid_nr_ns(task, ns); 37 | tid = task_pid_nr_ns(task, ns); 38 | 39 | rcu_read_lock(); 40 | parent = rcu_dereference(task->real_parent); 41 | ppid = task_tgid_nr_ns(parent, ns); 42 | ptid = task_pid_nr_ns(parent, ns); 43 | rcu_read_unlock(); 44 | 45 | 46 | printk(KERN_ALERT "PID = %d\n", pid); 47 | printk(KERN_ALERT "TID = %d\n", tid); 48 | printk(KERN_ALERT "PPID = %d\n", ppid); 49 | printk(KERN_ALERT "PTID = %d\n", ptid); 50 | 51 | return 0; 52 | } 53 | 54 | static void __exit nspid_exit(void) 55 | { 56 | printk(KERN_ALERT "[Goodbye] nspid\n"); 57 | } 58 | 59 | module_init(nspid_init); 60 | module_exit(nspid_exit); 61 | MODULE_LICENSE("GPL"); 62 | 63 | -------------------------------------------------------------------------------- /h041_show_max_fds/Makefile: -------------------------------------------------------------------------------- 1 | ifneq ($(KERNELRELEASE), ) 2 | obj-m := show_max_fds.o 3 | else 4 | KERNELDIR ?=/lib/modules/$(shell uname -r)/build 5 | PWD := $(shell pwd) 6 | all: 7 | $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 8 | clean: 9 | $(MAKE) -C $(KERNELDIR) M=$(PWD) clean 10 | load: 11 | @sudo dmesg -c > /dev/null 12 | @echo "#############[START] #################" 13 | @sudo insmod show_max_fds.ko 14 | @sudo dmesg 15 | unload: 16 | @sudo dmesg -c > /dev/null 17 | @sudo rmmod show_max_fds 18 | @sudo dmesg 19 | @echo "#############[ END ] #################" 20 | test: 21 | @make load 22 | @make unload 23 | endif 24 | -------------------------------------------------------------------------------- /h041_show_max_fds/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawolf/dive-in-kernel/663175ee02d5d976b289bdc64a23f70fefc4368f/h041_show_max_fds/README.md -------------------------------------------------------------------------------- /h041_show_max_fds/show_max_fds.c: -------------------------------------------------------------------------------- 1 | /*********************************************** 2 | * module : show_max_fds 3 | * 4 | * Wang Long (w@laoqinren.net) 5 | **********************************************/ 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | static int __init show_max_fds_init(void) 16 | { 17 | struct task_struct *pos; 18 | struct task_struct *leader; 19 | struct list_head *current_head; 20 | int count = 0; 21 | unsigned long fds = 0; 22 | struct files_struct *files = NULL; 23 | 24 | printk(KERN_ALERT "[Hello] show_max_fds \n"); 25 | current_head = &(current->tasks); 26 | list_for_each_entry(pos, current_head, tasks) 27 | { 28 | rcu_read_lock(); 29 | leader = pos; 30 | do { 31 | count++; 32 | spin_lock(&pos->alloc_lock); 33 | files = pos->files; 34 | if (files) { 35 | struct fdtable *fdt = files_fdtable(files); 36 | printk(KERN_INFO "[process %d]: %s's max_fds = %d\n", 37 | count, pos->comm, fdt->max_fds); 38 | fds += fdt->max_fds; 39 | } 40 | spin_unlock(&pos->alloc_lock); 41 | } while_each_thread(leader, pos); 42 | rcu_read_unlock(); 43 | } 44 | printk(KERN_INFO "The number of process is %d\n", count); 45 | printk(KERN_INFO "The number of total fds is %ld\n", fds); 46 | return 0; 47 | } 48 | 49 | static void __exit show_max_fds_exit(void) 50 | { 51 | printk(KERN_ALERT "[Goodbye] show_max_fds\n"); 52 | } 53 | 54 | module_init(show_max_fds_init); 55 | module_exit(show_max_fds_exit); 56 | MODULE_LICENSE("GPL"); 57 | -------------------------------------------------------------------------------- /h042_check_list/Makefile: -------------------------------------------------------------------------------- 1 | ifneq ($(KERNELRELEASE), ) 2 | obj-m := check_list.o 3 | else 4 | KERNELDIR ?=/lib/modules/$(shell uname -r)/build 5 | PWD := $(shell pwd) 6 | all: 7 | $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 8 | clean: 9 | $(MAKE) -C $(KERNELDIR) M=$(PWD) clean 10 | load: 11 | @sudo dmesg -c > /dev/null 12 | @echo "#############[START] #################" 13 | @sudo insmod check_list.ko 14 | @sudo dmesg 15 | unload: 16 | @sudo dmesg -c > /dev/null 17 | @sudo rmmod check_list 18 | @sudo dmesg 19 | @echo "#############[ END ] #################" 20 | test: 21 | @make load 22 | @make unload 23 | endif 24 | -------------------------------------------------------------------------------- /h042_check_list/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawolf/dive-in-kernel/663175ee02d5d976b289bdc64a23f70fefc4368f/h042_check_list/README.md -------------------------------------------------------------------------------- /h042_check_list/check_list.c: -------------------------------------------------------------------------------- 1 | /*********************************************** 2 | * module : check_list 3 | * 4 | * Wang Long (w@laoqinren.net) 5 | **********************************************/ 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | 12 | LIST_HEAD(bdi_list); 13 | 14 | struct test { 15 | struct list_head bdi_list; 16 | int flags; 17 | }; 18 | 19 | static int __init check_list_init(void) 20 | { 21 | struct test test1, test2; 22 | 23 | printk(KERN_ALERT "[Hello] check_list \n"); 24 | 25 | printk(KERN_ALERT "&bdi_list = %px", &bdi_list); 26 | printk(KERN_ALERT "bdi_list.next = %px", bdi_list.next); 27 | printk(KERN_ALERT "bdi_list.prev = %px", bdi_list.prev); 28 | list_add(&test1.bdi_list, &bdi_list); 29 | 30 | printk(KERN_ALERT "add test1XXXXXXXXXXXXXXXXXX \n"); 31 | printk(KERN_ALERT "&bdi_list = %px", &bdi_list); 32 | printk(KERN_ALERT "bdi_list.next = %px", bdi_list.next); 33 | printk(KERN_ALERT "bdi_list.prev = %px", bdi_list.prev); 34 | 35 | list_add(&test2.bdi_list, &bdi_list); 36 | printk(KERN_ALERT "add test2 XXXXXXXXXXXXXXXXXX \n"); 37 | printk(KERN_ALERT "&bdi_list = %px", &bdi_list); 38 | printk(KERN_ALERT "bdi_list.next = %px", bdi_list.next); 39 | printk(KERN_ALERT "bdi_list.prev = %px", bdi_list.prev); 40 | 41 | list_del(&test1.bdi_list); 42 | printk(KERN_ALERT "del test1XXXXXXXXXXXXXXXXXX \n"); 43 | printk(KERN_ALERT "&bdi_list = %px", &bdi_list); 44 | printk(KERN_ALERT "bdi_list.next = %px", bdi_list.next); 45 | printk(KERN_ALERT "bdi_list.prev = %px", bdi_list.prev); 46 | 47 | list_del(&test2.bdi_list); 48 | printk(KERN_ALERT "del test2XXXXXXXXXXXXXXXXXX \n"); 49 | printk(KERN_ALERT "&bdi_list = %px", &bdi_list); 50 | printk(KERN_ALERT "bdi_list.next = %px", bdi_list.next); 51 | printk(KERN_ALERT "bdi_list.prev = %px", bdi_list.prev); 52 | return 0; 53 | } 54 | 55 | static void __exit check_list_exit(void) 56 | { 57 | printk(KERN_ALERT "[Goodbye] check_list\n"); 58 | } 59 | 60 | module_init(check_list_init); 61 | module_exit(check_list_exit); 62 | MODULE_LICENSE("GPL"); 63 | -------------------------------------------------------------------------------- /h043_hack_meminfo/Makefile: -------------------------------------------------------------------------------- 1 | ifneq ($(KERNELRELEASE), ) 2 | obj-m := hack_meminfo.o 3 | else 4 | KERNELDIR ?=/lib/modules/$(shell uname -r)/build 5 | PWD := $(shell pwd) 6 | all: 7 | $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 8 | clean: 9 | $(MAKE) -C $(KERNELDIR) M=$(PWD) clean 10 | load: 11 | @sudo dmesg -c > /dev/null 12 | @echo "#############[START] #################" 13 | @sudo insmod hack_meminfo.ko 14 | @sudo dmesg 15 | unload: 16 | @sudo dmesg -c > /dev/null 17 | @sudo rmmod hack_meminfo 18 | @sudo dmesg 19 | @echo "#############[ END ] #################" 20 | test: 21 | @make load 22 | @make unload 23 | endif 24 | -------------------------------------------------------------------------------- /h043_hack_meminfo/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawolf/dive-in-kernel/663175ee02d5d976b289bdc64a23f70fefc4368f/h043_hack_meminfo/README.md -------------------------------------------------------------------------------- /h044_test_xarray/Makefile: -------------------------------------------------------------------------------- 1 | ifneq ($(KERNELRELEASE), ) 2 | obj-m := test_xarray.o 3 | else 4 | KERNELDIR ?=/lib/modules/$(shell uname -r)/build 5 | PWD := $(shell pwd) 6 | all: 7 | $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 8 | clean: 9 | $(MAKE) -C $(KERNELDIR) M=$(PWD) clean 10 | load: 11 | @sudo dmesg -c > /dev/null 12 | @echo "#############[START] #################" 13 | @sudo insmod test_xarray.ko 14 | @sudo dmesg 15 | unload: 16 | @sudo dmesg -c > /dev/null 17 | @sudo rmmod test_xarray 18 | @sudo dmesg 19 | @echo "#############[ END ] #################" 20 | test: 21 | @make load 22 | @make unload 23 | endif 24 | -------------------------------------------------------------------------------- /h044_test_xarray/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawolf/dive-in-kernel/663175ee02d5d976b289bdc64a23f70fefc4368f/h044_test_xarray/README.md -------------------------------------------------------------------------------- /h045_test_xarray/Makefile: -------------------------------------------------------------------------------- 1 | ifneq ($(KERNELRELEASE), ) 2 | obj-m := test_xarray.o 3 | else 4 | KERNELDIR ?=/lib/modules/$(shell uname -r)/build 5 | PWD := $(shell pwd) 6 | all: 7 | $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 8 | clean: 9 | $(MAKE) -C $(KERNELDIR) M=$(PWD) clean 10 | load: 11 | @sudo dmesg -c > /dev/null 12 | @echo "#############[START] #################" 13 | @sudo insmod test_xarray.ko 14 | @sudo dmesg 15 | unload: 16 | @sudo dmesg -c > /dev/null 17 | @sudo rmmod test_xarray 18 | @sudo dmesg 19 | @echo "#############[ END ] #################" 20 | test: 21 | @make load 22 | @make unload 23 | endif 24 | -------------------------------------------------------------------------------- /h045_test_xarray/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawolf/dive-in-kernel/663175ee02d5d976b289bdc64a23f70fefc4368f/h045_test_xarray/README.md -------------------------------------------------------------------------------- /h046_test_jiffies/Makefile: -------------------------------------------------------------------------------- 1 | ifneq ($(KERNELRELEASE), ) 2 | obj-m := test_jiffies.o 3 | else 4 | KERNELDIR ?=/lib/modules/$(shell uname -r)/build 5 | PWD := $(shell pwd) 6 | all: 7 | $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 8 | clean: 9 | $(MAKE) -C $(KERNELDIR) M=$(PWD) clean 10 | load: 11 | @sudo dmesg -c > /dev/null 12 | @echo "#############[START] #################" 13 | @sudo insmod test_jiffies.ko 14 | @sudo dmesg 15 | unload: 16 | @sudo dmesg -c > /dev/null 17 | @sudo rmmod test_jiffies 18 | @sudo dmesg 19 | @echo "#############[ END ] #################" 20 | test: 21 | @make load 22 | @make unload 23 | endif 24 | -------------------------------------------------------------------------------- /h046_test_jiffies/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawolf/dive-in-kernel/663175ee02d5d976b289bdc64a23f70fefc4368f/h046_test_jiffies/README.md -------------------------------------------------------------------------------- /h046_test_jiffies/test_jiffies.c: -------------------------------------------------------------------------------- 1 | /*********************************************** 2 | * module : test_jiffies 3 | * 4 | * Wang Long (w@laoqinren.net) 5 | **********************************************/ 6 | #include 7 | #include 8 | #include 9 | 10 | static int __init test_jiffies_init(void) 11 | { 12 | printk(KERN_ALERT "[Hello] test_jiffies \n"); 13 | 14 | printk(KERN_ALERT "msecs_to_jiffies(10) = %ld\n", msecs_to_jiffies(10)); 15 | return 0; 16 | } 17 | 18 | static void __exit test_jiffies_exit(void) 19 | { 20 | printk(KERN_ALERT "[Goodbye] test_jiffies\n"); 21 | } 22 | 23 | module_init(test_jiffies_init); 24 | module_exit(test_jiffies_exit); 25 | MODULE_LICENSE("GPL"); 26 | -------------------------------------------------------------------------------- /h047_test_timer/Makefile: -------------------------------------------------------------------------------- 1 | ifneq ($(KERNELRELEASE), ) 2 | obj-m := test_timer.o 3 | else 4 | KERNELDIR ?=/lib/modules/$(shell uname -r)/build 5 | PWD := $(shell pwd) 6 | all: 7 | $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 8 | clean: 9 | $(MAKE) -C $(KERNELDIR) M=$(PWD) clean 10 | load: 11 | @sudo dmesg -c > /dev/null 12 | @echo "#############[START] #################" 13 | @sudo insmod test_timer.ko 14 | @sudo dmesg 15 | unload: 16 | @sudo dmesg -c > /dev/null 17 | @sudo rmmod test_timer 18 | @sudo dmesg 19 | @echo "#############[ END ] #################" 20 | test: 21 | @make load 22 | @make unload 23 | endif 24 | -------------------------------------------------------------------------------- /h047_test_timer/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawolf/dive-in-kernel/663175ee02d5d976b289bdc64a23f70fefc4368f/h047_test_timer/README.md -------------------------------------------------------------------------------- /h047_test_timer/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(){ 4 | int i = 0; 5 | int j = 0; 6 | int n = 0; 7 | 8 | for(i = 0; i< 10000; i++) { 9 | for(j = 0; j < 100000; j++) 10 | n = i*j; 11 | } 12 | return 0; 13 | } 14 | -------------------------------------------------------------------------------- /h048_print_mem_cgroup/Makefile: -------------------------------------------------------------------------------- 1 | ifneq ($(KERNELRELEASE), ) 2 | obj-m := print_mem_cgroup_stat.o 3 | else 4 | KERNELDIR ?=/lib/modules/$(shell uname -r)/build 5 | PWD := $(shell pwd) 6 | all: 7 | $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 8 | clean: 9 | $(MAKE) -C $(KERNELDIR) M=$(PWD) clean 10 | load: 11 | @sudo dmesg -c > /dev/null 12 | @echo "#############[START] #################" 13 | @sudo insmod print_mem_cgroup_stat.ko 14 | @sudo dmesg 15 | unload: 16 | @sudo dmesg -c > /dev/null 17 | @sudo rmmod print_mem_cgroup_stat 18 | @sudo dmesg 19 | @echo "#############[ END ] #################" 20 | test: 21 | @make load 22 | @make unload 23 | endif 24 | -------------------------------------------------------------------------------- /h048_print_mem_cgroup/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawolf/dive-in-kernel/663175ee02d5d976b289bdc64a23f70fefc4368f/h048_print_mem_cgroup/README.md -------------------------------------------------------------------------------- /h048_print_mem_cgroup/print_mem_cgroup_stat.c: -------------------------------------------------------------------------------- 1 | /*********************************************** 2 | * module : print_mem_cgroup_stat 3 | * 4 | * Wang Long (w@laoqinren.net) 5 | **********************************************/ 6 | #include 7 | #include 8 | #include 9 | #include 10 | static int pid = 1; 11 | module_param(pid, int, 0400); 12 | MODULE_PARM_DESC(pid, "The pid to print"); 13 | 14 | static int __init print_mem_cgroup_stat_init(void) 15 | { 16 | pid_t p = (pid_t)pid; 17 | struct task_struct *task; 18 | struct mem_cgroup *memcg = NULL; 19 | long val = 0; 20 | int cpu; 21 | 22 | printk(KERN_ALERT "[Hello] print_mem_cgroup_stat \n"); 23 | task = get_pid_task(find_get_pid(p), PIDTYPE_PID); 24 | //memcg = mem_cgroup_from_task(task); 25 | memcg = mem_cgroup_from_css(task_subsys_state(task, mem_cgroup_subsys_id)); 26 | 27 | for_each_online_cpu(cpu) { 28 | val = per_cpu(memcg->stat->count[MEM_CGROUP_STAT_WRITEBACK], cpu); 29 | printk(KERN_ALERT "cpu %d, writeback count = %ld", cpu, val); 30 | } 31 | return 0; 32 | } 33 | 34 | static void __exit print_mem_cgroup_stat_exit(void) 35 | { 36 | printk(KERN_ALERT "[Goodbye] print_mem_cgroup_stat\n"); 37 | } 38 | 39 | module_init(print_mem_cgroup_stat_init); 40 | module_exit(print_mem_cgroup_stat_exit); 41 | MODULE_LICENSE("GPL"); 42 | -------------------------------------------------------------------------------- /h049_test_hlist_head/Makefile: -------------------------------------------------------------------------------- 1 | ifneq ($(KERNELRELEASE), ) 2 | obj-m := test_hlist_head.o 3 | else 4 | KERNELDIR ?=/lib/modules/$(shell uname -r)/build 5 | PWD := $(shell pwd) 6 | all: 7 | $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 8 | clean: 9 | $(MAKE) -C $(KERNELDIR) M=$(PWD) clean 10 | load: 11 | @sudo dmesg -c > /dev/null 12 | @echo "#############[START] #################" 13 | @sudo insmod test_hlist_head.ko 14 | @sudo dmesg 15 | unload: 16 | @sudo dmesg -c > /dev/null 17 | @sudo rmmod test_hlist_head 18 | @sudo dmesg 19 | @echo "#############[ END ] #################" 20 | test: 21 | @make load 22 | @make unload 23 | endif 24 | -------------------------------------------------------------------------------- /h049_test_hlist_head/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawolf/dive-in-kernel/663175ee02d5d976b289bdc64a23f70fefc4368f/h049_test_hlist_head/README.md -------------------------------------------------------------------------------- /h050_drop_caches/Makefile: -------------------------------------------------------------------------------- 1 | 2 | EXTRA_CFLAGS := -DMODULE 3 | ARCH := $(shell uname -i) 4 | UNAME := $(shell uname -r) 5 | 6 | ifeq ($(KERNEL_BUILD_PATH),) 7 | KERNEL_BUILD_PATH := /lib/modules/$(UNAME)/build 8 | endif 9 | 10 | ifneq ($(findstring mt20190308.130,$(KERNEL_BUILD_PATH)),) 11 | EXTRA_CFLAGS += -DMTOS_130 12 | endif 13 | 14 | ifneq ($(findstring mt20191225.323,$(KERNEL_BUILD_PATH)),) 15 | EXTRA_CFLAGS += -DMTOS_323 16 | endif 17 | 18 | ifneq ($(findstring mt20200626.413,$(KERNEL_BUILD_PATH)),) 19 | EXTRA_CFLAGS += -DMTOS_413 20 | endif 21 | 22 | ifneq ($(KERNELRELEASE), ) 23 | obj-m := drop_caches.o 24 | else 25 | KERNELDIR ?=/lib/modules/$(shell uname -r)/build 26 | PWD := $(shell pwd) 27 | all: 28 | $(MAKE) CFLAGS_MODULE="$(EXTRA_CFLAGS)" -C $(KERNELDIR) M=$(PWD) modules 29 | clean: 30 | $(MAKE) CFLAGS_MODULE="$(EXTRA_CFLAGS)" -C $(KERNELDIR) M=$(PWD) clean 31 | load: 32 | @sudo dmesg -c > /dev/null 33 | @echo "#############[START] #################" 34 | @sudo insmod drop_caches.ko 35 | @sudo dmesg 36 | unload: 37 | @sudo dmesg -c > /dev/null 38 | @sudo rmmod drop_caches 39 | @sudo dmesg 40 | @echo "#############[ END ] #################" 41 | test: 42 | @make load 43 | @make unload 44 | endif 45 | -------------------------------------------------------------------------------- /h050_drop_caches/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawolf/dive-in-kernel/663175ee02d5d976b289bdc64a23f70fefc4368f/h050_drop_caches/README.md -------------------------------------------------------------------------------- /h051_test_irq_cpu_on_off/Makefile: -------------------------------------------------------------------------------- 1 | ifneq ($(KERNELRELEASE), ) 2 | obj-m := test_irq.o 3 | else 4 | KERNELDIR ?=/lib/modules/$(shell uname -r)/build 5 | PWD := $(shell pwd) 6 | all: 7 | $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 8 | clean: 9 | $(MAKE) -C $(KERNELDIR) M=$(PWD) clean 10 | load: 11 | @sudo dmesg -c > /dev/null 12 | @echo "#############[START] #################" 13 | @sudo insmod test_irq.ko 14 | @sudo dmesg 15 | unload: 16 | @sudo dmesg -c > /dev/null 17 | @sudo rmmod test_irq 18 | @sudo dmesg 19 | @echo "#############[ END ] #################" 20 | test: 21 | @make load 22 | @make unload 23 | endif 24 | -------------------------------------------------------------------------------- /h051_test_irq_cpu_on_off/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawolf/dive-in-kernel/663175ee02d5d976b289bdc64a23f70fefc4368f/h051_test_irq_cpu_on_off/README.md -------------------------------------------------------------------------------- /h051_test_irq_cpu_on_off/a.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | a=0 4 | while [ $a -lt 20 ]; 5 | do 6 | echo 0 > /sys/devices/system/cpu/cpu0/online 7 | echo 1 > /sys/devices/system/cpu/cpu0/online 8 | echo 0 > /sys/devices/system/cpu/cpu2/online 9 | echo 1 > /sys/devices/system/cpu/cpu2/online 10 | sleep 1 11 | done 12 | -------------------------------------------------------------------------------- /h051_test_irq_cpu_on_off/test_irq.c: -------------------------------------------------------------------------------- 1 | /*********************************************** 2 | * module : test_irq 3 | * 4 | * Wang Long (w@laoqinren.net) 5 | **********************************************/ 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | struct timer_info { 14 | int cpu; 15 | int count; 16 | struct hrtimer timer; 17 | }; 18 | 19 | struct timer_info timer_infos[NR_CPUS]; 20 | 21 | 22 | static inline ktime_t __ms_to_ktime(u64 ms) 23 | { 24 | return ms * NSEC_PER_MSEC; 25 | } 26 | 27 | static enum hrtimer_restart hrtimer_handler(struct hrtimer *hrtimer) 28 | { 29 | enum hrtimer_restart ret = HRTIMER_RESTART; 30 | int cpu = smp_processor_id(); 31 | struct timer_info *t = container_of(hrtimer, struct timer_info, timer); 32 | 33 | if (in_irq()) { 34 | t->count++; 35 | if (t->count % 500 == 0) { 36 | printk(KERN_ALERT "[in irq], timer's cpu = %d, actual cpu = %d, hrtimer = %px, hrtimer[%d] = %px \n", t->cpu, cpu, hrtimer, cpu, &timer_infos[cpu].timer); 37 | } 38 | } else { 39 | printk(KERN_ALERT "[NOT in irq], timer's cpu = %d, actual cpu = %d, hrtimer = %px, hrtimer[%d] = %px \n", t->cpu, cpu, hrtimer, cpu, &timer_infos[cpu].timer); 40 | } 41 | 42 | hrtimer_forward_now(hrtimer, __ms_to_ktime(10)); 43 | 44 | return ret; 45 | } 46 | 47 | static void start_timer(void *info) 48 | { 49 | int cpu = smp_processor_id(); 50 | struct hrtimer *timer = &timer_infos[cpu].timer; 51 | 52 | 53 | timer_infos[cpu].cpu = cpu; 54 | 55 | /* start per-cpu hrtimer */ 56 | hrtimer_init(timer, CLOCK_MONOTONIC, HRTIMER_MODE_PINNED); 57 | timer->function = hrtimer_handler; 58 | hrtimer_start_range_ns(timer, 59 | __ms_to_ktime(10), 60 | 0, 61 | HRTIMER_MODE_REL_PINNED /*HRTIMER_MODE_PINNED*/); 62 | 63 | printk(KERN_ALERT "hrtimer[%d] = %px\n", cpu, timer); 64 | } 65 | 66 | static enum cpuhp_state cpuhp_ret; 67 | 68 | static int test_irq_online(unsigned int cpu) 69 | { 70 | 71 | smp_call_function_single(cpu, start_timer, NULL, 1); 72 | 73 | return 0; 74 | 75 | } 76 | 77 | static int test_irq_offline(unsigned int cpu) 78 | { 79 | 80 | hrtimer_cancel(&timer_infos[cpu].timer); 81 | 82 | return 0; 83 | } 84 | 85 | static int __init test_irq_init(void) 86 | { 87 | printk(KERN_ALERT "[Hello] test_irq \n"); 88 | 89 | on_each_cpu(start_timer, NULL, 1); 90 | 91 | cpuhp_ret = cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN, 92 | "test_irq:on_off_line", test_irq_online, 93 | test_irq_offline); 94 | WARN_ON(cpuhp_ret < 0); 95 | return 0; 96 | } 97 | 98 | static void __exit test_irq_exit(void) 99 | { 100 | int cpu; 101 | printk(KERN_ALERT "[Goodbye] test_irq\n"); 102 | 103 | for_each_possible_cpu(cpu) 104 | { 105 | hrtimer_cancel(&timer_infos[cpu].timer); 106 | } 107 | 108 | cpuhp_remove_state_nocalls(cpuhp_ret); 109 | } 110 | 111 | module_init(test_irq_init); 112 | module_exit(test_irq_exit); 113 | MODULE_LICENSE("GPL"); 114 | -------------------------------------------------------------------------------- /h054_print_mem_cgroup_stat/Makefile: -------------------------------------------------------------------------------- 1 | ifneq ($(KERNELRELEASE), ) 2 | obj-m := print_mem_cgroup_stat.o 3 | else 4 | KERNELDIR ?=/lib/modules/$(shell uname -r)/build 5 | PWD := $(shell pwd) 6 | all: 7 | $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 8 | clean: 9 | $(MAKE) -C $(KERNELDIR) M=$(PWD) clean 10 | load: 11 | @sudo dmesg -c > /dev/null 12 | @echo "#############[START] #################" 13 | @sudo insmod print_mem_cgroup_stat.ko 14 | @sudo dmesg 15 | unload: 16 | @sudo dmesg -c > /dev/null 17 | @sudo rmmod print_mem_cgroup_stat 18 | @sudo dmesg 19 | @echo "#############[ END ] #################" 20 | test: 21 | @make load 22 | @make unload 23 | endif 24 | -------------------------------------------------------------------------------- /h054_print_mem_cgroup_stat/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawolf/dive-in-kernel/663175ee02d5d976b289bdc64a23f70fefc4368f/h054_print_mem_cgroup_stat/README.md -------------------------------------------------------------------------------- /h054_print_mem_cgroup_stat/print_mem_cgroup_stat.c: -------------------------------------------------------------------------------- 1 | /*********************************************** 2 | * module : print_mem_cgroup_stat 3 | * 4 | * Wang Long (w@laoqinren.net) 5 | **********************************************/ 6 | #include 7 | #include 8 | #include 9 | #include 10 | static int pid = 1; 11 | module_param(pid, int, 0400); 12 | MODULE_PARM_DESC(pid, "The pid to print"); 13 | 14 | static int __init print_mem_cgroup_stat_init(void) 15 | { 16 | pid_t p = (pid_t)pid; 17 | struct task_struct *task; 18 | struct mem_cgroup *memcg = NULL; 19 | long val = 0; 20 | int cpu; 21 | int i; 22 | 23 | printk(KERN_ALERT "[Hello] print_mem_cgroup_stat \n"); 24 | task = get_pid_task(find_get_pid(p), PIDTYPE_PID); 25 | memcg = mem_cgroup_from_task(task); 26 | // memcg = mem_cgroup_from_css(task_subsys_state(task, mem_cgroup_subsys_id)); 27 | 28 | for_each_online_cpu(cpu) { 29 | //val = per_cpu(memcg->stat->count[MEM_CGROUP_STAT_WRITEBACK], cpu); 30 | val = per_cpu(memcg->stat_cpu->nr_page_events, cpu); 31 | printk(KERN_ALERT "cpu %d, nr_page_events = %ld", cpu, val); 32 | for (i = 0; i < MEM_CGROUP_NTARGETS; i++) { 33 | val = per_cpu(memcg->stat_cpu->targets[i], cpu); 34 | printk(KERN_ALERT "\t targets[%d] = %ld", i, val); 35 | } 36 | } 37 | return 0; 38 | } 39 | 40 | static void __exit print_mem_cgroup_stat_exit(void) 41 | { 42 | printk(KERN_ALERT "[Goodbye] print_mem_cgroup_stat\n"); 43 | } 44 | 45 | module_init(print_mem_cgroup_stat_init); 46 | module_exit(print_mem_cgroup_stat_exit); 47 | MODULE_LICENSE("GPL"); 48 | -------------------------------------------------------------------------------- /h055_per_cpu/Makefile: -------------------------------------------------------------------------------- 1 | ifneq ($(KERNELRELEASE), ) 2 | obj-m := test_per_cpu.o 3 | else 4 | KERNELDIR ?=/lib/modules/$(shell uname -r)/build 5 | PWD := $(shell pwd) 6 | all: 7 | $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 8 | clean: 9 | $(MAKE) -C $(KERNELDIR) M=$(PWD) clean 10 | load: 11 | @sudo dmesg -c > /dev/null 12 | @echo "#############[START] #################" 13 | @sudo insmod test_per_cpu.ko 14 | @sudo dmesg 15 | unload: 16 | @sudo dmesg -c > /dev/null 17 | @sudo rmmod test_per_cpu 18 | @sudo dmesg 19 | @echo "#############[ END ] #################" 20 | test: 21 | @make load 22 | @make unload 23 | endif 24 | -------------------------------------------------------------------------------- /h055_per_cpu/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawolf/dive-in-kernel/663175ee02d5d976b289bdc64a23f70fefc4368f/h055_per_cpu/README.md -------------------------------------------------------------------------------- /h055_per_cpu/test_per_cpu.c: -------------------------------------------------------------------------------- 1 | /*********************************************** 2 | * module : test_per_cpu 3 | * 4 | * Wang Long (w@laoqinren.net) 5 | **********************************************/ 6 | #include 7 | #include 8 | #include 9 | 10 | 11 | static DEFINE_PER_CPU(unsigned long, a); 12 | static DEFINE_PER_CPU(unsigned long, b); 13 | 14 | 15 | static int watchdog_should_run(void) 16 | { 17 | return __this_cpu_read(a) != __this_cpu_read(b); 18 | } 19 | 20 | static int __init test_per_cpu_init(void) 21 | { 22 | __this_cpu_write(a, 23333); 23 | __this_cpu_write(b, 23333); 24 | printk(KERN_ALERT "[Hello] test_per_cpu : \n"); 25 | printk(KERN_ALERT "watchdog_should_run return : %d\n", watchdog_should_run()); 26 | return 0; 27 | } 28 | 29 | static void __exit test_per_cpu_exit(void) 30 | { 31 | printk(KERN_ALERT "[Goodbye] test_per_cpu\n"); 32 | } 33 | 34 | module_init(test_per_cpu_init); 35 | module_exit(test_per_cpu_exit); 36 | MODULE_LICENSE("GPL"); 37 | -------------------------------------------------------------------------------- /h056_test_cap_sys_admin/Makefile: -------------------------------------------------------------------------------- 1 | ifneq ($(KERNELRELEASE), ) 2 | obj-m := test_cap_sys_admin.o 3 | else 4 | KERNELDIR ?=/lib/modules/$(shell uname -r)/build 5 | PWD := $(shell pwd) 6 | all: 7 | $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 8 | clean: 9 | $(MAKE) -C $(KERNELDIR) M=$(PWD) clean 10 | load: 11 | @sudo dmesg -c > /dev/null 12 | @echo "#############[START] #################" 13 | @sudo insmod test_cap_sys_admin.ko 14 | @sudo dmesg 15 | unload: 16 | @sudo dmesg -c > /dev/null 17 | @sudo rmmod test_cap_sys_admin 18 | @sudo dmesg 19 | @echo "#############[ END ] #################" 20 | test: 21 | @make load 22 | @make unload 23 | endif 24 | -------------------------------------------------------------------------------- /h056_test_cap_sys_admin/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawolf/dive-in-kernel/663175ee02d5d976b289bdc64a23f70fefc4368f/h056_test_cap_sys_admin/README.md -------------------------------------------------------------------------------- /h056_test_cap_sys_admin/test_cap_sys_admin.c: -------------------------------------------------------------------------------- 1 | /*********************************************** 2 | * module : test_cap_sys_admin 3 | * 4 | * Wang Long (w@laoqinren.net) 5 | **********************************************/ 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | static int pid = 1; 14 | module_param(pid, int, 0400); 15 | MODULE_PARM_DESC(pid, "The pid to clear CAP_SYS_ADMIN"); 16 | 17 | static void render_cap_t(const char *header, 18 | kernel_cap_t *a) 19 | { 20 | char buff[1024]; 21 | int desc = 0; 22 | unsigned __capi; 23 | 24 | desc += sprintf(buff+desc, "%s", header); 25 | CAP_FOR_EACH_U32(__capi) { 26 | desc += sprintf(buff+desc, "%08x", 27 | a->cap[CAP_LAST_U32 - __capi]); 28 | } 29 | printk("%s", buff); 30 | } 31 | 32 | 33 | static int __init test_cap_sys_admin_init(void) 34 | { 35 | pid_t pp = (pid_t)pid; 36 | struct task_struct *p; 37 | const struct cred *cred; 38 | kernel_cap_t cap_inheritable, cap_permitted, cap_effective, 39 | cap_bset, cap_ambient; 40 | 41 | printk(KERN_ALERT "[Hello] test_cap_sys_admin \n"); 42 | 43 | p = get_pid_task(find_get_pid(pp), PIDTYPE_PID); 44 | rcu_read_lock(); 45 | cred = __task_cred(p); 46 | cap_inheritable = cred->cap_inheritable; 47 | cap_permitted = cred->cap_permitted; 48 | cap_effective = cred->cap_effective; 49 | cap_bset = cred->cap_bset; 50 | cap_ambient = cred->cap_ambient; 51 | rcu_read_unlock(); 52 | 53 | render_cap_t("CapInh:\t", &cap_inheritable); 54 | render_cap_t("CapPrm:\t", &cap_permitted); 55 | render_cap_t("CapEff:\t", &cap_effective); 56 | render_cap_t("CapBnd:\t", &cap_bset); 57 | render_cap_t("CapAmb:\t", &cap_ambient); 58 | 59 | return 0; 60 | } 61 | 62 | static void __exit test_cap_sys_admin_exit(void) 63 | { 64 | printk(KERN_ALERT "[Goodbye] test_cap_sys_admin\n"); 65 | } 66 | 67 | module_init(test_cap_sys_admin_init); 68 | module_exit(test_cap_sys_admin_exit); 69 | MODULE_LICENSE("GPL"); 70 | -------------------------------------------------------------------------------- /h057_add_mycatget_call/Makefile: -------------------------------------------------------------------------------- 1 | ifneq ($(KERNELRELEASE), ) 2 | obj-m := mycapset_call.o 3 | else 4 | KERNELDIR ?=/lib/modules/$(shell uname -r)/build 5 | PWD := $(shell pwd) 6 | all: 7 | $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 8 | clean: 9 | $(MAKE) -C $(KERNELDIR) M=$(PWD) clean 10 | load: 11 | @sudo dmesg -c > /dev/null 12 | @echo "#############[START] #################" 13 | @sudo insmod mycapset_call.ko 14 | @sudo dmesg 15 | unload: 16 | @sudo dmesg -c > /dev/null 17 | @sudo rmmod mycapset_call 18 | @sudo dmesg 19 | @echo "#############[ END ] #################" 20 | test: 21 | @make load 22 | @make unload 23 | endif 24 | -------------------------------------------------------------------------------- /h057_add_mycatget_call/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawolf/dive-in-kernel/663175ee02d5d976b289bdc64a23f70fefc4368f/h057_add_mycatget_call/README.md -------------------------------------------------------------------------------- /h058_add_new_syscall/Makefile: -------------------------------------------------------------------------------- 1 | ifneq ($(KERNELRELEASE), ) 2 | obj-m := add_new_syscall.o 3 | else 4 | KERNELDIR ?=/lib/modules/$(shell uname -r)/build 5 | PWD := $(shell pwd) 6 | all: 7 | $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 8 | gcc -o test_syscall test.c 9 | clean: 10 | $(MAKE) -C $(KERNELDIR) M=$(PWD) clean 11 | rm -fr test_syscall 12 | load: 13 | @sudo dmesg -c > /dev/null 14 | @echo "#############[START] #################" 15 | @sudo insmod add_new_syscall.ko 16 | @sudo dmesg 17 | unload: 18 | @sudo dmesg -c > /dev/null 19 | @sudo rmmod add_new_syscall 20 | @sudo dmesg 21 | @echo "#############[ END ] #################" 22 | test: 23 | @make load 24 | ./test_syscall 25 | sleep 2 26 | @sudo dmesg 27 | @make unload 28 | endif 29 | -------------------------------------------------------------------------------- /h058_add_new_syscall/README.md: -------------------------------------------------------------------------------- 1 | http://kerneltravel.net/blog/2020/syscall_ljr_1/ 2 | -------------------------------------------------------------------------------- /h058_add_new_syscall/add_new_syscall.c: -------------------------------------------------------------------------------- 1 | /*********************************************** 2 | * module : add_new_syscall 3 | * 4 | * Wang Long (w@laoqinren.net) 5 | **********************************************/ 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | 15 | 16 | #define __NR_syscall 400 /* 系统调用号400 */ 17 | unsigned long * sys_call_table; 18 | 19 | unsigned int clear_and_return_cr0(void); 20 | void setback_cr0(unsigned int val); 21 | static int sys_mycall(void); 22 | 23 | int orig_cr0; /* 用来存储cr0寄存器原来的值 */ 24 | unsigned long *sys_call_table = 0; 25 | static int (*anything_saved)(void); /*定义一个函数指针,用来保存一个系统调用*/ 26 | 27 | /* 28 | * 设置cr0寄存器的第17位为0 29 | */ 30 | unsigned int clear_and_return_cr0(void) 31 | { 32 | unsigned int cr0 = 0; 33 | unsigned int ret; 34 | /* 前者用在32位系统。后者用在64位系统,本系统64位 */ 35 | 36 | /* 将cr0寄存器的值移动到rax寄存器中,同时输出到cr0变量中 */ 37 | //asm volatile ("movl %%cr0, %%eax" : "=a"(cr0)); 38 | asm volatile ("movq %%cr0, %%rax" : "=a"(cr0)); 39 | 40 | ret = cr0; 41 | cr0 &= 0xfffeffff; /* 将cr0变量值中的第17位清0,将修改后的值写入cr0寄存器 */ 42 | 43 | /* 读取cr0的值到rax寄存器,再将rax寄存器的值放入cr0中 */ 44 | //asm volatile ("movl %%eax, %%cr0" :: "a"(cr0)); 45 | asm volatile ("movq %%rax, %%cr0" :: "a"(cr0)); 46 | return ret; 47 | } 48 | 49 | /* 读取val的值到rax寄存器,再将rax寄存器的值放入cr0中 */ 50 | void setback_cr0(unsigned int val) 51 | { 52 | //asm volatile ("movl %%eax, %%cr0" :: "a"(val)); 53 | asm volatile ("movq %%rax, %%cr0" :: "a"(val)); 54 | } 55 | 56 | /* 添加自己的系统调用函数 */ 57 | static int sys_mycall(void) 58 | { 59 | int ret = 12345; 60 | printk(KERN_ALERT "My syscall is successful!\n"); 61 | return ret; 62 | } 63 | 64 | 65 | static int __init add_new_syscall_init(void) 66 | { 67 | printk(KERN_ALERT "[Hello] add_new_syscall \n"); 68 | 69 | sys_call_table = (unsigned long *)kallsyms_lookup_name("sys_call_table"); /* 获取系统调用服务首地址 */ 70 | printk(KERN_ALERT "sys_call_table: 0x%p\n", sys_call_table); 71 | 72 | anything_saved = (int(*)(void))(sys_call_table[__NR_syscall]); /* 保存原始系统调用 */ 73 | orig_cr0 = clear_and_return_cr0(); /* 设置cr0可更改 */ 74 | sys_call_table[__NR_syscall] = (unsigned long)&sys_mycall; /* 更改原始的系统调用服务地址 */ 75 | setback_cr0(orig_cr0); /* 设置为原始的只读cr0 */ 76 | 77 | return 0; 78 | } 79 | 80 | static void __exit add_new_syscall_exit(void) 81 | { 82 | orig_cr0 = clear_and_return_cr0(); /* 设置cr0中对sys_call_table的更改权限 */ 83 | sys_call_table[__NR_syscall] = (unsigned long)anything_saved; /* 设置cr0可更改 */ 84 | setback_cr0(orig_cr0); /* 恢复原有的中断向量表中的函数指针的值 */ 85 | printk(KERN_ALERT "[Goodbye] add_new_syscall\n"); 86 | } 87 | 88 | module_init(add_new_syscall_init); 89 | module_exit(add_new_syscall_exit); 90 | MODULE_LICENSE("GPL"); 91 | -------------------------------------------------------------------------------- /h058_add_new_syscall/test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | int main(void) 4 | { 5 | printf("%d\n",syscall(400)); 6 | return 0; 7 | } 8 | -------------------------------------------------------------------------------- /h059_add_new_syscall2/Makefile: -------------------------------------------------------------------------------- 1 | ifneq ($(KERNELRELEASE), ) 2 | obj-m := add_new_syscall.o 3 | else 4 | KERNELDIR ?=/lib/modules/$(shell uname -r)/build 5 | PWD := $(shell pwd) 6 | all: 7 | $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 8 | gcc -o test_syscall test.c 9 | clean: 10 | $(MAKE) -C $(KERNELDIR) M=$(PWD) clean 11 | rm -fr test_syscall 12 | load: 13 | @sudo dmesg -c > /dev/null 14 | @echo "#############[START] #################" 15 | @sudo insmod add_new_syscall.ko 16 | @sudo dmesg 17 | unload: 18 | @sudo dmesg -c > /dev/null 19 | @sudo rmmod add_new_syscall 20 | @sudo dmesg 21 | @echo "#############[ END ] #################" 22 | test: 23 | @make load 24 | ./test_syscall 25 | sleep 2 26 | @sudo dmesg 27 | @make unload 28 | endif 29 | -------------------------------------------------------------------------------- /h059_add_new_syscall2/README.md: -------------------------------------------------------------------------------- 1 | https://www.cnblogs.com/wangzahngjun/p/4992045.html 2 | 3 | 相比前一个模块,使用了新的方法来修改系统调用表 4 | -------------------------------------------------------------------------------- /h059_add_new_syscall2/add_new_syscall.c: -------------------------------------------------------------------------------- 1 | /*********************************************** 2 | * module : add_new_syscall 3 | * 4 | * Wang Long (w@laoqinren.net) 5 | **********************************************/ 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | 15 | 16 | #define __NR_syscall 400 /* 系统调用号400 */ 17 | static int sys_mycall(void); 18 | 19 | unsigned long *sys_call_table = 0; 20 | static int (*anything_saved)(void); /*定义一个函数指针,用来保存一个系统调用*/ 21 | 22 | int make_rw(unsigned long address) 23 | { 24 | unsigned int level; 25 | pte_t *pte = lookup_address(address, &level);//查找虚拟地址所在的页表地址 26 | if (pte->pte & ~_PAGE_RW) //设置页表读写属性 27 | pte->pte |= _PAGE_RW; 28 | 29 | return 0; 30 | } 31 | 32 | int make_ro(unsigned long address) 33 | { 34 | unsigned int level; 35 | pte_t *pte = lookup_address(address, &level); 36 | pte->pte &= ~_PAGE_RW; //设置只读属性 37 | 38 | return 0; 39 | } 40 | 41 | /* 添加自己的系统调用函数 */ 42 | static int sys_mycall(void) 43 | { 44 | int ret = 12345; 45 | printk(KERN_ALERT "My syscall is successful!\n"); 46 | return ret; 47 | } 48 | 49 | static int __init add_new_syscall_init(void) 50 | { 51 | printk(KERN_ALERT "[Hello] add_new_syscall \n"); 52 | 53 | sys_call_table = (unsigned long *)kallsyms_lookup_name("sys_call_table"); /* 获取系统调用服务首地址 */ 54 | printk(KERN_ALERT "sys_call_table: 0x%px\n", sys_call_table); 55 | 56 | anything_saved = (int(*)(void))(sys_call_table[__NR_syscall]); /* 保存原始系统调用 */ 57 | make_rw((unsigned long)sys_call_table); 58 | sys_call_table[__NR_syscall] = (unsigned long)&sys_mycall; /* 更改原始的系统调用服务地址 */ 59 | make_ro((unsigned long)sys_call_table); 60 | 61 | return 0; 62 | } 63 | 64 | static void __exit add_new_syscall_exit(void) 65 | { 66 | make_rw((unsigned long)sys_call_table); 67 | sys_call_table[__NR_syscall] = (unsigned long)anything_saved; /* 设置cr0可更改 */ 68 | make_ro((unsigned long)sys_call_table); 69 | printk(KERN_ALERT "[Goodbye] add_new_syscall\n"); 70 | } 71 | 72 | module_init(add_new_syscall_init); 73 | module_exit(add_new_syscall_exit); 74 | MODULE_LICENSE("GPL"); 75 | -------------------------------------------------------------------------------- /h059_add_new_syscall2/test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | int main(void) 4 | { 5 | printf("%d\n",syscall(400)); 6 | return 0; 7 | } 8 | -------------------------------------------------------------------------------- /h060_add_new_syscall3/Makefile: -------------------------------------------------------------------------------- 1 | ifneq ($(KERNELRELEASE), ) 2 | obj-m := add_new_syscall.o 3 | else 4 | KERNELDIR ?=/lib/modules/$(shell uname -r)/build 5 | PWD := $(shell pwd) 6 | all: 7 | $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 8 | gcc -o test_syscall test.c 9 | clean: 10 | $(MAKE) -C $(KERNELDIR) M=$(PWD) clean 11 | rm -fr test_syscall 12 | load: 13 | @sudo dmesg -c > /dev/null 14 | @echo "#############[START] #################" 15 | @sudo insmod add_new_syscall.ko 16 | @sudo dmesg 17 | unload: 18 | @sudo dmesg -c > /dev/null 19 | @sudo rmmod add_new_syscall 20 | @sudo dmesg 21 | @echo "#############[ END ] #################" 22 | test: 23 | @make load 24 | ./test_syscall 25 | sleep 2 26 | @sudo dmesg 27 | @make unload 28 | endif 29 | -------------------------------------------------------------------------------- /h060_add_new_syscall3/README.md: -------------------------------------------------------------------------------- 1 | 2 | 本来打算使用新的方法是这系统调用表可写: 3 | 4 | ``` 5 | /* 6 | * Functions to change memory attributes. 7 | */ 8 | int set_memory_ro(unsigned long addr, int numpages); 9 | int set_memory_rw(unsigned long addr, int numpages); 10 | int set_memory_x(unsigned long addr, int numpages); 11 | int set_memory_nx(unsigned long addr, int numpages); 12 | ``` 13 | 14 | 但经过实验发现,该方法无法完成。 15 | 在 set_memory_rw() 内部调用的set_memory_rw() static_protections()函数会在以下情况下删除_PAGE_RW标志: 16 | 17 | * 它在 BIOS 区域 18 | * 地址在 .rodata 里面 19 | * CONFIG_DEBUG_RODATA 设置,内核设置为只读 20 | 21 | 22 | 参考:https://qa.icopy.site/questions/2103315/linux-kernel-system-call-hooking-example?noredirect=1 23 | 参考:https://elixir.bootlin.com/linux/v5.10/source/arch/x86/mm/pat/set_memory.c#L526 24 | 25 | -------------------------------------------------------------------------------- /h060_add_new_syscall3/add_new_syscall.c: -------------------------------------------------------------------------------- 1 | /*********************************************** 2 | * module : add_new_syscall 3 | * 4 | * Wang Long (w@laoqinren.net) 5 | **********************************************/ 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #define __NR_syscall 400 /* 系统调用号400 */ 17 | static int sys_mycall(void); 18 | 19 | unsigned long *sys_call_table = 0; 20 | static int (*anything_saved)(void); /*定义一个函数指针,用来保存一个系统调用*/ 21 | 22 | 23 | static int (*hulk_set_memory_rw)(unsigned long addr, int numpages); 24 | static int (*hulk_set_memory_ro)(unsigned long addr, int numpages); 25 | 26 | /* 添加自己的系统调用函数 */ 27 | static int sys_mycall(void) 28 | { 29 | int ret = 12345; 30 | printk(KERN_ALERT "My syscall is successful!\n"); 31 | return ret; 32 | } 33 | 34 | static int __init add_new_syscall_init(void) 35 | { 36 | int ret; 37 | printk(KERN_ALERT "[Hello] add_new_syscall \n"); 38 | 39 | hulk_set_memory_rw = (void *)kallsyms_lookup_name("set_memory_rw"); 40 | if (!hulk_set_memory_rw) { 41 | pr_err("can't find set_memory_rw symbol\n"); 42 | return -ENXIO; 43 | } 44 | 45 | hulk_set_memory_ro = (void *)kallsyms_lookup_name("set_memory_ro"); 46 | if (!hulk_set_memory_ro) { 47 | pr_err("can't find set_memory_ro symbol\n"); 48 | return -ENXIO; 49 | } 50 | 51 | 52 | sys_call_table = (unsigned long *)kallsyms_lookup_name("sys_call_table"); /* 获取系统调用服务首地址 */ 53 | printk(KERN_ALERT "sys_call_table: 0x%px\n", sys_call_table); 54 | 55 | anything_saved = (int(*)(void))(sys_call_table[__NR_syscall]); /* 保存原始系统调用 */ 56 | ret = hulk_set_memory_rw((unsigned long)sys_call_table & PAGE_MASK , 1); 57 | if (ret) 58 | printk(KERN_ALERT "hulk_set_memory_rw returns: %d\n", ret); 59 | // sys_call_table[__NR_syscall] = (unsigned long)&sys_mycall; /* 更改原始的系统调用服务地址 */ 60 | ret = hulk_set_memory_ro((unsigned long)sys_call_table & PAGE_MASK , 1); 61 | if (ret) 62 | printk(KERN_ALERT "hulk_set_memory_ro returns: %d\n", ret); 63 | 64 | return 0; 65 | } 66 | 67 | static void __exit add_new_syscall_exit(void) 68 | { 69 | int ret; 70 | ret = hulk_set_memory_rw((unsigned long)sys_call_table & PAGE_MASK , 1); 71 | if (ret) 72 | printk(KERN_ALERT "hulk_set_memory_rw returns: %d\n", ret); 73 | // sys_call_table[__NR_syscall] = (unsigned long)anything_saved; /* 设置cr0可更改 */ 74 | ret = hulk_set_memory_ro((unsigned long)sys_call_table & PAGE_MASK , 1); 75 | if (ret) 76 | printk(KERN_ALERT "hulk_set_memory_ro returns: %d\n", ret); 77 | printk(KERN_ALERT "[Goodbye] add_new_syscall\n"); 78 | } 79 | 80 | module_init(add_new_syscall_init); 81 | module_exit(add_new_syscall_exit); 82 | MODULE_LICENSE("GPL"); 83 | -------------------------------------------------------------------------------- /h060_add_new_syscall3/test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | int main(void) 4 | { 5 | printf("%d\n",syscall(400)); 6 | return 0; 7 | } 8 | -------------------------------------------------------------------------------- /h061_test_set_fs/Makefile: -------------------------------------------------------------------------------- 1 | ifneq ($(KERNELRELEASE), ) 2 | obj-m := read_write_userspace.o 3 | else 4 | KERNELDIR ?=/lib/modules/$(shell uname -r)/build 5 | PWD := $(shell pwd) 6 | all: 7 | $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 8 | clean: 9 | $(MAKE) -C $(KERNELDIR) M=$(PWD) clean 10 | load: 11 | @sudo dmesg -c > /dev/null 12 | @echo "#############[START] #################" 13 | @sudo insmod read_write_userspace.ko 14 | @sudo dmesg 15 | unload: 16 | @sudo dmesg -c > /dev/null 17 | @sudo rmmod read_write_userspace 18 | @sudo dmesg 19 | @echo "#############[ END ] #################" 20 | test: 21 | @make load 22 | @make unload 23 | endif 24 | -------------------------------------------------------------------------------- /h061_test_set_fs/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawolf/dive-in-kernel/663175ee02d5d976b289bdc64a23f70fefc4368f/h061_test_set_fs/README.md -------------------------------------------------------------------------------- /h061_test_set_fs/read_write_userspace.c: -------------------------------------------------------------------------------- 1 | /*********************************************** 2 | * module : read_write_userspace 3 | * 4 | * Wang Long (w@laoqinren.net) 5 | **********************************************/ 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | static ssize_t (*orig_vfs_write)(struct file *file, const char __user *buf, size_t count, loff_t *pos); 14 | static ssize_t (*orig_vfs_read)(struct file *file, char __user *buf, size_t count, loff_t *pos); 15 | 16 | char buf_write[128]; 17 | char buf_read[128]; 18 | static int __init read_write_userspace_init(void) 19 | { 20 | struct file *fp; 21 | mm_segment_t old_fs; 22 | int ret; 23 | 24 | loff_t pos; 25 | 26 | printk(KERN_ALERT "[Hello] read_write_userspace \n"); 27 | 28 | orig_vfs_read = (void *)kallsyms_lookup_name("vfs_read"); 29 | if (!orig_vfs_read) { 30 | pr_err("can't find vfs_read symbol\n"); 31 | return -ENXIO; 32 | } 33 | 34 | orig_vfs_write = (void *)kallsyms_lookup_name("vfs_write"); 35 | if (!orig_vfs_write) { 36 | pr_err("can't find vfs_write symbol\n"); 37 | return -ENXIO; 38 | } 39 | 40 | fp = filp_open("/root/kernel_file", O_RDWR|O_CREAT, 0644); 41 | if (IS_ERR(fp)) { 42 | printk(KERN_ALERT "create file error"); 43 | return -1; 44 | } 45 | 46 | sprintf(buf_write,"%s", "The message: I from kerenl!\n"); 47 | old_fs = get_fs(); 48 | set_fs(KERNEL_DS); 49 | 50 | pos = 0; 51 | ret = orig_vfs_write(fp, buf_write, sizeof(buf_write), &pos); 52 | if (ret < 0) 53 | printk(KERN_ALERT "vfs_write : ret = %d\n", ret); 54 | 55 | pos =0; 56 | ret = orig_vfs_read(fp, buf_read, sizeof(buf_read), &pos); 57 | if (ret < 0) 58 | printk(KERN_ALERT "vfs_read: ret = %d\n", ret); 59 | 60 | printk(KERN_ALERT "write connent = %s\n", buf_read); 61 | filp_close(fp, NULL); 62 | set_fs(old_fs); 63 | 64 | return 0; 65 | } 66 | 67 | static void __exit read_write_userspace_exit(void) 68 | { 69 | printk(KERN_ALERT "[Goodbye] read_write_userspace\n"); 70 | } 71 | 72 | module_init(read_write_userspace_init); 73 | module_exit(read_write_userspace_exit); 74 | MODULE_LICENSE("GPL"); 75 | -------------------------------------------------------------------------------- /h062_test_kernel_read_write/Makefile: -------------------------------------------------------------------------------- 1 | ifneq ($(KERNELRELEASE), ) 2 | obj-m := read_write_userspace.o 3 | else 4 | KERNELDIR ?=/lib/modules/$(shell uname -r)/build 5 | PWD := $(shell pwd) 6 | all: 7 | $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 8 | clean: 9 | $(MAKE) -C $(KERNELDIR) M=$(PWD) clean 10 | load: 11 | @sudo dmesg -c > /dev/null 12 | @echo "#############[START] #################" 13 | @sudo insmod read_write_userspace.ko 14 | @sudo dmesg 15 | unload: 16 | @sudo dmesg -c > /dev/null 17 | @sudo rmmod read_write_userspace 18 | @sudo dmesg 19 | @echo "#############[ END ] #################" 20 | test: 21 | @make load 22 | @make unload 23 | endif 24 | -------------------------------------------------------------------------------- /h062_test_kernel_read_write/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawolf/dive-in-kernel/663175ee02d5d976b289bdc64a23f70fefc4368f/h062_test_kernel_read_write/README.md -------------------------------------------------------------------------------- /h062_test_kernel_read_write/read_write_userspace.c: -------------------------------------------------------------------------------- 1 | /*********************************************** 2 | * module : read_write_userspace 3 | * 4 | * Wang Long (w@laoqinren.net) 5 | **********************************************/ 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | char buf_write[128]; 13 | char buf_read[128]; 14 | static int __init read_write_userspace_init(void) 15 | { 16 | struct file *fp; 17 | int ret; 18 | 19 | loff_t pos; 20 | 21 | printk(KERN_ALERT "[Hello] read_write_userspace \n"); 22 | 23 | fp = filp_open("/root/kernel_file2", O_RDWR|O_CREAT, 0644); 24 | if (IS_ERR(fp)) { 25 | printk(KERN_ALERT "create file error"); 26 | return -1; 27 | } 28 | 29 | sprintf(buf_write,"%s", "The message: I from kerenl!, using kernel_write and kernel_read\n"); 30 | 31 | pos = 0; 32 | ret = kernel_write(fp, buf_write, sizeof(buf_write), &pos); 33 | if (ret < 0) 34 | printk(KERN_ALERT "kernel_write : ret = %d\n", ret); 35 | 36 | pos =0; 37 | ret = kernel_read(fp, buf_read, sizeof(buf_read), &pos); 38 | if (ret < 0) 39 | printk(KERN_ALERT "kernel_read: ret = %d\n", ret); 40 | 41 | printk(KERN_ALERT "write connent = %s\n", buf_read); 42 | filp_close(fp, NULL); 43 | 44 | return 0; 45 | } 46 | 47 | static void __exit read_write_userspace_exit(void) 48 | { 49 | printk(KERN_ALERT "[Goodbye] read_write_userspace\n"); 50 | } 51 | 52 | module_init(read_write_userspace_init); 53 | module_exit(read_write_userspace_exit); 54 | MODULE_LICENSE("GPL"); 55 | -------------------------------------------------------------------------------- /h063_test_file_fop/Makefile: -------------------------------------------------------------------------------- 1 | ifneq ($(KERNELRELEASE), ) 2 | obj-m := read_write_userspace.o 3 | else 4 | KERNELDIR ?=/lib/modules/$(shell uname -r)/build 5 | PWD := $(shell pwd) 6 | all: 7 | $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 8 | clean: 9 | $(MAKE) -C $(KERNELDIR) M=$(PWD) clean 10 | load: 11 | @sudo dmesg -c > /dev/null 12 | @echo "#############[START] #################" 13 | @sudo insmod read_write_userspace.ko 14 | @sudo dmesg 15 | unload: 16 | @sudo dmesg -c > /dev/null 17 | @sudo rmmod read_write_userspace 18 | @sudo dmesg 19 | @echo "#############[ END ] #################" 20 | test: 21 | @make load 22 | @make unload 23 | endif 24 | -------------------------------------------------------------------------------- /h063_test_file_fop/README.md: -------------------------------------------------------------------------------- 1 | 该模块没有达到期望的目标,在filp_open一个文件后,file->f_op->write是null,所以不能直接使用。 2 | -------------------------------------------------------------------------------- /h063_test_file_fop/read_write_userspace.c: -------------------------------------------------------------------------------- 1 | /*********************************************** 2 | * module : read_write_userspace 3 | * 4 | * Wang Long (w@laoqinren.net) 5 | **********************************************/ 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | char buf_write[128]; 13 | char buf_read[128]; 14 | static int __init read_write_userspace_init(void) 15 | { 16 | struct file *fp; 17 | int ret; 18 | mm_segment_t old_fs; 19 | loff_t pos; 20 | 21 | printk(KERN_ALERT "[Hello] read_write_userspace \n"); 22 | 23 | fp = filp_open("/root/kernel_file3", O_RDWR|O_APPEND|O_CREAT, 0644); 24 | if (IS_ERR(fp)) { 25 | printk(KERN_ALERT "create file error"); 26 | return -1; 27 | } 28 | 29 | if (fp->f_op == NULL) { 30 | printk(KERN_ALERT "fp->f_op == NULL"); 31 | return -1; 32 | } 33 | 34 | if (fp->f_op->write == NULL) { 35 | printk(KERN_ALERT "fp->f_op->write == NULL"); 36 | return -1; 37 | } 38 | 39 | if (fp->f_op->read == NULL) { 40 | printk(KERN_ALERT "fp->f_op->read == NULL"); 41 | return -1; 42 | } 43 | 44 | sprintf(buf_write,"%s", "The message: I from kerenl!, using file->f_op->write\n"); 45 | old_fs = get_fs(); 46 | pos = 0; 47 | ret = fp->f_op->write(fp, buf_write, sizeof(buf_write), &pos); 48 | if (ret < 0) 49 | printk(KERN_ALERT "fp->f_op->write: ret = %d\n", ret); 50 | 51 | pos =0; 52 | ret = fp->f_op->read(fp, buf_read, sizeof(buf_read), &pos); 53 | if (ret < 0) 54 | printk(KERN_ALERT "fp->f_op->read: ret = %d\n", ret); 55 | 56 | printk(KERN_ALERT "write connent = %s\n", buf_read); 57 | filp_close(fp, NULL); 58 | set_fs(old_fs); 59 | 60 | return 0; 61 | } 62 | 63 | static void __exit read_write_userspace_exit(void) 64 | { 65 | printk(KERN_ALERT "[Goodbye] read_write_userspace\n"); 66 | } 67 | 68 | module_init(read_write_userspace_init); 69 | module_exit(read_write_userspace_exit); 70 | MODULE_LICENSE("GPL"); 71 | -------------------------------------------------------------------------------- /m001/Makefile: -------------------------------------------------------------------------------- 1 | ifneq ($(KERNELRELEASE), ) 2 | obj-m := up_sem.o 3 | else 4 | KERNELDIR ?=/lib/modules/$(shell uname -r)/build 5 | PWD := $(shell pwd) 6 | all: 7 | $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 8 | clean: 9 | $(MAKE) -C $(KERNELDIR) M=$(PWD) clean 10 | load: 11 | @sudo dmesg -c > /dev/null 12 | @echo "#############[START] #################" 13 | @sudo insmod up_sem.ko 14 | @sudo dmesg 15 | unload: 16 | @sudo dmesg -c > /dev/null 17 | @sudo rmmod up_sem 18 | @sudo dmesg 19 | @echo "#############[ END ] #################" 20 | test: 21 | @make load 22 | @make unload 23 | endif 24 | -------------------------------------------------------------------------------- /m001/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawolf/dive-in-kernel/663175ee02d5d976b289bdc64a23f70fefc4368f/m001/README.md -------------------------------------------------------------------------------- /m001/up_sem.c: -------------------------------------------------------------------------------- 1 | /*********************************************** 2 | * module : up_sem 3 | * 4 | * Wang Long (wanglong@laoqinren.net) 5 | **********************************************/ 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | // insmod up_sem.ko task_address=0xffff880119b40000 13 | 14 | static ulong task_address; 15 | module_param(task_address, ulong, 0400); 16 | MODULE_PARM_DESC(mem_address, "The task_struct address to up sem"); 17 | 18 | static int __init up_sem_init(void) 19 | { 20 | struct task_struct *task = (struct task_struct *)task_address; 21 | struct rw_semaphore *sem = &task->mm->mmap_sem; 22 | 23 | printk(KERN_ALERT "[Hello] up_sem \n"); 24 | printk("task->comm = %s\n", task->comm); 25 | 26 | 27 | if (down_read_trylock(sem)) 28 | { 29 | printk("up read for 1: %s\n", task->comm); 30 | up_read(sem); 31 | printk("up read for 2: %s\n", task->comm); 32 | up_read(sem); 33 | } 34 | else { 35 | printk("up write for: %s\n", task->comm); 36 | up_write(sem); 37 | } 38 | 39 | return 0; 40 | } 41 | 42 | static void __exit up_sem_exit(void) 43 | { 44 | printk(KERN_ALERT "[Goodbye] up_sem\n"); 45 | } 46 | 47 | module_init(up_sem_init); 48 | module_exit(up_sem_exit); 49 | MODULE_LICENSE("GPL"); 50 | MODULE_AUTHOR("datawolf"); 51 | -------------------------------------------------------------------------------- /m002_test_kallsyms_lookup_name/Makefile: -------------------------------------------------------------------------------- 1 | ifneq ($(KERNELRELEASE), ) 2 | obj-m := test_kallsyms_lookup_name.o 3 | else 4 | KERNELDIR ?=/lib/modules/$(shell uname -r)/build 5 | PWD := $(shell pwd) 6 | all: 7 | $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 8 | clean: 9 | $(MAKE) -C $(KERNELDIR) M=$(PWD) clean 10 | load: 11 | @sudo dmesg -c > /dev/null 12 | @echo "#############[START] #################" 13 | @sudo insmod test_kallsyms_lookup_name.ko 14 | @sudo dmesg 15 | unload: 16 | @sudo dmesg -c > /dev/null 17 | @sudo rmmod test_kallsyms_lookup_name 18 | @sudo dmesg 19 | @echo "#############[ END ] #################" 20 | test: 21 | @make load 22 | @make unload 23 | cat /proc/kallsyms | grep -E 'super_blocks|sys_call_table' 24 | endif 25 | -------------------------------------------------------------------------------- /m002_test_kallsyms_lookup_name/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawolf/dive-in-kernel/663175ee02d5d976b289bdc64a23f70fefc4368f/m002_test_kallsyms_lookup_name/README.md -------------------------------------------------------------------------------- /m002_test_kallsyms_lookup_name/test_kallsyms_lookup_name.c: -------------------------------------------------------------------------------- 1 | /*********************************************** 2 | * module : test_kallsyms_lookup_name 3 | * 4 | * Wang Long (w@laoqinren.net) 5 | **********************************************/ 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | 12 | static int __init test_kallsyms_lookup_name_init(void) 13 | { 14 | struct list_head *super_blocks; 15 | unsigned long *sys_call_table; 16 | 17 | printk(KERN_ALERT "[Hello] test_kallsyms_lookup_name \n"); 18 | 19 | super_blocks = (struct list_head *)kallsyms_lookup_name("super_blocks"); 20 | printk(KERN_ALERT "The address of super_blocks is 0x%lx\n", super_blocks); 21 | printk(KERN_ALERT "The address of super_blocks is 0x%p\n", super_blocks); 22 | printk(KERN_ALERT "The address of super_blocks is 0x%px\n", super_blocks); 23 | 24 | 25 | sys_call_table = (unsigned long *)kallsyms_lookup_name("sys_call_table"); 26 | printk(KERN_ALERT "The address of sys_call_table is 0x%lx\n", sys_call_table); 27 | printk(KERN_ALERT "The address of sys_call_table is 0x%p\n", sys_call_table); 28 | printk(KERN_ALERT "The address of sys_call_table is 0x%px\n", sys_call_table); 29 | 30 | return 0; 31 | } 32 | 33 | static void __exit test_kallsyms_lookup_name_exit(void) 34 | { 35 | printk(KERN_ALERT "[Goodbye] test_kallsyms_lookup_name\n"); 36 | } 37 | 38 | module_init(test_kallsyms_lookup_name_init); 39 | module_exit(test_kallsyms_lookup_name_exit); 40 | MODULE_LICENSE("GPL"); 41 | -------------------------------------------------------------------------------- /m003_test_printf/Makefile: -------------------------------------------------------------------------------- 1 | ifneq ($(KERNELRELEASE), ) 2 | obj-m := test_printf.o 3 | else 4 | KERNELDIR ?=/lib/modules/$(shell uname -r)/build 5 | PWD := $(shell pwd) 6 | all: 7 | $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 8 | clean: 9 | $(MAKE) -C $(KERNELDIR) M=$(PWD) clean 10 | load: 11 | @sudo dmesg -c > /dev/null 12 | @echo "#############[START] #################" 13 | @sudo insmod test_printf.ko 14 | @sudo dmesg 15 | unload: 16 | @sudo dmesg -c > /dev/null 17 | @sudo rmmod test_printf 18 | @sudo dmesg 19 | @echo "#############[ END ] #################" 20 | test: 21 | @make load 22 | @make unload 23 | endif 24 | -------------------------------------------------------------------------------- /m003_test_printf/README.md: -------------------------------------------------------------------------------- 1 | copy form: https://elixir.bootlin.com/linux/latest/source/lib/test_printf.c 2 | -------------------------------------------------------------------------------- /m004_test_rh_mark_used_feature/Makefile: -------------------------------------------------------------------------------- 1 | ifneq ($(KERNELRELEASE), ) 2 | obj-m := test_rh_mark_used_feature.o 3 | else 4 | KERNELDIR ?=/lib/modules/$(shell uname -r)/build 5 | PWD := $(shell pwd) 6 | all: 7 | $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 8 | clean: 9 | $(MAKE) -C $(KERNELDIR) M=$(PWD) clean 10 | load: 11 | @sudo dmesg -c > /dev/null 12 | @echo "#############[START] #################" 13 | @sudo cat /proc/driver/rh_features 14 | @sudo insmod test_rh_mark_used_feature.ko 15 | @sudo cat /proc/driver/rh_features 16 | @sudo dmesg 17 | unload: 18 | @sudo dmesg -c > /dev/null 19 | @sudo rmmod test_rh_mark_used_feature 20 | @sudo dmesg 21 | @echo "#############[ END ] #################" 22 | test: 23 | @make load 24 | @make unload 25 | endif 26 | -------------------------------------------------------------------------------- /m004_test_rh_mark_used_feature/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawolf/dive-in-kernel/663175ee02d5d976b289bdc64a23f70fefc4368f/m004_test_rh_mark_used_feature/README.md -------------------------------------------------------------------------------- /m004_test_rh_mark_used_feature/test_rh_mark_used_feature.c: -------------------------------------------------------------------------------- 1 | /*********************************************** 2 | * module : test_rh_mark_used_feature 3 | * 4 | * Wang Long (w@laoqinren.net) 5 | **********************************************/ 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | static int __init test_rh_mark_used_feature_init(void) 12 | { 13 | printk(KERN_ALERT "[Hello] test_rh_mark_used_feature \n"); 14 | printk(KERN_ALERT "%ld", rh_mark_used_feature("Feature/three")); 15 | printk(KERN_ALERT "%ld", rh_mark_used_feature("Feature/three")); 16 | return 0; 17 | } 18 | 19 | static void __exit test_rh_mark_used_feature_exit(void) 20 | { 21 | printk(KERN_ALERT "[Goodbye] test_rh_mark_used_feature\n"); 22 | } 23 | 24 | module_init(test_rh_mark_used_feature_init); 25 | module_exit(test_rh_mark_used_feature_exit); 26 | MODULE_LICENSE("GPL"); 27 | -------------------------------------------------------------------------------- /m005_test_linux_version_code/Makefile: -------------------------------------------------------------------------------- 1 | ifneq ($(KERNELRELEASE), ) 2 | obj-m := test_linux_version_code.o 3 | else 4 | KERNELDIR ?=/lib/modules/$(shell uname -r)/build 5 | PWD := $(shell pwd) 6 | all: 7 | $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 8 | clean: 9 | $(MAKE) -C $(KERNELDIR) M=$(PWD) clean 10 | load: 11 | @sudo dmesg -c > /dev/null 12 | @echo "#############[START] #################" 13 | @sudo insmod test_linux_version_code.ko 14 | @sudo dmesg 15 | unload: 16 | @sudo dmesg -c > /dev/null 17 | @sudo rmmod test_linux_version_code 18 | @sudo dmesg 19 | @echo "#############[ END ] #################" 20 | test: 21 | @make load 22 | @make unload 23 | endif 24 | -------------------------------------------------------------------------------- /m005_test_linux_version_code/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawolf/dive-in-kernel/663175ee02d5d976b289bdc64a23f70fefc4368f/m005_test_linux_version_code/README.md -------------------------------------------------------------------------------- /m005_test_linux_version_code/test_linux_version_code.c: -------------------------------------------------------------------------------- 1 | /*********************************************** 2 | * module : test_linux_version_code 3 | * 4 | * Wang Long (w@laoqinren.net) 5 | **********************************************/ 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | static int __init test_linux_version_code_init(void) 13 | { 14 | printk(KERN_ALERT "[Hello] test_linux_version_code \n"); 15 | printk(KERN_ALERT "[Hello] LINUX_VERSION_CODE= %d\n", LINUX_VERSION_CODE); 16 | printk(KERN_ALERT "[Hello] UTS_RELEASE= %s\n", UTS_RELEASE); 17 | return 0; 18 | } 19 | 20 | static void __exit test_linux_version_code_exit(void) 21 | { 22 | printk(KERN_ALERT "[Goodbye] test_linux_version_code\n"); 23 | } 24 | 25 | module_init(test_linux_version_code_init); 26 | module_exit(test_linux_version_code_exit); 27 | MODULE_LICENSE("GPL"); 28 | --------------------------------------------------------------------------------