以下是整理的笔记
1. 驱动是内核代码的一部分,怎么将驱动代码融入到内核?
1.1 内核的编译及配置
a. cp mini2451_jsetc_config .config
make menuconfig
b. 修改源码根目录下的主Makefile (大概190多行处)
ARCH = arm
CROSS_COMPILE = arm-linux-
c. make uImage
如果没有mkimage工具,需要将mkimage拷贝到 /usr/sbin下
d. 编译完成后
在arch/arm/boot下就要编译好的内核压缩文件 uImage
1.2 Linux内核源码结构
|---arch/ 硬件架构相关代码,Linux系统支持不同cpu架构
|---mach-xxx 具体某款soc的支持代码(比如s3c24xx对应mach-s3c24xx目录)
|---drivers Linux内核的驱动库,按类别分目录管理
1.3 驱动的静态编译(编译链接进uImage)
(1) 将驱动源码部署在drivers下的某个目录(drivers/char/jsetc_driver.c)
(2) 修改对应目录下的Makefile (drivers/char/Makefile)
obj-y += jsetc_driver.o
(3) 重新编译内核
make uImage
1.4 举例说明内核配置原理(参考kernel_demo_v3)
(1) 通常会把一些功能选项写成配置开关(#define CONFIG_ADC),
放在config.h中,源码include此头文件,从而决定对用功能是否应用。
(2) 通过定义一些编译的开关(CONFIG_ADC=y),放在一个配置文件中(.config),
此配置文件被Makefile include,从而决定编译哪个目录以及编译哪个文件
1.5 在Linux内核中加入可配置的代码
(通过menuconfig将对应的代码编译进或者是移除内核)
(1) 将源码(驱动)放在某个目录,(drivers/char)
(2) 修改对应目录的Makefile,将源码部署进来 (drivers/char/Makefile)
同时引入配置开关
obj-$(CONFIG_JSETC_DRIVER)+= jsetc_driver.o
配置开关CONFIG_JSETC_DRIVER是否为y,决定jsetc_driver.c是否编译链接进内核
(3)定义CONFIG_JSETC_DRIVER,并在menuconfig中体现出来
修改对应目录的Kconfig,(drivers/char/Kconfig)
config JSETC_DRIVER
bool "jsetc driver"
default y //select depend on CONFIG_LED
help
"just for test"
通过menuconfig的配置,可以将CONFIG_JSETC_DRIVER赋值(CONFIG_JSETC_DRIVER=y),
最后保存在源码根目录.config中,.config会被导出到整个Makefile
(4)make uImage
1.6 驱动的动态加载
(1)修改对应目录的Kconfig,(drivers/char/Kconfig)
config JSETC_DRIVER
tristate "jsetc driver"
default y
help
"just for test"
///
uImage: $(obj-y)
modules: $(obj-m)
///
(2) 生成可动态加载的模块
make modules
在对应目录里生成了.ko的内核目标文件
(3)将模块加载进内核
insmod jsetc_driver.ko
查看
lsmod
卸载
rmmod jsetc_driver
如果在卸载模块时出错,创建以下目录
/lib/modules/3.6.0-FriendlyARM
1.7 在内核源码目录外编译动态加载的驱动模块
在当前目录创建Makefile:
obj-m = hello_driver.o
KERN_DIR = /home/linux/jsetc_system_build/3-kernel/linux-3.6-jsetc
all:
make -C $(KERN_DIR) M=$(shell pwd) modules