linux-内核-x86内核模块加载

大纲:
1.内核模块简介
2.内核模块编译和加载的过程
一.什么叫内核模块(linux如何使用需要的组件呢?)
把所有的组件都编译进内核文件,即zimage或者bzimage,会导致:生成内核文件过大;如果要添加或者删除某个组件,需要重新编译整个内核
让内核文件(即zimage或者bzimage)本身不包含这些组件,而是该组件需要被使用的时候进行动态的添加到正在运行的内核中,叫内核模块机制。
二.内核模块特点
1)本身并不被编译进内核文件
2)根据需求在内核运行期间动态安装或者卸载
Linux内核模块可以通过静态或动态的方法加载到内核空间,静态加载是指在内核启动过程中加载;动态加载是指在内核运行的过程中随时加载。
三.一个源文件的内核模块的Makefile文件
一个helloworld.c内核模块实例

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>

static int hello_init(void){
    printk(KERN_WARNING"hello world!\n");
    return 0;
    }
static void hello_exit(void){
    printk(KERN_INFO"Goodbye world!\n");
    }   
module_init(hello_init);
module_exit(hello_exit);   

Makefile文件(使用的时候改一下tab键)

KERNELDIR :=/lib/modules/4.4.0-31-generic/build

PWD :=$(shell pwd)

all:
    $(MAKE) -C $(KERNELDIR) M=$(PWD) modules  

modules_install:
    $(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install

clean:
    rm -rf *.o *.ko *.mod.c *.order *.mod.o *.symvers

obj-m:=helloworld.o

Makefile文件讲解
1.KERNELDIR的路径是x86系统内核源码自带的modules去编译
内核版本的查询uname -r
2.PWD表示当前目录的路径
3.行首空格必须用Tab键打出
4.$(MAKE) -C表示进入KERNELDIR路径里面的Makefile进行编译
5.M表示内核模块的目录
6.obj-m必须和源c文件文件名称一致
运行结果:
这里写图片描述
四.多个内核模块的编译

add.c文件如下
int add(int a,int b){
    return a+b;
    }

main.c文件如下
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
extern int add(int a,int b);
static int _init hello_init(void){
    printk(KERN_WARNING"hello world!\n");
    add(1,2);
    return 0;
    }
static void _exit hello_exit(void){
    printk(KERN_INFO"Goodbye world!\n");
    }   
module_init(hello_init);
module_exit(hello_exit);

Makefile文件

KERNELDIR :=/lib/modules/4.4.0-31-generic/build

PWD :=$(shell pwd)

all:
    $(MAKE) -C $(KERNELDIR) M=$(PWD) modules  

modules_install:
    $(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install

clean:
    rm -rf *.o *.ko *.mod.c *.order *.mod.o *.symvers

obj-m:=mymodule.o
mymodule-objs:=main.o add.o

五.模块的安装和卸载
加载insmod
卸载rmmod(每次用完这个模块需要卸载)
查看lsmod
还有一种加载的方式是modprobe会跟据/lib/modules/<$version>/modules.dep来查看要加载的模块,看到它是否依赖于其他模块
如果是modprobe会首先找到这些模块,把他们先加载到内核
六.模块参数
通过宏module_param指定模块参数,模块参数用于在加载模块时候传递参数给模块
module_param(name,type,perm)
name:模块参数名称
type:这个参数的类型
perm:模块参数的访问权限
S_IRUGO 任何用户对于/sys/module中出现的该参数具有读权限
S_IWUSR 允许root用户修改/sys/module中出现的该参数
例:
int a=3;
char *st=”coco”;
module_param(a,int,S_IWUSR);
module_param(st,char,S_IWUSR);
模块加载的时候直接insmod hello.o 输出的是默认参数
模块加载的时候直接insmod hello.o a=4 输出的是新的参数
七.内核符号到处
为什么要内核导出:一个模块中的函数想要被其他模块使用必须要先导出,执行的时候要先执行被导出的模块的.ko文件
导出函数 EXPORT_SYMBOL(函数名)

总结:
1.应用程序是从main函数从头到尾的执行任务,执行结束后在内存中消失;
内核模块是在内核中先注册自己以便服务将来的某个请求,然后他的初始化函数结束,此时模块仍然存在于内核中,直到卸载函数被调用,模块才从内核中消失
2.printk在内核中使用,printf在应用程序中使用
printk的优先级
KERN_EMERG>KERN_ALERT>KERN_CRIT>KERN_ERR>KERN_WARNING>KERN_NOTICE>KERN_INFO>KERN_DEBUG
<0> <1> <2> <3> <4> <5> <6> <7>
3.内核版本的查询uname -r,所依赖的内核代码版本必须和当前内核运行版本一致

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
编译 Linux 内核需要以下步骤: 1. 获取 Linux 内核源代码。你可以从官方网站或 GitHub 上下载最新的内核源代码。 2. 安装交叉编译工具链。如果你的开发环境是 x86 架构的,你需要安装交叉编译工具链来编译适用于 ARM 架构的内核。你可以使用 apt-get 命令或其他包管理器来安装工具链。例如,在 Ubuntu 或 Debian 上,你可以使用以下命令来安装: ``` sudo apt-get install gcc-arm-linux-gnueabihf ``` 3. 配置内核。进入内核源代码目录,使用以下命令来配置内核: ``` make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- orangepi_zero2_defconfig ``` 这将使用默认配置文件来配置内核。 4. 编译内核。使用以下命令来编译内核: ``` make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- zImage dtbs modules ``` 这将编译内核镜像、设备树和内核模块。 5. 安装内核。将编译好的内核镜像和设备树文件复制到 SD 卡的 boot 分区中。例如,在 Ubuntu 或 Debian 上,你可以使用以下命令来安装: ``` sudo cp arch/arm/boot/zImage /media/boot/ sudo cp arch/arm/boot/dts/sun8i-h2-plus-orangepi-zero2.dtb /media/boot/ ``` 6. 配置引导加载程序。编辑 SD 卡的 boot 分区中的 boot.cmd 文件,并添加以下内容: ``` setenv bootargs console=ttyS0,115200 root=/dev/mmcblk0p2 rootwait panic=10 fatload mmc 0:1 ${kernel_addr_r} zImage fatload mmc 0:1 ${fdt_addr_r} sun8i-h2-plus-orangepi-zero2.dtb bootz ${kernel_addr_r} - ${fdt_addr_r} ``` 这将配置引导加载程序以加载内核镜像和设备树,并指定内核参数。 7. 生成引导加载程序镜像。使用以下命令来生成引导加载程序镜像: ``` mkimage -C none -A arm -T script -d boot.cmd boot.scr ``` 这将生成一个名为 boot.scr 的文件,它是引导加载程序镜像。 8. 将引导加载程序镜像复制到 SD 卡的 boot 分区中: ``` sudo cp boot.scr /media/boot/ ``` 9. 将 SD 卡插入 Orange Pi Zero 2 开发板,并启动板子。如果一切正常,你应该看到内核启动信息在串口终端中输出。 注意:这只是一个简单的指南,实际的操作可能会因环境和设备而有所不同。请确保你熟悉 Linux 内核编译和 Orange Pi Zero 2 开发板的使用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值