lib:库文件,注意内核中使用的库都是自己实现的,不会使用C库。
Vmlinux:在内核的根目录下,未压缩的ELF格式的内核镜像。
Image:未压缩,经过arm-linux-objcopy 处理后生成只包含内核数据的一个内核镜像文件(6M),直接加载到内存运行。
zImage:压缩,压缩Image生成的内核镜像,压缩50%(3M)+解压启动代码。自解压后,加载到内存中 。
自解压:zImage运行之前,要进行自解压:arch/arm/boot/compressed/head.S:decompress_kernel(定义misc.c)。
uImage:为u-boot 使用 bootm 命令引导的 Linux 压缩内核映像文件格式。是使用工具mkimage对普通的压缩内核映像文件(zImage)加工而得。它是uboot专用的映像文件,它是在zImage之前加上一个长度为 64字节的“头”,说明这个内核的版本、加载位置、生成时间、大小等信息;其0x40之后与zImage没区别。bootloader一般要占用0X0地址,所以,uImage比zImage的好处就是可以和bootloader 共存。
zImage和uImage的区别:其实就是一个自动跟手动的区别,有了uImage头部的描述,u-boot就知道对应Image的信息,如果没有头部则需要自己手动去设置这些参数。
.config:编译内核时,根据该文件的内容,Makefile 决定“哪些选项需要编译及以何种方式编译”到内核 —— CONFIG_XXX_XXXX
Kconfig:配置内核的菜单(make menuconfig)是通过读取内核各目录下的Kconfig(配置选项)文件来生成。通过修改Kconfig文件,虽然可以在配置内核的时候进行选择,但实际上编译内核并不能把XXX.c(自定义源文件)编译进内核。还需要修改 Makefile文件,把内核配置选项和真正的源代码联系起来,修改~/linux-2.6.35.7/arch/arm/mach-s5pv210/Makefile<<<<<将Kconfig中添加的文件变量名和文件关联。
============================================
内核的 Makefile分为5个组成部分:
1.最顶层的Makefile ;
2.内核的.config配置文件;
3.在arch/$(ARCH) 目录下的体系结构相关的Makefile;
4.在 s 目录下的 Makefile.* 文件,是一些Makefile的通用规则(链接编译、模块编译等);
5.各级目录下的大概约500个kbuild Makefile文件。
顶层的Makefile文件读取.config文件的内容,并总体上负责build内核和模块。arch Makefile则提供补充体系结构相关的信息。 s目录下的Makefile文件包含了所有用来根据kbuild Makefile 构建内核所需的定义和规则。
============================================
kbuildMakefile:对于Makefiles的不同组成部分,有一些不同的语法规则,针对的对象也不同。对于大部分内核模块或设备驱动的开发者和使用者来说,最常接触到的就是各层目录下基于kbuild架构的Makefile文件。(文件如何进行编译的规则模块编译,编译链接等)
Kbuild Makefile 核心内容主要包括:目标定义就是用来定义哪些内容要做为模块编译,哪些要编译链接进内核。
如:
obj-y += foo.o
表示由 foo.c 或者 foo.s 文件编译得到 foo.o 并链接进内核,而 obj-m 则表示该文件要作为模块编译。 除了y,m外,obj-x形式的目标都不会被编译。更常见的做法是根据.config文件的CONFIG_变量来决定文件的编译方式,如:Makefile在编译时,根据kbuildMakefile规则,读取.config 文件,来选择如何编译文件【链接编译[y],模块编译[m]】 :obj-$(CONFIG_EXT2) += ext2.o
============================================
patch:为内核打补丁
============================================
顶层的Makefile:需要确定体系架构和 使用的交叉编译器。
191 ARCH = arm
192 CROSS_COMPILE =arm-linux-
============================================
Linux内核启动过程总体过程:
1.架构/开发板相关的引导过程:通常使用汇编来编写。1.检查内核是否支持当前架构的CPU处理器;2.检查是否支持当前的开发板。
2.内核通用的启动过程:用C语言来编写。进行内核的初始化全部工作,最后调用rest_init函数创建系统的第一个用户进程 —— init进程。
============================================
Linux内核启动过程的代码分析:
1)zImage内核进行自解压并进行运行前的两步检查:arch/arm/kernel/head.S
81 mrc p15, 0, r9, c0, c0//将存储在协处理器中CPU的ID号读到ARM处理器的r9寄存器
82 bl __lookup_processor_type//内核是否支持此CPU的ID号
381 __proc_info_begin = .;
382 *(.proc.info.init)
383 __proc_info_end = .;
//用r9中CPU的ID号到__proc_info_begin至__proc_info_end中匹配,如果匹配不成功,内核不启动。
============================================
85 bl __lookup_machine_type
theKernel(0, 2456, 0x20000100)
r0 r1 r2
//用 u-boot通过r1寄存器传递来板子的2456号,到以下内存区域匹配。如果匹配成功,返回开发板结构体,内核继续执行;如果不成功,内核不启动
384 __arch_info_begin = .;
385 *(.arch.info.init)
386 __arch_info_end = .;
2)挂载根文件系统
3)启动init进程
============================================
arch/arm/mach-s5pv210/mach-smdkv210.c开发板文件描述信息:struct machine_desc {
/*
* Note! The first fourelements are used
* by assembler code inhead.S, head-common.S
*/
unsigned int nr; /*architecture number */
unsignedint phys_io; /*start of physical io */
unsignedint io_pg_offst;/* byte offset for io
* page tabe entry */
const char *name; /*architecture name */
unsignedlong boot_params; /*tagged list */
unsignedint video_start;/* start of video RAM */
unsignedint video_end; /*end of video RAM */
unsignedint reserve_lp0:1; /* never has lp0 */
unsignedint reserve_lp1:1; /* never has lp1 */
unsignedint reserve_lp2:1; /* never has lp2 */
unsignedint soft_reboot:1; /* soft reboot */
void (*fixup)(struct machine_desc *,
struct tag *, char **,
struct meminfo *);
void (*map_io)(void);/* IO mapping function */
void (*init_irq)(void);
structsys_timer *timer; /* system tick timer */
void (*init_machine)(void);
};
~/workdir/tools/linux-2.6.35.7/arch/arm/tools vi mach-types
MACH_TYPE_SMDKV210
machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number
static const structmachine_desc __mach_desc_SMDKV210 \
__used __attribute__ ((__section__(".arch.info.init")))={ \ /*快速访问*/
.nr = MACH_TYPE_SMDKV210,
.name = "SMDKV210",
/*Maintainer: Kukjin Kim<kgene.kim@samsung.com> */
.phys_io = S3C_PA_UART& 0xfff00000,
.io_pg_offst = (((u32)S3C_VA_UART)>> 18) &0xfffc,
.boot_params = S5P_PA_SDRAM +0x100,
.init_irq = s5pv210_init_irq,
.map_io = smdkv210_map_io,
.init_machine =smdkv210_machine_init,
.timer = &s3c24xx_timer,
};