📒
Notes
  • 个人笔记
  • Machine Learning
    • Tensorflow
      • Text
        • Keras构建RNN
        • 字词嵌入
        • 字词嵌入示例程序
      • Data processing
        • tf.data数据加载
      • Tensorflow Tricks
    • 循环神经网络概览
    • Pix2Pix
  • Assembly Language
    • DOS中的Debug模式
    • LOOP指令
    • 8086CPU
    • 标志位寄存器
    • 汇编指令
    • 汇编语言源程序格式
  • Linux System
    • Systemctl 服务脚本
    • Linux端口占用
    • Btrfs文件系统
    • C Socket网络编程细节问题
  • Hexo
    • Hexo下的Tag/Categories栏
    • Git备份博客
    • Hexo博客基本部署
  • Kernel
    • C语言中消息队列实现
    • Linux内核的进程调度函数
    • Linux内核模块的编译
    • Linux Kernel概述
  • Linux Software
    • Linux软件安装与配置
  • Docker
    • OVS+Docker网络构建
    • Docker分层垃圾清理
  • C
    • CMakeList语法
Powered by GitBook
On this page
  • Hello, World!
  • 构建内核模块

Was this helpful?

  1. Kernel

Linux内核模块的编译

Linux内核采用了模块化的设计,允许内核在运行时插入或删除代码。这些代码组合在一起,形成了所谓的模块。

支持模块的好处是内核可以尽可能的小,可选的功能和驱动则利用模块来提供。

Hello, World!

/* hello world module */
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>

static int __init hello_init(void)  // 初始化函数,模块装载时被调用
{
        printk("<1> Hello, World!\n");
        return 0;
}

static void __exit hello_exit(void) // 退出函数,模块卸载的时候被调用
{
        printk(KERN_ALERT "hello module exit.\n");
}

module_init(hello_init);
module_exit(hello_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("hello world");
MODULE_DESCRIPTION("first module");

模块的出口和入口都通过调用module_init()来注册到系统中,唯一的参数是模块的初始化函数。它其实是一个宏调用而非函数。 所有初始化函数必须满足如下形式:

int my_init(void);

类似的,退出函数使用module_exit()来注册,对应的函数作为出口函数,负责在返回(具体指了卸载内核模块)之前清理资源。 如果模块被静态地编译进内核,则这部分不会被调用,因为内核不需要卸载操作。

构建内核模块

内核模块的构建需要使用Makefile,使用一下模板可以完成编译:

ifneq ($(KERNELRELEASE),)
    obj-m += main.o
else
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
PWD := "$(shell pwd)"

default:
    $(MAKE) -C $(KERNELDIR) M=$(PWD) modules
    rm main.mod.c main.mod.o main.o modules.order Module.symvers .main.ko.cmd main.mod .main.mod.* .main.o.* -rf
endif

另外在Clion中使用如下的CMakeLists.txt,可以消除错误的报错信息并拥有相应的代码提示。在运行时不需要指定可执行目标,直接运行编译即可在根目录编译产生main.ko(即为一个内核模块),使用insmod命令加载即可。

cmake_minimum_required(VERSION 3.15)
project(default)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -nostdinc")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99 -nostdinc")

set(KERNEL_ROOT /usr/src/linux)
include_directories(
        # kernel headers
        "${KERNEL_ROOT}/include"
        "${KERNEL_ROOT}/arch/arm64/include"
        "${KERNEL_ROOT}/arch/arm/include"
        "${KERNEL_ROOT}/mm"
        "/usr/include"
)
add_definitions(-D__KERNEL__=1)

add_custom_target(default_custom COMMAND make -C "${default_SOURCE_DIR}"
        CLION_EXE_DIR="${PROJECT_BINARY_DIR}")
PreviousLinux内核的进程调度函数NextLinux Kernel概述

Last updated 5 years ago

Was this helpful?