网站页面设计具体步骤,隧道建设期刊网站进不去,河南建设工程信息网电话,国外优秀的网站设计文章目录 模块实现编译模块的 makefile编译报错解决模块编译日志自动化模块安装模块卸载配置头文件路径 模块实现
新建 my_module.c 文件
#include linux/types.h
#include linux/kernel.h
#include linux/init.h
#include linux/module.hst… 文章目录 模块实现编译模块的 makefile编译报错解决模块编译日志自动化模块安装模块卸载配置头文件路径 模块实现
新建 my_module.c 文件
#include linux/types.h
#include linux/kernel.h
#include linux/init.h
#include linux/module.hstatic int __init module_base_init(void)
{printk(base module init!\r\n);return 0;
}static void __exit module_base_exit(void)
{printk(base module exit!\r\n);
}module_init(module_base_init);
module_exit(module_base_exit);MODULE_LICENSE(GPL);
MODULE_AUTHOR(tyustli);
编译模块的 makefile
新建 Makefile 文件
# 指定内核路径
KERNELDIR : /home/tyustli/code/open_source/kernel/linux-6.5.7
# 指定当前路径
CURRENT_PATH : $(shell pwd)
# 指定编译的模块名
obj-m : my_module.obuild: kernel_moduleskernel_modules:$(MAKE) -C $(KERNELDIR) M$(CURRENT_PATH) modules
clean:$(MAKE) -C $(KERNELDIR) M$(CURRENT_PATH) clean编译报错解决
此时如果直接在模块路径执行 make 会有 如下警告和报错cc1: error: cannot load plugin ./scripts/gcc-plugins/arm_ssp_per_task_plugin.so: ./scripts/gcc-plugins/arm_ssp_per_task_plugin.so: undefined symbol: _Z16gen_load_tp_hardP7rtx_def
完整日志如下
make -C /home/tyustli/code/open_source/kernel/linux-6.5.7 M/home/tyustli/code/qemu_code/linux_driver/0001_module_init modules
make[1]: Entering directory /home/tyustli/code/open_source/kernel/linux-6.5.7
warning: the compiler differs from the one used to build the kernelThe kernel was built by: arm-none-linux-gnueabihf-gcc (GNU Toolchain for the A-profile Architecture 10.3-2021.07 (arm-10.29)) 10.3.1 20210621You are using: gcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0CC [M] /home/tyustli/code/qemu_code/linux_driver/0001_module_init/my_module.o
cc1: error: cannot load plugin ./scripts/gcc-plugins/arm_ssp_per_task_plugin.so: ./scripts/gcc-plugins/arm_ssp_per_task_plugin.so: undefined symbol: _Z16gen_load_tp_hardP7rtx_def
make[3]: *** [scripts/Makefile.build:243: /home/tyustli/code/qemu_code/linux_driver/0001_module_init/my_module.o] Error 1
make[2]: *** [/home/tyustli/code/open_source/kernel/linux-6.5.7/Makefile:2037: /home/tyustli/code/qemu_code/linux_driver/0001_module_init] Error 2
make[1]: *** [Makefile:237: __sub-make] Error 2
make[1]: Leaving directory /home/tyustli/code/open_source/kernel/linux-6.5.7
make: *** [Makefile:11: kernel_modules] Error 2这是因为前面编译内核的时候 ARCH 和 CROSS_COMPILE 是通过 shell 脚本传进去的编译模块的时候又没有指定这些。
解决方法就是在内核顶层的 Makefile 直接定义这两个变量(有点粗暴)
ARCH arm
CROSS_COMPILE arm-none-linux-gnueabihf-模块编译日志
make -C /home/tyustli/code/open_source/kernel/linux-6.5.7 M/home/tyustli/code/qemu_code/linux_driver/0001_module_init modules
make[1]: Entering directory /home/tyustli/code/open_source/kernel/linux-6.5.7CC [M] /home/tyustli/code/qemu_code/linux_driver/0001_module_init/my_module.oMODPOST /home/tyustli/code/qemu_code/linux_driver/0001_module_init/Module.symversCC [M] /home/tyustli/code/qemu_code/linux_driver/0001_module_init/my_module.mod.oLD [M] /home/tyustli/code/qemu_code/linux_driver/0001_module_init/my_module.ko
make[1]: Leaving directory /home/tyustli/code/open_source/kernel/linux-6.5.7自动化
模块编译好之后最好的方法就是将 rootfs 设置为 nfs这样直接将编译的 ko 放到网络文件系统中直接启动内核即可。
由于目前使用的是 ubuntu wifi 的形式如果想让 qemu 联网需要建立网桥但是 wifi 网卡没有处于 AP 模式处于 Managed 模式的无线网卡没有足够多的信息做网桥只能转换成 master 模式
iwconfig wlp2s0 mode master结果网卡不支持
Error for wireless request Set Mode (8B06) :SET failed on device wlp2s0 ; Operation not permitted.只能通过软件 hostapd 来实现。。。。。。
这个有点复杂超出了研究 linux driver 的目的。
解决方法就是每次生成 xxx.ko 之后将生成的 ko 文件拷贝到根文件目录下然后重新打包 rootfs 根文件系统。这样 linux 启动之后模块就在 rootfs 根文件系统中
# 将生成的 .ko 文件拷贝到根文件系统的 roorfs 中
cp ./my_module.ko /home/tyustli/code/open_source/busybox/rootfs/dev# 切换到根文件系统目录
cd /home/tyustli/code/open_source/busybox
# 生成虚拟 SD 卡系统镜像
sudo dd if/dev/zero ofrootfs.ext3 bs1M count32
# 格式化镜像
sudo mkfs.ext3 rootfs.ext3#将文件复制到镜像中
sudo mkdir tmpfs_rootfs
sudo mount -t ext3 rootfs.ext3 tmpfs_rootfs/ -o loop
sudo cp -r rootfs/* tmpfs_rootfs/
sudo umount tmpfs_rootfs
rmdir tmpfs_rootfs这里 rootfs 就制作好了重新启动 linux
sudo qemu-system-arm -M vexpress-a9 -m 512M \
-kernel /home/tyustli/code/open_source/kernel/linux-6.5.7/arch/arm/boot/zImage \
-dtb /home/tyustli/code/open_source/kernel/linux-6.5.7/arch/arm/boot/dts/arm/vexpress-v2p-ca9.dtb -nographic \
-append root/dev/mmcblk0 rw consolettyAMA0 \
-sd /home/tyustli/code/open_source/busybox/rootfs.ext3脚本源码
# 参数解析
# ./my_module_build.sh para1 para2(可选)
# 脚本名称 指定模块路径 是否执行 make clean 命令# 判断 shell 脚本有几个参数如果没有指定 module 目录 shell 脚本就报错退出
if [ $# -eq 0 ]; thenecho Incorrect number of arguments for command
Usage: my_module_build.sh module_dir build your own moduleexit
fi# 切换到指定的目录
cd $1# 如果是清除工程就执行 make clean 命令
if [ $2 clean ]; thenmake cleanexit
fi# 编译指定目录的模块
make
# 将生成的 .ko 文件拷贝到根文件系统的 roorfs 中
cp ./my_module.ko /home/tyustli/code/open_source/busybox/rootfs/dev# 切换到根文件系统目录
cd /home/tyustli/code/open_source/busybox
# 生成虚拟 SD 卡系统镜像
sudo dd if/dev/zero ofrootfs.ext3 bs1M count32
# 格式化镜像
sudo mkfs.ext3 rootfs.ext3#将文件复制到镜像中
sudo mkdir tmpfs_rootfs
sudo mount -t ext3 rootfs.ext3 tmpfs_rootfs/ -o loop
sudo cp -r rootfs/* tmpfs_rootfs/
sudo umount tmpfs_rootfs
rmdir tmpfs_rootfs# 切换回指定的目录
cd $1# 启动 kernel
sudo qemu-system-arm -M vexpress-a9 -m 512M \
-kernel /home/tyustli/code/open_source/kernel/linux-6.5.7/arch/arm/boot/zImage \
-dtb /home/tyustli/code/open_source/kernel/linux-6.5.7/arch/arm/boot/dts/arm/vexpress-v2p-ca9.dtb -nographic \
-append root/dev/mmcblk0 rw consolettyAMA0 \
-sd /home/tyustli/code/open_source/busybox/rootfs.ext3用法
./my_module_build.sh 0001_module_init/模块安装
查看模块文件是否存在
ls /dev/my_module.ko 模块安装
/dev/my_module.kobase module init 和 module_base_init 打印的信息一致
模块卸载
rmmod my_modulebase module exit 和 module_base_exit 打印的信息一致
配置头文件路径
在 my_module.c 文件中使用 #include 包含了一些内核的头文件那么这些头文件如何跳转可以借助 C/C 插件
Ctrl Shift p 输入 C/C:Edit Configurations(JSON)在当前路径下会自动新建一个 .vscode 文件并生成 c_cpp_properties.json在文件中输入
{configurations: [{name: Linux,includePath: [${workspaceFolder}/**,/home/tyustli/code/open_source/kernel/linux-6.5.7/include,/home/tyustli/code/open_source/kernel/linux-6.5.7/include/uapi,/home/tyustli/code/open_source/kernel/linux-6.5.7/arch/arm/include,/home/tyustli/code/open_source/kernel/linux-6.5.7/arch/arm/include/generated,/home/tyustli/code/open_source/kernel/linux-6.5.7/arch/arm/include/generated/uapi],defines: [],compilerPath: /home/tyustli/cross_tool/gcc-arm-10.3-2021.07-x86_64-arm-none-linux-gnueabihf/bin/arm-none-linux-gnueabihf-gcc,cStandard: c17,cppStandard: gnu17,intelliSenseMode: linux-gcc-arm}],version: 4
}这样配置之后头文件可以正常跳转
同样可以在 .vscode 生成 settings.json 文件在其中输入
{search.exclude: {**/node_modules: true,**/bower_components: true,**/*.su:true,Documentation:true,},files.exclude: {**/.git: true,**/.svn: true,**/.hg: true,**/CVS: true,**/.DS_Store: true,**/*.su:true,Documentation:true,},files.associations: {map.h: c,module.h: c,init.h: c,types.h: c,kernel.h: c,kobject.h: c,sysfs.h: c,kernfs.h: c,idr.h: c,radix-tree.h: c,xarray.h: c,mm.h: c,sched.h: c,seccomp.h: c,*.tcc: c,compiler_attributes.h: c}
}