Dai*_*aiz 4 c xilinx embedded-linux buildroot
我目前正在为Xilinx的Zybo Board构建嵌入式Linux.为此,我使用Buildroot.现在我想添加一个用C语言编写的驱动程序,用户程序可以使用该驱动程序写入某些特定的寄存器,使其能够控制某些LED.当我查看手册时,基本上说首先要做的是在新的包文件夹中创建一个Config.in,在那里你可以写一些解释驱动程序的文本.好的,我做到了.但是现在makefile:我不太明白那里需要什么.它只是一个编译命令gcc -o ledcontrol hellofunc.c吗?除了Config.in和Makefile之外,我还需要做些什么吗?
完全自动化的树外QEMU示例
来源树:
buildroot/:Buildroot 2017.02子模块kernel_module/:带有一些模块的外部包
Config.inexternal.mkMakefilehello.c:你好世界模块kernel_module/Config.in:
config BR2_PACKAGE_KERNEL_MODULE
bool "kernel_module"
depends on BR2_LINUX_KERNEL
help
Linux Kernel Module Cheat.
Run Code Online (Sandbox Code Playgroud)
kernel_module/external.mk:
KERNEL_MODULE_VERSION = 1.0
KERNEL_MODULE_SITE = $(BR2_EXTERNAL_KERNEL_MODULE_PATH)
KERNEL_MODULE_SITE_METHOD = local
$(eval $(kernel-module))
$(eval $(generic-package))
Run Code Online (Sandbox Code Playgroud)
kernel_module/Makefile文件:
obj-m += $(addsuffix .o, $(notdir $(basename $(wildcard $(BR2_EXTERNAL_KERNEL_MODULE_PATH)/*.c))))
ccflags-y := -DDEBUG -g -std=gnu99 -Wno-declaration-after-statement
.PHONY: all clean
all:
$(MAKE) -C '$(LINUX_DIR)' M='$(PWD)' modules
clean:
$(MAKE) -C '$(LINUX_DIR)' M='$(PWD)' clean
Run Code Online (Sandbox Code Playgroud)
kernel_module/hello.c中:
#include <linux/module.h>
#include <linux/kernel.h>
MODULE_LICENSE("GPL");
static int myinit(void)
{
printk(KERN_INFO "hello init\n");
return 0;
}
static void myexit(void)
{
printk(KERN_INFO "hello exit\n");
}
module_init(myinit)
module_exit(myexit)
Run Code Online (Sandbox Code Playgroud)
用法:
cd buildroot
make BR2_EXTERNAL="$(pwd)/../kernel_module" qemu_x86_64_defconfig
echo 'BR2_PACKAGE_KERNEL_MODULE=y' >> .config
make BR2_JLEVEL="$(($(nproc) - 2))" all
qemu-system-x86_64 -M pc -kernel output/images/bzImage -drive file=output/images/rootfs.ext2,if=virtio,format=raw -append root=/dev/vda -net nic,model=virtio -net user
Run Code Online (Sandbox Code Playgroud)
QEMU打开,然后运行:
root
modprobe hello
modprobe -r hello
Run Code Online (Sandbox Code Playgroud)
dmesg 说明:
hello init
hello exit
Run Code Online (Sandbox Code Playgroud)
关键线路$(eval $(kernel-module))中external.mk,这对我们完成所有设置,并安装模块,其中modprobe会发现他们(/lib/modules/*/extra/hello.ko),包括modules.dep模块间的依赖关系:如何调用导出的内核模块的功能从另一个模块?
如何GDB步骤调试内核模块:如何使用QEMU调试Linux内核模块?
要在启动时自动加载模块,请使用BR2_ROOTFS_OVERLAY="../rootfs_overlay"和执行该操作的rootfs_overlay/etc/init.d/S99modules文件modprobe.
树内例子:https://github.com/cirosantilli/buildroot/tree/9580078b98f885ca94e4dfc896265a8a491f6ae1它不太干净,但也有效.
在Ubuntu 16.04主机上测试.
您正在寻找的是内核模块基础架构.您可以在这里查看Buildroot手册:
或者在使用Buildroot提供的内核模块基础结构的众多示例中,它们帮助内核模块添加到Buildroot:
$ git grep "(kernel-module)" -- package/
package/amd-catalyst/amd-catalyst.mk:$(eval $(kernel-module))
package/batman-adv/batman-adv.mk:$(eval $(kernel-module))
package/cryptodev-linux/cryptodev-linux.mk:$(eval $(kernel-module))
package/emlog/emlog.mk:$(eval $(kernel-module))
package/freescale-imx/kernel-module-imx-gpu-viv/kernel-module-imx-gpu-viv.mk:$(eval $(kernel-module))
package/igh-ethercat/igh-ethercat.mk:$(eval $(kernel-module))
package/iqvlinux/iqvlinux.mk:$(eval $(kernel-module))
package/ktap/ktap.mk:$(eval $(kernel-module))
package/linux-backports/linux-backports.mk:$(eval $(kernel-module))
package/lttng-modules/lttng-modules.mk:$(eval $(kernel-module))
package/nvidia-driver/nvidia-driver.mk:$(eval $(kernel-module))
package/ocf-linux/ocf-linux.mk:$(eval $(kernel-module))
package/on2-8170-modules/on2-8170-modules.mk:$(eval $(kernel-module))
package/owl-linux/owl-linux.mk:$(eval $(kernel-module))
package/pkg-kernel-module.mk:# $(eval $(kernel-module))
package/pkg-kernel-module.mk:# $(eval $(kernel-module))
package/rtl8188eu/rtl8188eu.mk:$(eval $(kernel-module))
package/rtl8821au/rtl8821au.mk:$(eval $(kernel-module))
package/simicsfs/simicsfs.mk:$(eval $(kernel-module))
package/sysdig/sysdig.mk:$(eval $(kernel-module))
Run Code Online (Sandbox Code Playgroud)
是的,我想我可以写一个很长的回复,但我只是复制Buildroot手册.因此,让我们尊重勇敢的开发人员,他们已经编写了如此简洁的文档和如此简洁的代码(Buildroot核心非常干净,每个软件包都经过了广泛的审核,所以它们通常写得非常好).