.
.
----- >
--->
--->
-----------
------------------
-----------
-- --
---> ---> ---> ---> --->
---> ---> --->
---> ---> --->
3. 内核内部构造和内核启动
第一阶段不打印调试信息--> head.S
第二阶段: init/main.c
start_kernel()
|
printk(KERN_NOTICE "%s", linux_banner);
setup_arch(&command_line);
|
struct machine_desc *mdesc;
mdesc = setup_machine_tags(machine_arch_type);
|
for (p = __arch_info_begin; p < __arch_info_end; p++)
machine_desc = mdesc;
printk(KERN_NOTICE "Kernel command line: %s\n", boot_command_line);
parse_early_param();
parse_args("Booting kernel", static_command_line, __start___param,
__stop___param - __start___param,
&unknown_bootoption);
rest_init();
|
启动三个内核线程
kernel_thread(kernel_init, NULL, CLONE_FS | CLONE_SIGHAND);
kernel_init()
|
1, do_basic_setup();
|
do_initcalls();
|
initcall_t *fn;
for (fn = __early_initcall_end; fn < __initcall_end; fn++)
do_one_initcall(*fn);
|
ret = fn();
2,prepare_namespace();
3,init_post();
|
if (execute_command) {
run_init_process(execute_command);
printk(KERN_WARNING "Failed to execute %s. Attempting "
"defaults...\n", execute_command);
}
run_init_process("/sbin/init");
run_init_process("/etc/init");
run_init_process("/bin/init");
run_init_process("/bin/sh");
panic("No init found. Try passing init= option to kernel. "
"See Linux Documentation/init.txt for guidance.");
kernel_thread(kthreadd, NULL, CLONE_FS | CLONE_FILES);
kthreadd()
schedule();
mach-smdkv210.c
MACHINE_START(SMDKV210, "FS210")
.boot_params = S5P_PA_SDRAM + 0x100,
.init_irq = s5pv210_init_irq,
.map_io = smdkv210_map_io,
.init_machine = smdkv210_machine_init,
.timer = &s5p_timer,
MACHINE_END
#define MACHINE_START(_type,_name) \
static const struct machine_desc __mach_desc_##_type \
__used \
__attribute__((__section__(".arch.info.init"))) = { \
.nr = MACH_TYPE_##_type, \
.name = _name,
#define MACHINE_END \
};
===>
整个结构体都会编译到.arch.info.init
static const struct machine_desc __mach_desc_SMDKV210 __attribute__((__section__(".arch.info.init"))) ={
.nr = MACH_TYPE_SMDKV210,
.name = "FS210",
.boot_params = S5P_PA_SDRAM + 0x100,
.init_irq = s5pv210_init_irq,
.map_io = smdkv210_map_io,
.init_machine = smdkv210_machine_init,
.timer = &s5p_timer,
};
解释--为什么smdkv210_machine_init(void)是在开机的时候执行
__arch_info_begin = .;
*(.arch.info.init)
__arch_info_end = .;
只需要知道.arch.info.init -->整个结构体__mach_desc_SMDKV210
知道结构体就可以调用函数指针:init_machine()
调用函数指针就实际调用了smdkv210_machine_init();
static int __init myname_setup(char *str)
{
printk("----^_^myname = %s ------\n", str);
return 1;
}
__setup("myname=", myname_setup);
static int __init myage_setup(char *str)
{
int age = simple_strtoul(str, NULL, 10);
printk("----^_^myage = %d ------\n", age);
return 1;
}
__setup("myage=", myage_setup);
出错处理:
Starting kernel ...
Uncompressing Linux... done, booting the kernel.
原因:
1, console=xx设置错误
2, uboot传递machid出错
3, 内核在编译:
(0) S3C UART to use for low-level messages