如何编译Linux内核模块?

问题描述 投票:0回答:2

我正在尝试按照此 guide 编译一个简单的 hello world 模块,但我对

Makefile
实际上在做什么感到困惑。

这是:

obj-m += hello-1.o

all:
    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

clean:
    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

我知道,当我输入

make
命令时,它将运行运行
all
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
配方。所以现在它运行在
-C
标志后给出的路径中找到的 Makefile,但是
M=$(PWD) modules
是做什么的?

c makefile linux-kernel linux-device-driver
2个回答
15
投票

这是一个细分:

  1. obj-m
    :指定构建为可加载内核模块的目标文件。

  2. all and clean
    :如果默认运行
    make
    ,它将运行第一个目标,即
    all
    。但我们也可以使用
    make all
    make clean
    :它只会运行那些特定的目标。

    例如:

    make all
    # Will run: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
    
    make clean
    # Will run: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
    
  3. uname -r
    :获取当前内核的版本信息。

    示例:对我来说,输出是

    4.6.0-rc1

  4. 选项

    -C dir
    :在读取其中的 makefile 之前更改为目录
    dir

    示例:

    make -C /lib/modules/$(shell uname -r)/build
    # Will translate to: make -C /lib/modules/4.6.0-rc1/build
    # And execute the Makefile at /lib/modules/4.6.0-rc1/build/Makefile
    
    
  5. $(PWD)
    :获取当前目录的路径。

现在您想使用以下方法创建可加载模块:

make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

您的源代码需要特定的环境才能编译。这就是为什么我们必须使用

-C
选项来更改构建目录。其中包含所有需要的定义、头文件、宏等。现在,在更改到构建目录后,您可以使用
M=$(PWD)
告诉内核 Makefile 模块所在的位置。


5
投票

要编译内核模块,通常需要的

make
命令采用以下形式:

make -C /lib/modules/3.16.0-70-generic/build M=/home/test/ldd3/hello modules

其中,

-C
表示切换到另一条路径。

/lib/modules/3.16.0-70-generic/

是所使用的内核的路径,并且

/home/test/ldd3/hello

是模块源所在的位置。

M=$(PWD) 模块有什么作用?

正如我所说,

M=$(PWD)
只是一个 shell 变量,用于存储内核模块的当前路径。
make
需要在切换到内核构建路径时存储它。

© www.soinside.com 2019 - 2024. All rights reserved.