x86系统引导(5)

再次回到asmlinkage void __init start_kernel(void)函数

asmlinkage void __init start_kernel(void)
{
char * command_line;
extern struct kernel_param __start___param[], __stop___param[];
/*
 * Interrupts are still disabled. Do necessary setups, then
 * enable them
 */
lock_kernel();
page_address_init();
printk(linux_banner);
setup_arch(&command_line);上几篇分析的主要是这个函数。
setup_per_cpu_areas();/* 设置smp中每个cpu区域偏移量信息 */
/*
* Mark the boot cpu "online" so that it can call console drivers in
* printk() and can access its per-cpu storage.
*/
smp_prepare_boot_cpu();设置引导cpu在工作状态

/*
* Set up the scheduler prior starting any interrupts (such as the
* timer interrupt). Full topology setup happens at smp_init()
* time - but meanwhile we still have a functioning scheduler.
*/
sched_init();对进程调度机制的初始化
build_all_zonelists();
page_alloc_init();
printk("Kernel command line: %s\n", saved_command_line);
parse_early_param();对命令行进行解析,只是做一些字符串的处理
parse_args("Booting kernel", command_line, __start___param,
  __stop___param - __start___param,
  &unknown_bootoption);

对命令行进行分析,并执行对应的函数。源码如下:

/* Args looks like "foo=bar,bar2 baz=fuz wiz". */
int parse_args(const char *name,
      char *args,
      struct kernel_param *params,
      unsigned num,
      int (*unknown)(char *param, char *val))
{
char *param, *val;
DEBUGP("Parsing ARGS: %s\n", args);
while (*args) {
int ret;

args = next_arg(args, &param, &val);
ret = parse_one(param, val, params, num, unknown);

主要是这两个函数,涉及到一个结构体,如下:

typedef int (*param_set_fn)(const char *val, struct kernel_param *kp);
typedef int (*param_get_fn)(char *buffer, struct kernel_param *kp);
struct kernel_param {
const char *name;
unsigned int perm;
param_set_fn set;
param_get_fn get;
void *arg;
};

从命令行中找到对应的命令,然后执行kernel_param结构体中对应的函数。

static int parse_one(char *param,
    char *val,
    struct kernel_param *params, 
    unsigned num_params,
    int (*handle_unknown)(char *param, char *val))
{
unsigned int i;

/* Find parameter */
for (i = 0; i < num_params; i++) {
if (parameq(param, params[i].name)) {
DEBUGP("They are equal!  Calling %p\n",
      params[i].set);
return params[i].set(val, &params[i]);执行对应的函数。
}
}
.....
}

.....

}
......
}
}.....
}
sort_main_extable();/* 异常处理调用函数表排序 */
trap_init();设置终端门和陷阱门
rcu_init();/* 初始化RCU(Read-Copy Update) */
init_IRQ();中断初始化
pidhash_init();pidhash表初始化
init_timers();
softirq_init();软中断
time_init();定时器初始化

/*
* HACK ALERT! This is early. We're enabling the console before
* we've done PCI setups etc, and console_init() must be aware of
* this. But we do want output early, in case something goes wrong.
*/
console_init();控制台初始化
if (panic_later)
panic(panic_later, panic_param);
profile_init();
local_irq_enable();开中断
#ifdef CONFIG_BLK_DEV_INITRD
if (initrd_start && !initrd_below_start_ok &&
initrd_start < min_low_pfn << PAGE_SHIFT) {
printk(KERN_CRIT "initrd overwritten (0x%08lx < 0x%08lx) - "
   "disabling it.\n",initrd_start,min_low_pfn << PAGE_SHIFT);
initrd_start = 0;
}
#endif
vfs_caches_init_early();
mem_init();内存
kmem_cache_init();
numa_policy_init();
if (late_time_init)
late_time_init();
calibrate_delay();
pidmap_init();
pgtable_cache_init();
prio_tree_init();
anon_vma_init();
#ifdef CONFIG_X86
if (efi_enabled)
efi_enter_virtual_mode();
#endif
fork_init(num_physpages);
proc_caches_init();
buffer_init();
unnamed_dev_init();
security_init();
vfs_caches_init(num_physpages);建立专用的slab缓冲区队列
radix_tree_init();
signals_init();
/* rootfs populating might need page-writeback */
page_writeback_init();
#ifdef CONFIG_PROC_FS
proc_root_init();
#endif
check_bugs();


acpi_early_init(); /* before LAPIC and SMP init */


/* Do the rest non-__init'ed, we're now alive */
rest_init();

系统的初始化过程有很多函数,可以到具体用时在查,有很多函数只看名字就知道它的大致作用,就不说了。

你可能感兴趣的:(struct,command,tree,buffer,X86,Parsing)