一、makefile分析
1 linux内核中的几类makefile
对makefile讲解:
1.1子目录下的makefile
2顶层makefile分析开始
然后到arch/arm/makefile下查找找到uImage:
uImage位于arch下,显然顶层makefile 会包含arch/arm下的makefile。
]
同样,.config生成的头,也被包含到顶层
重点分析顶层makefile
到arch/arm/makefile下查找找到uImage
uImage依赖于vmlinux
uImage=头+内核
\显然真正的内核就是vmlinux
Vmlinux依赖于谁呢?vmlinux依赖在顶层目录里面。
打开顶makefile 搜索vmlinux
显然 make的时候 也依赖于vmlinux。也需要生成vmlinux。
搜索vmlinux依赖于谁?:
顶层搜索如:
vmlinux: $(vmlinux-lds) $(vmlinux-init)$(vmlinux-main) $(kallsyms.o) FORCE
UImage依赖vmlinux
Vmlinux依赖于下面:
vmlinux: $(vmlinux-lds) $(vmlinux-init)$(vmlinux-main) $(kallsyms.o) FORCE
Lds链接脚本
Init:初始化代码
Main:内核相关主要代码、
查看下:
vmlinux-init := $(head-y) $(init-y)
vmlinux-main := $(core-y) $(libs-y) $(drivers-y)$(net-y)
vmlinux-all := $(vmlinux-init) $(vmlinux-main)
vmlinux-lds := arch/$(ARCH)/kernel/vmlinux.lds
vmlinux-init:
搜索head-y,顶层中没搜到,显然在架构makefile中:
head-y :=arch/arm/kernel/head$(MMUEXT).o arch/arm/kernel/init_task.o
(最初始的代码)搜索init-y,顶层中搜到:
init-y :=init/
init-y :=$(patsubst %/, %/built-in.o, $(init-y))
说明:
%/代表init/,所以:
init-y :=$(patsubst %/, %/built-in.o, $(init-y))= init/ built-in.o
vmlinux-main:顶层搜索:vmlinux-main 查到:
vmlinux-main := $(core-y) $(libs-y)$(drivers-y) $(net-y)
核心 库 驱动 网络
顶层搜索core-y:
core-y :=usr/
core-y +=kernel/ mm/ fs/ ipc/ security/ crypto/ block/
core-y :=$(patsubst %/, %/built-in.o, $(core-y))
显然最后core-y= usr/ built-in.o kernel/ built-in.o mm/ built-in.o fs/ built-in.o ipc/ security/ built-in.o crypto/ built-in.o block/ built-in.o 文件
顶层搜索libs-y
libs-y :=lib/
libs-y1 :=$(patsubst %/, %/lib.a, $(libs-y))
libs-y2 :=$(patsubst %/, %/built-in.o, $(libs-y))
libs-y :=$(libs-y1) $(libs-y2)
libs-y= lib/ lib.a lib/ built-in.o
顶层搜索drivers-y
drivers-y :=drivers/ sound/
drivers-y :=$(patsubst %/, %/built-in.o, $(drivers-y))
drivers-y =drivers/ built-in.o sound/ built-in.o
顶层搜索net-y
net-y :=net/
net-y :=$(patsubst %/, %/built-in.o, $(net-y))
net-y =net/ built-in.o
因此原材料就是这些东西,来链接 组成内核:
一个方法分析:
另一个方法:直接make uImage V=1
V=1 命令 详细的列出来。
主要关心最后一个命令
-o vmlinux 输出vmlinux
链接脚本:vmlinux.lds:决定了原材料如何排布
原材料是哪些呢:
head.o
init-task.o
init/built-in.o等等
makefile得到俩大结果:
第一个文件是谁:\linux-2.6.22.6\arch\arm\kernel\head.s
链接脚本:linux-2.6.22.6\linux-2.6.22.6\arch\arm\kernel\vmlinux.lds
内核虚拟地址,材料排布等:
二、内核启动分析
1建立sourceinsight工程
Addall
先整体删除掉arch目录
Add tree
去掉include目录
建立sourceinsigth工程完成
2内核启动分析,从这里开始分析:
Uboot执行过程中,在内存设置了很多参数
(内存信息、命令行信息)等
猜测内核启动的时候做什么事情
最终目的:启动应用程序(根文件系统中)
2.1处理uboot传入的参数(从arch/arm/kernel/head.S)
内核可能很大 通过压缩 使用的时候先解压
head.S上来做了什么
(1)__lookup_processor_type:
是否支持CPU,判断内核是否支持该处理器,不支持调到err
(2)__lookup_machine_type:
检测是否支持该单板,uboot启动内核时,传入进来的机器ID(362),内核支持哪些单板 自己知道,判断362是否匹配支持。不支持调到err死循环。
__lookup_machine_type代码如下:
汇编交互原则知道,362应该是存放在R1寄存器里
内核启动的时候 从begin读到end 来判断是否支持该单板信息
从这里读出单板信息
猜测内核支持如下单板:
/*
* Set of macros to define architecture features. This is built into
* a table by the linker.
*/
#define MACHINE_START(_type,_name) \
static const struct machine_desc __mach_desc_##_type \
__used \
__attribute__((__section__(".arch.info.init"))) = { \
.nr = MACH_TYPE_##_type, \= MACH_TYPE_ S3C2440,
.name = _name, name,= SMDK2440
#define MACHINE_END \
};
MACHINE_START(S3C2440, "SMDK2440")
/* Maintainer: Ben Dooks <ben@fluff.org> */
.phys_io = S3C2410_PA_UART,
.io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
.boot_params = S3C2410_SDRAM_PA + 0x100,
.init_irq = s3c24xx_init_irq,
.map_io = smdk2440_map_io,
.init_machine = smdk2440_machine_init,
.timer = &s3c24xx_timer,
MACHINE_END
(3)建立页表,启动MMU
.(4)start_kernel启动内核(处理uboot的参数)内核第一个c函数
.
处理启动参数:
setup_arch(&command_line);
setup_command_line(command_line);
处理命令行参数: