精华内容
下载资源
问答
  • linux内核模块编译 两种编译
    万次阅读
    2018-04-09 18:51:27

    linux内核模块的编译方法有两种:

    1.放入linux内核源码中编译

    2.独立编译模块

    (1)放入linux内核源码中编译

    这里先了解Kconfig和Makefile的作用

    Kconfig:对应内核模块的配置菜单。

    Makefile:对应内核模块的编译选项。

    linux内核编译过程:是根据配置裁剪的结果配合Makefile完成内核编译。

    以ARM平台为例,具体配置过程:

    1.当执行make menuconfig 时,系统首先读取arch/arm/Kconfig生成整个配置界面

    2.在读取配置界面的同时,系统会读取顶层目录下的.config文件,生成所有配置选项的默认值

    3.当修改玩配置并保存后,系统会更新顶层目录下的.config

    4.当执行make时,各层的Makefile会根据.config文件中的编译选项来决定哪些文件会被编译到内核中,或者编译成模块。

    下面进入正题怎么把自己的内核代码添加到内核中

    1.把自己的内核代码放入到内核合适的位置   // 字符驱动  driver/char/

    2.把自己开发的功能添加到linux内核的配置选项中,使用户能够选中这项功能并编译。// vi /driver/char/Kconfig

    在Kconfig文件结尾,endmenu的前面加入一个config选项 

    config 2018_HELLO

            bool "This is my first drive "

            default y

            help

                The driver hh.     

    3.构建或修改Makefile。// vi dreiver/char/Makefile  obj-$(CONFIG_2018_HELLO)        += hello.c

    4.执行make

    (2)独立编译

    KVERS = $(shell uname -r)
    obj-m += hello.o
    build: kernel_modules
    EXTRA_CFLAGS=-g -o0
    kernel_modules:
        make -C /lib/modules/$(KVERS)/build M=$(CURDIR) modules
    clean:

        make -C /lib/modules/$(KVERS)/build M=$(CURDIR) clean

    写个Makefile就好了,生成.ko 在insmod hello.ko。

    两者的区别就是独立编译比较省时间,方便添加 移除,重启后消失。

     

    更多相关内容
  • linux内核模块编译。 1、准备内核模块源码 2、编写Makefile文件 3、编译模块 4、加载/卸载模块 5、加载模块时传递参数 6、总结
  • 下面就介绍这个内核模块实验hello 如何正确编译,我所使用的系统为内核版本:2.6.10  在/home/tmp/下建立两个文件hello.c,Makefile  hello.c  ------------  #include  #include  #include  MODULE_...
  • 本文主要说说如何编译自己开发的内核模块。由于驱动通常也被编译内核模块,因此文章的内容也适用于驱动的编译
  • 本篇文章中只讨论linux内核模块编译的makefile,linux内核makefile总览可以参考另一篇博客:linux内核makefile概览 本篇博客参考官方文档。 linux内核使用的是kbuild编译系统,在编译可加载模块时,其makefile的风格...

    linux内核可加载模块的makefile
    在开发linux内核驱动时,免不了要接触到makefile的编写和修改,尽管网上的makefile模板一大堆,做一些简单的修改就能用到自己的项目上,但是,对于这些基础的东西,更应该做到知其然并知其所以然。
    本篇文章中只讨论linux内核模块编译的makefile,linux内核makefile总览可以参考另一篇博客:linux内核makefile概览

    本篇博客参考官方文档。

    linux内核使用的是kbuild编译系统,在编译可加载模块时,其makefile的风格和常用的编译C程序的makefile有所不同,尽管如此,makefile的作用总归是给编译器提供编译信息。

    最简单的makefile
    我们先来看看一个最简单的makefile是怎样的:

    obj-m+=hello.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
    

    这个makefile的作用就是编译hello.c文件,最终生成hello.ko文件。

    obj-m+=hello.o
    obj-m表示编译生成可加载模块。

    相对应的,obj-y表示直接将模块编译进内核。

    可以看到,这里并没有输入hello.c源文件,熟悉makefile的人应该知道,这得益于makefile的自动推导功能,需要编译生成filename.o文件而没有显示地指定filename.c文件位置时,make查找filename.c是否存在,如果存在就正常编译,如果不存在,则报错。

    obj-m+=hello.o,这条语句就是显式地将hello.o编译成hello.ko,而hello.o则由make的自动推导功能编译hello.c文件生成。

    all,clean
    all,clean这一类的是makefile中的伪目标,伪目标并不是一个真正的编译目标,它代表着一系列你想要执行的命令集合,通常一个makefile会对应多个操作,例如编译,清除编译结果,安装,就可以使用这些伪目标来进行标记。在执行时就可以键入:

    make clean
    make install
    

    等指令来完成相应的指令操作,当make后不带参数时,默认执行第一个伪目标的操作。

    make -C /lib/modules/ ( s h e l l u n a m e − r ) / b u i l d / M = (shell uname -r)/build/ M= (shellunamer)/build/M=(PWD) modules
    标准的make指令是这样的:make -C K D I R M = KDIR M= KDIRM=PWD [target],下面分别介绍每个字段的含义。

    -C选项:此选项指定内核源码的位置,make在编译时将会进入内核源码目录,执行编译,编译完成时返回。

    K D I R : / l i b / m o d u l e s / KDIR:/lib/modules/ KDIR/lib/modules/(shell uname -r)/build/,指定内核源码的位置。

    直接在目标板上编译时,内核头文件默认存放在/lib/modules/$(shell uname -r)/build/中,这个build/目录是一个软连接,链接到源码头文件的安装位置。而内核真正的源码库则直接引用正在运行的内核镜像。

    当跨平台编译时,就需要指定相应的内核源码目录,而不是系统中的源码目录,但是交叉编译时,需不需要指定架构平台和交叉编译工具链呢?我们接着往下看;

    M=$(PWD):需要编译的模块源文件地址

    [target]:modules,事实上,这是个可选选项。默认行为是将源文件编译并生成内核模块,即module(s),但是它还支持一下选项:

    modules_install:安装这个外部模块,默认安装地址是/lib/modules/$(uname -r)/extra/,同时可以由内建变量INSTALL_MOD_PATH指定安装目录
    clean:卸载源文件目录下编译过程生成的文件,在上文的makefile最后一行可以看到。
    help:帮助信息
    更多选项
    编译多个源文件
    hello_world总是简单的,但是在实际开发中,就会出现更复杂的情况,这时候就需要了解更多的makefile选项:

    首先,当一个.o目标文件的生成依赖多个源文件时,显然make的自动推导规则就力不从心了(它只能根据同名推导,比如编译filename.o,只会去查找filename.c),我们可以这样指定:

    obj-m  += hello.o
    hello-y := a.o b.o hello_world.o
    

    hello.o目标文件依赖于a.o,b.o,hello_world.o,那么这里的a.o和b.o如果没有指定源文件,根据推导规则就是依赖源文件a.c,b.c,hello_world.c.
    除了hello-y,同时也可以用hello-objs,实现效果是一样的。

    同时编译多个可加载模块
    kbuild支持同时编译多个可加载模块,也就是生成多个.ko文件,它的格式是这样的:

    obj-m := foo.o bar.o
    foo-y := <foo_srcs>
    bar-y := <bar_srcs>
    

    就是这么简单。

    ifneq ($(KERNELRELEASE),)
    通常,标准的makefile会写成这样:

    ifneq ($(KERNELRELEASE),)
    obj-m  := hello.o
    
    else
    KDIR ?= /lib/modules/`uname -r`/build
    
    all:
            $(MAKE) -C $(KDIR) M=$(PWD) modules
    clean:
            $(MAKE) -C $(KDIR) M=$(PWD) clean
    endif
    

    为什么要添加一个ifneq,else,all条件判断。

    这得从linux内核模块make执行的过程说起:当键入make时,make在当前目录下寻找makefile并执行,KERNELRELEASE在顶层的makefile中被定义,所以在执行当前makefile时KERNELRELEASE并没有被定义,走else分支,直接执行

    $(MAKE) -C $(KDIR) M=$(PWD) modules
    

    而这条指令会进入到$(KDIR)目录,调用顶层的makefile,在顶层makefile中定义了KERNELRELEASE变量.

    在顶层makefile中会递归地再次调用到当前目录下的makefile文件,这时KERNELRELEASE变量已经非空,所以执行if分支,在可加载模块编译列表添加hello模块,由此将模块编译成可加载模块放在当前目录下。

    归根结底,各级子目录中的makefile文件的作用就是先切换到顶层makefile,然后通过obj-m在可加载模块编译列表中添加当前模块,kbuild就会将其编译成可加载模块。

    如果是直接编译整个内核源码,就省去了else分支中进入顶层makefile的步骤。

    需要注意的一个基本概念是:每一次编译,顶层makefile都试图递归地进入每个子目录调用子目录的makefile,只是当目标子目录中没有任何修改时,默认不再进行重复编译以节省编译时间。

    这里同时解决了上面的一个疑问:既然是从顶层目录开始编译,那么只要顶层目录中指定了架构(ARCH)和交叉编译工具链地址(CROSS_COMPILE),各子目录中就不再需要指定这两个参数。

    头文件的放置
    当编译的目标模块依赖多个头文件时,kbuild对头文件的放置有这样的规定:

    直接放置在makefile同在的目录下,在编译时当前目录会被添加到头文件搜索目录。

    放置在系统目录,这个系统目录是源代码目录中的include/linux/。

    与通用的makefile一样,使用-I$(DIR)来指定,不同的是,代表编译选项的变量是固定的,为ccflag.

    一般的用法是这样的:

          ccflags-y := -I$(DIR)/include   
    

    kbuild就会将$(DIR)/includ目录添加到编译时的头文件搜索目录中。
    linux内核makefile总览可以参考另一篇博客:linux内核makefile概览

    好了,关于linux编译内核模块的makefile介绍就到此为止啦,如果朋友们对于这个有什么疑问或者发现有文章中有什么错误,欢迎留言

    原创博客,转载请注明出处!

    祝各位早日实现项目丛中过,bug不沾身.

    展开全文
  • 通过本实验,使学生掌握在Linux系统内核中单独编译、加载和卸载所需的模块的一般方法和过程。
  • 下面就介绍这个内核模块实验hello 如何正确编译,我所使用的系统为内核版本:2.6.10  在/home/tmp/下建立两个文件hello.c,Makefile  hello.c  ------------  #include  #include  #include  MODULE_...
  • 如果预设核心忘记加入某个功能,而且该功能可以编译成为模块,不过, 预设核心却也没有将该项功能编译成为模块,不能使用时,该如何是好?如果 Linux 核心原始码并...本文将为大家解析Linux系统单一内核模块编译过程。
  • 内核模块编译--Makefile写法

    千次阅读 2018-10-23 19:07:00
    内核模块编译-Makefile写法 如果编译内核模块,可以编写Makefile,然后执行make命令即可。 Linux2.6的Makefile模板如下: #Makefile2.6 ifneq ($(KERNELRELEASE),) #kbuild syntax. dependency relationship of...

    内核模块编译-Makefile写法

    如果编译内核模块,可以编写Makefile,然后执行make命令即可。

    Linux2.6的Makefile模板如下:

    #Makefile2.6

    ifneq ($(KERNELRELEASE),)

    #kbuild syntax. dependency relationship of files and target modules are listed here.

    mymodule-objs := file1.o file2.o

    obj-m := mymodule.o

    else

    PWD := $(shell pwd)

    KVER := &(shell uname -r)

    KDIR := /lib/modules/$(KVER)/build

    all:

        $(MAKE)   -C  $(KDIR)  M=$(PWD)
    

    clean:

         rm -rf   *.*.cmd  *.o  *.mod.c *.ko .tmp_versions
    

    endif

    注意:

    1.ifneq 后面有空格。

    2.命令前面必须使用tab键,如&(MAKE)和rm 的前面。

    3.Makefile必须和相应的.c文件放在同一个目录下。

    代码解释:

    (1) ifneq ($(KERNELRELEASE),)

    KERNELRELEASE是在内核源码的顶层Makefile中定义的一个变量,当第一次执行这个Makefile时,KERNELRELEASE没有被定义,所以会执行else后面的内容。

    (2)PWD:=$(shellpwd)

    可以把shell脚本写到Makefile里面,这句话的意思:执行shell脚本命令pwd(pwd是显示当前目录的路径),把返回值赋给PWD这个变量,所以PWD存的就是当前目录的路径。

    (3)KVER:=$(shell uname -r)

    执行shell脚本命令:uname-r,这个命令的作用是显示当前内核版本(kernelreleaes),所以变量KVER的内容是当前系统kernelrelease.

    (4)KDIR:=/lib/modules/$(KVER)/build,DIR指定了内核源码的路径.

    (5)all:

        $(MAKE) -C $(KDIR)  M=$(PWD)  #前面必须是tab。
    

    这里all只是个标号,可以自己定义,是make的默认执行目标。

    ( M A K E ) : M A K E 是 M a k e f i l e 中 的 宏 变 量 , 要 引 用 宏 变 量 要 使 用 符 号 (MAKE):MAKE是Makefile中的宏变量,要引用宏变量要使用符号 (MAKE):MAKEMakefile使。这里实际上就是指向make程序,所以这里也可以把$(MAKE)换成make.

    -C:是make命令的一个选项,-C作用是changedirectory. -C dir 就是转到dir目录。

    M=$(PWD):返回当前目录。

    这句话的意思是:当make执行默认的目标all时,-C ( K V D I R ) 指 明 跳 转 到 内 核 源 码 目 录 下 去 执 行 那 里 的 M a k e f i l e , M = (KVDIR)指明跳转到内核源码目录下去执行那里的Makefile,M= (KVDIR)Makefile,M=(PWD)表示又返回到当前目录来执行当前的Makefile.

    (6)当从内核源码目录返回时,再次执行这个Makefile时,KERNELRELEASE已经被定义过,这次 ifneq ($(KERNELRELEASE),)条件判断成立,就会执行后面的内容。ifneq之后else之前的内容为kbuild语法的语句,指明模块源码中各模块间的依赖关系,以及要生成的模块的名称。

    (7)mymodule_objs:=file1.ofile2.o

    表明mymodule.o由file1.和file2.o链接生成

    (8)obj-m:=mymodule.o

    编译链接后要生成mymodule.o模块。obj-m表示以模块编译,obj-y表示编译并链接进内核. mymodule这个是模块名字。

    注:如果模块就由一个文件编译而成,可写为:obj-m:=mymodule.o。(必须与mymodule.c名字对应,都是mymodule。上面的file1.ofile2.o也如此)

    (9)clean:

       rm -rf   *.*.cmd  *.o  *.mod.c *.ko .tmp_versions
    

    在命令行中输入:make,只会执行(1)到(8)的指令,不会执行clean标号之后的指令。要想执行clean标号后面的指令,需要在命令行中输入:makeclean

    rm 就是删除后面这些由make生成的文件。一般如果需要重新执行make编译之前,使用make clean先清理上次生成的文件。

    如果想删除make生成的所有文件,也可以使用下面方式:

    clean:

      $(MAKE) -C $(KDIR) M=$(PWD)clean
    

    或者

    clean:

     make-C $(KDIR) M=$(PWD)clean
    

    一个简单的Makefile例子(为《内核模块程序机构》中hello.c编写的)

    //Makfile

    ifneq ($(KERNELRELEASE),)

    #kbuildsyntax. dependency relationshsip of files and target modules arelisted here.

    #mymodule-objs:= file1.o file2.o

    obj-m:= hello.o

    else

    PWD := $(shell pwd)

    KVER:= $(shell uname -r)

    KDIR:= /lib/modules/$(KVER)/build

    all:

       $(MAKE)-C $(KDIR) M=$(PWD)
    

    clean:

       $(MAKE)-C $(KDIR) M=$(PWD) clean
    

    endif

    作者:Thinker_mhy
    来源:CSDN
    原文:https://blog.csdn.net/miaohongyu1/article/details/8877497
    版权声明:本文为博主原创文章,转载请附上博文链接!

    展开全文
  • Linux2.6内核模块编译Makefile[归类].pdf
  • Linux 2.6 下内核模块的Makefile  # Makefile 2.6  obj-m += hello.o  KDIR:=/lib/modules/$(shell uname -r)/build  # PWD=$(shell pwd)  all:  make -C $(KDIR) M=$(PWD) modules  clean:  make -...
  • 如何将内核模块编译进linux内核

    千次阅读 2020-01-25 18:01:35
    下面我们来做一个实例,实例的目的是编写一个简单的内核模块,然后把该模块编译进S3C6410开发板的内核中,并运行。 1、内核模块的代码hello.c如下所示。 #include <linux/module.h> #include <linux/...

          linux系统的内核模块,在编好之后,可以通过insmod命令安装到系统中,也可以将模块直接编译进内核。

    下面我们来做一个实例,实例的目的是编写一个简单的内核模块,然后把该模块编译进S3C6410开发板的内核中,并运行。

    1、内核模块的代码hello.c如下所示。

    #include <linux/module.h>
    #include <linux/init.h>
     
    static int __init hello_init(void)
    {
    	printk(KERN_EMERG "Hello world!\n");
    	return 0;
    }
     
    static void __exit hello_exit(void)
    {
    	printk(KERN_EMERG "hello exit\n");
    }
     
    module_init(hello_init);
    module_exit(hello_exit);

    2、将hello.c加入到内核源码中

         我们把hello.c当做字符设备驱动,加入到内核源码的 drivers/char/路径下。在这个文件夹下,保护了内核所有字符设备的驱动源码。

    3、修改Kconfig文件。

         在内核源码的 drivers/char/路径下打开 Kconfig文件,加入hello相关的条目,如下所示。

    #
    # Character device configuration
    #
    
    menu "Character devices"
    
    config HELLO_WORLD
    	bool "hello"
    
    config VT
    	bool "Virtual terminal" if EXPERT
    	depends on !S390
    ....................................

    Kconfig文件的修改的作用是改变内核配置的菜单。

    4、修改Makefile文件

      在内核源码的 drivers/char/路径下打开 Makefile文件,加入hello相关的条目,如下所示。

    #
    # Makefile for the kernel character device drivers.
    #
    
    obj-$(CONFIG_HELLO_WORLD)       +=hello.o
    obj-y				+= mem.o random.o
    obj-$(CONFIG_TTY_PRINTK)	+= ttyprintk.o
    obj-y				+= misc.o

    Makefile文件的修改的作用是把hello.o编译进内核里。

    5、配置内核

            在内核源码文件夹下,执行下面命令

    make menuconfig ARCH=arm

    在Device Drivers选项下的Character devices选项下,可以找到名字为hello的选项,按空格键,将该选项选中,如下图所示。

    配置好之后,在内核源码文件夹下的.config文件中,可以看到hello相关的条目,如下所示。

    #
    # Character devices
    #
    CONFIG_HELLO_WORLD=y
    CONFIG_VT=y
    CONFIG_CONSOLE_TRANSLATIONS=y
    CONFIG_VT_CONSOLE=y
    CONFIG_HW_CONSOLE=y

    可以看到,已经将CONFIG_HELLO_WORLD选中。

    6、编译内核

    用下面的命令编译内核

    make uImage ARCH=arm CROSS_COMPILE=arm-linux-

    编译之后在源码文件夹下的  arch/arm/boot/文件夹下,可以看到uImage文件夹。

    7、验证

    将新生成的uImage文件烧写到开发板中,重启开发板,在开发板终端的启动信息中,可以看到hello模块初始化过程打印的Hello world!

     

    展开全文
  • 内核模块编译

    千次阅读 2015-06-19 16:39:32
    一.Linux内核介绍 1.Linux 内核很庞大,相应的包含的组件也非常多。...即内核模块机制。3.关于内核模块。有以下特征: (1)不被编译进内核文件 (2)可以动态加载和卸载4.关于内核模块的操作 (1)加载in
  • Linux内核模块编译出错问题解决

    千次阅读 2019-04-23 15:19:35
    在对内核模块进行编译时出现以下错误 出现该问题是由于没有指定架构和编译器造成的首先看下内核模块编译过程 编译内核模块的Makefile举例如下 ifneq($(KERNELRELEASE),) obj-m:=hello.o else ...
  • Linux内核模块编译

    千次阅读 2018-07-25 19:12:52
    如果没有内核模块,需要向内核添加功能就需要自发代码、重新编译内核、安装新内核等步骤。 内核空间中不止一个程序试图访问驱动程序模块,导致一个内核块在没有被调用完毕之前又被其他程序调用,这称之炒代码的重入...
  • (1)当模块被载入内核时会向系统日志文件中写入“hello,world”;当被卸载时,会向系统写入“goodbye”。 (2)设计一个模块,要求列出系统中所有内核线程的程序名、PID、进程状态、进程优先级、父进程的PID。 ...
  • linux内核模块编译

    千次阅读 2017-09-01 23:39:12
    最近在学习linux内核模块,在初次编译时遇到了不少坑,下面是完整的内核模块编译流程。 写了一个简单的hello_world.c文件作为内核模块学习的第一步,代码如下: #include #include static int __init hello...
  • 内核模块编译 makefile入门

    千次阅读 2017-12-19 10:37:29
    一、模块编译  我们在前面内核编译中驱动移植那块,讲到驱动编译分为静态...静态编译即为将驱动直接编译内核,动态编译即为将驱动编译模块。 而动态编译又分为两种: a -- 内部编译  在内核源码目录内编译
  • 如果想要在Linux内核上扩展功能,有两条路可选,一是将自己的模块编译进Kernel,使模块成为内核的一部分;一是以模块的方式供内核加载。
  • Android内核模块编译执行

    千次阅读 2017-02-24 23:03:04
    本文以一个“hello”驱动为例,简单介绍内核驱动编写、编译的基本过程,包括内核模块的内建编译和动态加载方式的编译。 0X02 编写 在./goldsifh/drivers文件夹下新建hello目录,在hello目录中新建hello.c文
  • Linux内核模块编译 ----Makefile 模板 在Linux 2.6内核中,模块的编译需要配置过的内核源代码;编译过程首先会到内核源码目录下读取顶层的Makefile文件,然后再返回模块源码所在目录;经过编译、...
  • 如何编译Linux 内核模块

    万次阅读 2018-11-03 09:44:58
    ubuntu版本:ubuntu-gnome-16.04-desktop-amd64,gnome版 ---------------------------------------------------------...本文主要介绍如何在内核外编译内核模块,即: how to build an out-of-tree kernel module...
  • 内核模块编译常见问题

    千次阅读 2018-04-15 14:45:35
    我使用的硬件平台是exynos4412,内核版本是3.14 0、卸载模块提示找不到相关目录 收到创建缺少的目录,再重新卸载就可以了 1、显示文件修改时间在未来 make编译的时候出现如下图片: 原因:源代码修改时间和...
  • Linux学习记录--内核|内核模块编译

    千次阅读 2014-04-09 21:14:05
    内核|内核模块编译 (对于内核的知识觉得了解不够,等学习完LFS再来详细整理下这方面的知识)   内核:系统上面的一个文件,这个文件包含了驱动主机各项硬件的检测程序和驱动模块。   计算机真正工作的是硬件,...
  • 大纲: 1.交叉编译环境搭建 2.内核模块的编写 3.将开发板连接上PC串口测试,加载模块 4.内核模块参数 5.总结
  • ubuntu下编译自定义内核模块

    千次阅读 2019-07-15 09:23:37
    ubuntu下编译自定义内核模块 内核模块是Linux内核向外部提供的一个插口,其全称为动态可加载内核模块(Loadable Kernel Module,LKM),我们简称为模块。Linux内核之所以提供模块机制,是因为它本身是一个单内核...
  • 树莓派3B 内核模块编译

    千次阅读 2016-12-27 21:59:19
    编译内核模块需要kernel-headers。输入命令sudo apt-cache search kernel-headers,搜索合适的kernel-headers。结果如下: raspberrypi-kernel-headers - Header files for the Raspberry Pi Linux kernel ...
  • 代码编译内核编译模块在代码中有什么区别呢?  从模块的代码中看是一样的。入口函数都是module_init(fun),但是代码中的条件编译会使宏module_init()在编译内核编译模块的情况下替换成不同的代码。 ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 150,813
精华内容 60,325
关键字:

内核模块编译

友情链接: G-2-16-65-81sanwei222.zip