linux2.6内核配置:
1.make menuconfig命令进行菜单配置,根据arch下不同结构体系目录下的kconfig文件进行配置
2.生成 /.config文件,提供给makefile文件使用
3.生成/include/linux下autoconf.h文件 config.h文件提供给程序编译使用
YLP2440下的参数列表:
1.在内核配置menuconfig中,boot options下有commandline配置输入项。同时在0x30000100处,由bootloader存入了linux参数列表:(包括commandline)struct param_struct *params = (struct param_struct *)0x30000100;
2.而在linux中,由MakeFile.boot指定params_phys-y := 0x30000100
同时定义了BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100)也指向该区域
3.commandline的值由bootloader设置,最终由init/main.c中的setup_arch()实现。其中关键代码注释如下:
struct tag *tags = (struct tag*)&init_tags; //tags指向默认的tag链表
……
mdesc = setup_machine(machine_arch_type);// mdesc包含启动参数在内存中的地址
if( mdesc->boot_params )
tags = phys_to_vert(mdesc->boot_params);// bootloader有传递启动参数到内核
if( tags->hdr.tag != ATAG_CORE )
convert_to_tag_list(tags);//如果是旧的启动参数结构,将其转成新的tag链表的形式
if( tags->hdr.tags != ATAG_CORE )
tags = (struct tag*)&init_tags;//转换失败,使用内置的启动参数
if( tags->hdr.tag == ATAG_CORE )
{
if( meminfo.nr_banks != 0 )
squash_mem_tags(tags);//如果在meminfo中有配置内存tag则跳过对内存tag的处理
parse_tags(tags);
}
对于内核参数有哪些,可以在内核目录下搜索__setup关键字,就可查出,也可见:Linux操作系统内核启动参数详细解析文章。
linux启动过程:
1.call_linux(0, boot_params.machine.val, buf);//bootloader调用内核
2.内核编译链接过程是依靠vmlinux.lds文件,以arm为例vmlinux.lds文件位kernel/arch/arm/boot/compressed/vmlinux.lds,但是该文件是由vmlinux.lds.in生成的。vmlinux.lds的生成过程在kernel/Makefile中。在Vmlinux.lds中定义了内核起始入口:ENTRY(_start)
3.如果kernel压缩过,则要进行解压,在压缩过的kernel头部有解压程序。压缩过得kernel入口第一个文件源码位置在arch/arm/boot/compressed/head.S的start:,它将调用函数decompress_kernel(),这个函数在文件arch/arm/boot/compressed/misc.c中,decompress_kernel()又调用arch_decomp_setup()进行设置,然后使用在打印出信息“Uncompressing Linux...”后,调用gunzip()。将内核放于指定的位置(0x30008000)。
我们在内核启动的开始都会看到这样的输出:
Uncompressing Linux..................................................done, booting the kernel.
这也是由decompress_kernel函数内部输出的,其中省略号是由arch/arm/boot/compressed/misc.c中的flush_window()中putstr(".");实现的。执行完解压过程,再返回到head.S中,启动内核:
call_kernel: bl cache_clean_flush
bl cache_off
mov r0, #0
mov r1, r7 @ restore architecture number
mov pc, r4 @ call kernel
下面就开始真正的内核了。
4.内核的入口:/arch/arm/kernel/head.S下的ENTRY(stext),执行一系列的过程,最终 b start_kernel 跳到内核c语言部分第二阶段。内核启动第二阶段从init/main.c的start_kernel()函数开始到函数结束。这一阶段对整个系统内存、cache、信号、设备等进行初始化,最后产生新的内核线程init后,调用cpu_idle()完成内核第二阶段。