实验十一 Linux内核的配置和编译
【实验目的】
掌握Linux内核的配置和编译的方法。
说明:在实验中命令行提示符为“$”表示在主机上运行,“#”表示在目标板上运行。
【实验环境】
Ubuntu 16.04 64位发行版
FS6818平台
【实验步骤】
将“系统移植\案例源码\第二天\kernel-3.4.39.tar.bz2”拷贝到Ubuntu主机。
使用下面的命令对源码进行解压。
$ tar -xvf kernel-3.4.39.tar.bz2
进入到解压的目录,清除配置。
$ cd kernel-3.4.39/
$ make ARCH=arm mrproper
或
$ make ARCH=arm distclean
使用下面的命令可以对内核进行fs6818的默认配置。
make ARCH=arm fs6818_defconfig
也可以直接拷贝默认的配置文件,但在编译前必须要进行一次make menuconfig。
$ cp arch/arm/configs/fs6818_defconfig .config
使用下面的命令,对内核进行配置。
$ make ARCH=arm menuconfig
指定交叉编译工具链的前缀
General setup --->
(arm-none-linux-gnueabi-) Cross-compiler tool prefix
编译内核的uImage镜像。
$ make ARCH=arm uImage
或
$ make ARCH=arm uImage -j2
或
$ make ARCH=arm uImage -j2 > /dev/null
其中j后面的数字通常是CPU个数的两倍。
如果不想每次都在命令行中输入ARCH=arm,则可以通过修改顶层的Makefile文件来实现。
将:
ARCH ?= $(SUBARCH)
改为:
ARCH ?= arm
拷贝内核到Fastboot目录准备进行烧写,烧写办法参考实验七。
or
linux内核的配置和编译
1》配置交叉编译工具链
顶层目录的Makefile中进行配置
CROSS_COMPILE
2》第一次编译内核是清除中间文件
make clean
make distclean
3》配置内核支持fs6818硬件平台
make fs6818_defconfig
4》通过图形化界面对内核进行配置
make menuconfig
5》编译内核生成uImage镜像
make uImage
#################################################
【1】make menuconfig执行过程详解
1. 搜索menuconfig,没有搜索到;
搜索%config,搜索到一下信息
491 %config: scripts_basic outputmakefile FORCE
492 $(Q)mkdir -p include/linux include/config
493 $(Q)$(MAKE) $(build)=scripts/kconfig $@
解析:
Q = @
mkdir -p include/linux include/config
make -f scripts/Makefile.build obj=scripts/kconfig menuconfig
进入scripts/kconfig目录下执行make menuconfig
2. 打开scripts/kconfig目录下的Makefile文件
搜索menuconfig,得到以下信息
20 menuconfig: $(obj)/mconf
21 $< $(Kconfig)
解析:
scripts/kconfig/mconf Kconfig
使用file命令查看scripts/kconfig目录下mconf文件的类型
file scripts/kconfig/mconf
可知mconf文件是一个elf可执行文件
mconf根据内核源码顶层目录的Kconfig文件生成
图形化界面的菜单选项配置界面。
3. 打开内核源码顶层目录的Kconfig文件
5 mainmenu "Linux/$ARCH $KERNELVERSION Kernel Configuration"
6
7 config SRCARCH
8 string
9 option env="SRCARCH"
10
11 source "arch/$SRCARCH/Kconfig"
解析:
mainmenu : 主菜单
语法格式:mainmenu "主菜单名字"
source:包含下一级子菜单对应的Kconfig文件路径
语法格式: source "下一级子菜单的Kconfig路径"
打开arch/arm/目录下的Kconfig文件。
Kconfig文件作用?
Kconfig用于存放菜单选项的配置信息。
254 menu "System Type"
255
256 config MMU
257 bool "MMU-based Paged Memory Management Support"
258 default y
259 help
260 Select if you want MMU-based virtualised addressing space
261 support by paged memory management. If unsure, say 'Y'.
......
endmenu
解析:
/***********************
menu: 子菜单选项
endmenu: 子菜单结尾
语法格式:
menu "子菜单的名字"
....
endmenu
***********************/
/**********************
bool: 菜单选项
语法格式: bool "菜单选项的名字"
bool类型的菜单选项只有两种状态
[*] :被选中状态 对应的驱动被编译到uImage内核镜像中
[ ] :未被选中状态 对应的驱动不被编译到uImage内核镜像中
***********************/
/**********************
default : 对应菜单选项的默认状态
default y :默认被选中的状态
***********************/
/**********************
help : 帮助信息
***********************/
/**********************
如果config MMU下边对应的菜单选项是[*]被选中的状态,
config MMU会被写到.config配置文件中
在.config文件中的格式为 CONFIG_MMU = y,
如果config MMU下边对应的菜单选项是[ ]未被选中的状态,
config MMU会被写到.config配置文件中
在.config文件中的格式为 # CONFIG_MMU is not set
***********************/
.config文件的作用?
答:
Makefile文件根据.config文件中的配置信息来决定
哪些代码被编译到内核uImage镜像中,那些代码不被编译到
内核uImage镜像中。
如果CONFIG_****=y表示对应的驱动被编译到内核中。
打开arch/arm/目录下的Makefile文件:
32 ifeq ($(CONFIG_MMU),)
33 MMUEXT := -nommu
34 endif
如果CONFIG_MMU=y使用内存管理单元
如果# CONFIG_MMU is not set 不使用内存管理单元
【2】使用图形化界面的方式添加自己的驱动代码到内核中
1. 去除华清远见研发中心提供的led灯驱动
Device Drivers --->
Character devices --->
[ ] FS6818 beep driver // 去掉
FS6818 board device driver support --->
[ ] adc driver for farsight FS6818 all platform // 去掉
[ ] pwm timer driver for farsight FS6818 // 去掉
FS6818 extension device driver support --->
[ ] This is FS6818_LED! // 去掉
[ ] zlg7290 driver support input device // 去掉
保存退出
2. 添加自己led灯驱动对应的菜单选项
1》 拷贝fs6818_led.c和fs6818_led.h文件到内核的
drivers/char目录下
2》 添加菜单选项
修改drivers/char目录下的Kconfig文件,添加以下信息:
4 menu "HQYJ FS6818 LED"
5 config LED_DRIVER
6 bool "FS6818 led"
7 default y
8 help
9 hqyj fs6818 led drivers!
10 endmenu
3》 修改drivers/char目录下的Makefile文件,添加以下信息:
5 obj-$(CONFIG_LED_DRIVER) += fs6818_led.o
4》 通过图形化界面对led灯驱动进行配置
</> for Search
使用搜索的功能搜索CONFIG后边的内容
搜索LED_DRIVER
│ Symbol: LED_DRIVER [=y]
│ Type : boolean
│ Prompt: FS6818 led
│ Defined at drivers/char/Kconfig:5
│ Location:
│ -> Device Drivers
│ -> HQYJ FS6818 LED
5》 编译内核生成uImage的内核镜像
make -j4 uImage
6》 测试led灯驱动是都可用
led灯驱动已经编译到uImage内核镜像中
1> 拷贝新生成的uImage镜像到tftpboot目录下
cp arch/arm/boot/uImage ~/tftpboot
2> 启动开发板 (开发阶段系统的启动方式)
使用tftp下载uImage到内存中
使用nfs服务挂载根文件系统
检查自己uboot中的bootcmd和bootargs环境变量。
3> 编译led灯的应用程序,并将可执行文件拷贝到根文件系统中。
arm-none-linux-gnueabi-gcc fs6818led_test.c -o led_test
cp led_test ~/nfs/rootfs
4> 运行led灯的应用程序,观察led灯的现象
./led_test
【3】驱动采用模块化的方式进行编译
bool : []
[*] : 对应的驱动被编译到uImage中
[ ] : 对应的驱动不被编译到uImage中
tristate : <>
<*> : 对应的驱动被编译到uImage中
< > : 对应的驱动不被编译到uImage中
<M> : 对应的驱动采用模块化的方式进行编译
模块化的编译方式:***.c -编译生成->***.ko
当需要使用驱动时可以使用insmod命令将***.ko
文件加载到内核中。
当不需要使用驱动时可以使用rmmod命令将***.ko
文件从内核中卸载掉。
1》 拷贝fs6818_led.c和fs6818_led.h文件到内核的
drivers/char目录下
2》 添加菜单选项
修改drivers/char目录下的Kconfig文件,添加以下信息:
4 menu "HQYJ FS6818 LED"
5 config LED_DRIVER
6 tristate "FS6818 led"
7 default y
8 help
9 hqyj fs6818 led drivers!
10 endmenu
3》 修改drivers/char目录下的Makefile文件,添加以下信息:
5 obj-$(CONFIG_LED_DRIVER) += fs6818_led.o
4》 通过图形化界面对led灯驱动进行配置
</> for Search
使用搜索的功能搜索CONFIG后边的内容
搜索LED_DRIVER
│ Symbol: LED_DRIVER [=m]
│ Type : boolean
│ Prompt: FS6818 led
│ Defined at drivers/char/Kconfig:5
│ Location:
│ -> Device Drivers
│ -> HQYJ FS6818 LED
修改:
-> Device Drivers
-> HQYJ FS6818 LED
<M> FS6818 led // <*>修改为<M>
5》 编译内核生成uImage的内核镜像 (去除led灯的驱动)
$ make -j4 uImage
去掉自己上午添加的led灯驱动,将tftpboot目录下的
uImage文件进行替换
$ cp arch/arm/boot/uImage ~/tftpboot
6》 使用模块化的方式编译led灯的驱动
$ make modules 模块化的方式编译驱动,
所有的模块化的驱动都被编译成.ko文件
编译结果打印以下信息,表示模块化编译成功:
CC drivers/char/fs6818_led.mod.o
LD [M] drivers/char/fs6818_led.ko
6》 测试led灯驱动是都可用
led灯驱动已经编译到uImage内核镜像中
1> 拷贝driver/char目录下的fs6818_led.ko文件到
根文件系统目录下
$ cp drivers/char/fs6818_led.ko ~/nfs/rootfs
2> 启动开发板 (开发阶段系统的启动方式)
使用tftp下载uImage到内存中
使用nfs服务挂载根文件系统
检查自己uboot中的bootcmd和bootargs环境变量。
3> 编译led灯的应用程序,并将可执行文件拷贝到根文件系统中。
$ arm-none-linux-gnueabi-gcc fs6818led_test.c -o led_test
$ cp led_test ~/nfs/rootfs
4> 使用insmod命令加载fs6818_led.ko的驱动文件到内核中
# insmod fs6818_led.ko // 系统启动成功,在串口工具中执行命令
# ./led_test
# lsmod 查看已经加载的驱动
# rmmod fs6818_led // 只需要指定驱动的名称
(1)出现以下错误信息:
rmmod: can't change directory to '/lib/modules':
No such file or directory
解决办法:
在根文件系统的lib目录下创建modules文件夹即可。
(2)出现以下错误信息:
rmmod: can't change directory to '3.4.39-farsight':
No such file or directory
解决办法:
在根文件系统的lib/modules目录下
创建3.4.39-farsight文件夹即可。