一、内核打补丁、编译、烧写、试验
1、解压缩
linux@ubuntu:~/linux$ tar -xjf linux-2.6.22.6.tar.bz2
2、打补丁
linux@ubuntu:~/linux/linux-2.6.22.6$ patch -p1 < ../linux-2.6.22.6_jz2440_v2v3.patch
3、配置(三种方法)
- make menuconfig
- 使用默认配置,在这基础上面修改
- 使用厂家提供的配置文件
第二种方法详细讲解:
在arch/arm/configs
目录下找到相似的配置文件xxx_defconfig
,执行make xxx_defconfig
(结果保存在.config
),再次执行menuconfig
(读取.config
)。
linux@ubuntu:~/linux/linux-2.6.22.6$ make s3c2410_defconfig
第三种方法详细讲解:
厂家提供一个config_name(厂家名)
,之后拷贝cp config_name .config
,再次执行menuconfig
(读取.config
),目前,我们使用的是厂家提供的
linux@ubuntu:~/linux/linux-2.6.22.6$ cp config_ok .config
4、编译
make uImage
uImage = 头部 + zImage
二、内核功能、结构,结合Makefile、Kconfig进行分析
1、配置(.config)
配置的结果生成.config
文件。
vim .config
以一个配置想为例(CONFIG_DM9000
)
linux@ubuntu:~/linux/linux-2.6.22.6$ grep "CONFIG_DM9000" * -rwR
搜索结果如下:
发现CONFIG_DM9000
存在于一下文件下
- C源码:
CONFIG_DM9000
(宏定义) - 子目录
Makefile
:drivers/net/Makefile
include/config/auto.conf
include/linux/autoconf.h
其中,当.config
文件下的CONFIG_DM9000
配置为Y
或者M
时,当执行make uImage
会自动生成头文件,为include/config/auto.conf
和include/linux/autoconf.h
,这时候,C语言的源码中这些宏被定义,就会执行相应的代码。
include/config/auto.conf
的内容:
include/linux/autoconf.h
内容:
内核子目录Makefile
的讲解
obj - (y) +=xxx.o //将xxx.c编译为xxx.o并被链接到内核
obj - (m) +=yyy.o //将把yyy.c编译成模块 yyy.ko.
子目录中y
与m
由auto.conf
决定,而auto.conf
由.config
决定
include/config/auto.conf
被顶层Makefile
包含
小结:
执行make uImage
之后,①.config
自动创建生成autoconf.h
,用于源代码的使用;②.config
自动创建生成auto.conf
,用于被顶层Makefile包含。
2、分析Makefile
根据Makefile
可以找到第一个文件,也可以找链接脚本,可以了解到内核在内存中是如何分布的。
①子目录下的Makefile比较简单
obj - (y) +=xxx.o //将xxx.c编译为xxx.o并被链接到内核
obj - (m) +=yyy.o //将把yyy.c编译成模块 yyy.ko.
将多个.c文件链接成以个.ko模块方法(根据Makefile.txt介绍)
obj-$(CONFIG_ISDN) += isdn.o
isdn-objs := isdn_net_lib.o isdn_v110.o isdn_common.o
②make uImage
位于arch/arm/Makefile
,猜测这个Makefile肯定被包含在顶层Makefile
arch/arm/Makefile
中uImage依赖于vmlinux(顶层)
第一个文件:arch/arm/kernel/head.s
链接脚本:arch/arm/kernel/vmlinux.lds
三、内核启动过程分析
内核的作用:
①处理uboot传入的参数 arch/arm/kernel/head.S
-
判断是否支持这个处理器
#define MACHINE_START(_type,_name)
static const struct machine_desc _mach_desc##_type
_used
attribute((section(".arch.info.init"))) = { \ //结构体强制设置属性,设置为“.arch.info.init”段
.nr = MACH_TYPE##_type, \ //所有含有“.arch.info.init”的会被链接文件强制放到一块
.name = _name,#define MACHINE_END
}; -
判断是否支持这个单板(uboot启动内核时传输的机器ID)
#define MACHINE_START(_type,_name)
static const struct machine_desc _mach_desc##_type
_used
attribute((section(".arch.info.init"))) = { \ //结构体强制设置属性,设置为“.arch.info.init”段
.nr = MACH_TYPE##_type, \ //所有含有“.arch.info.init”的会被链接文件强制放到一块
.name = _name,#define MACHINE_END
}; -
创建页表
-
使能MMU
-
跳转start_kernel(内核第一个C函数)
最终目的运行应用程序(挂接根文件系统)