linux内核之Hello World

2023年 7月 25日 45.3k 0

1. 问题描述

梳理内核函数dump_stack的源码实现时,PC上竟然没有该函数打印内容的日志截图,又不想从网上盗图,所以学习下如何在内核中打印Hello World。

2. 解决方案

科普:Kernel Module是一个二进制文件,用于运行时拓展内核功能,如果功能不被需要时,可被卸载。直观上看,与dlopen机制类似,程序运行时显示加载so,当不使用该库时,调用dlclose关闭so。

解决思路:基于Kernel Module机制,执行命令"insmod + 模块名" 安装模块,执行打印。

2.1 基础版

注意:测试使用的系统是Ubuntu,目录/lib/modules下已有内核相应的头文件,无需自己安装源码。

  • 模块被加载时,内核执行函数hello_init,卸载则执行hello_exit。源文件名:hello.c
  • #include 
    #include 
    #include 
    
    MODULE_LICENSE("GPL");
    
    static int hello_init(void)
    {
        pr_info("%sn", "Hello World!");
        return 0;
    }
    
    static void hello_exit(void)
    {
        pr_info("%sn", "Byebye");
        return;
    }
    
    module_init(hello_init);
    module_exit(hello_exit);
    

    仅从代码来看,该机制类似于Java中调用System.loadLibrary加载so,so的JNI_OnLoad方法被执行。

  • Makefile,不要迟疑,文件名也是Makefile
  • obj-m := hello.o
    KDIR := /lib/modules/`uname -r`/build
    
    modules:
    	make -C $(KDIR) M=`pwd`
    clean:
    	make -C $(KDIR) M=`pwd` clean
    
  • 代码目录结构如下所示:
  • 截屏2023-07-25 10.24.59.png
    执行make命令即可,编译成功后,将生成hello.ko文件

  • 安装模块,命令:insmod hello.ko
  • 日志文件 /var/log/syslog,可看到如下打印。
    截屏2023-07-25 10.43.27.png
    使用命令lsmod,可查看内核加载的模块。
    截屏2023-07-25 10.44.04.png
    从图中也不难看出,hello模块也确实被加载到内核。
    5. 卸载模块,命令:rmmod hello

    截屏2023-07-25 10.52.55.png

    2.2 进阶版

    仅打印Hello World,还差点意思,需求场景:用户态进程使用C++ std::thread启动线程,该线程内部调用Linux系统调用,然后系统调用内部使用dump_stack打印内核堆栈。显然单靠Hello World完不成。

    该部分内容编撰中,敬请期待

    3. 参考

  • Kernel Modules 基础
  • kali2022编译Linux内核驱动ko文件
  • 相关文章

    服务器端口转发,带你了解服务器端口转发
    服务器开放端口,服务器开放端口的步骤
    产品推荐:7月受欢迎AI容器镜像来了,有Qwen系列大模型镜像
    如何使用 WinGet 下载 Microsoft Store 应用
    百度搜索:蓝易云 – 熟悉ubuntu apt-get命令详解
    百度搜索:蓝易云 – 域名解析成功但ping不通解决方案

    发布评论