解读linux内核代码之boot(1)

最近开始研究linux内核,之前本来是在看《Understanding The Linux Kernel》,看了几章之后,发现虽然这本书讲的很通俗易懂,但是我看的是第二版,书中对应的内核版本是2.4的,而现在最新的内核版本确实2.6.39的,大体上算法是差不多的,但是很多代码实现完全不同了,所以就放弃了这本书,开始从源代码入手开始看。

由于内核代码很多,刚开始也不知道从哪里开始看起,纠结了很久才决定从内核boot的代码开始看起。

 

boot的代码在/arch/x86/boot/这个目录下,下面很明显的有个main.c文件,自然地打开一看,里面有个main函数,如下

 

void main(void)
{
    /* First, copy the boot header into the "zeropage" */
    copy_boot_params();

    /* Initialize the early-boot console */
    console_init();
    if (cmdline_find_option_bool("debug"))
        puts("early console in setup code/n");

    /* End of heap check */
    init_heap();

    /* Make sure we have all the proper CPU support */
    if (validate_cpu()) {
        puts("Unable to boot - please use a kernel appropriate "
             "for your CPU./n");
        die();
    }

    /* Tell the BIOS what CPU mode we intend to run in. */
    set_bios_mode();

    /* Detect memory layout */
    detect_memory();

    /* Set keyboard repeat rate (why?) */
    keyboard_set_repeat();

    /* Query MCA information */
    query_mca();

    /* Query Intel SpeedStep (IST) information */
    query_ist();

    /* Query APM information */
#if defined(CONFIG_APM) || defined(CONFIG_APM_MODULE)
    query_apm_bios();
#endif

    /* Query EDD information */
#if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE)
    query_edd();
#endif

    /* Set the video mode */
    set_video();

    /* Do the last things and invoke protected mode */
    go_to_protected_mode();
}

 

函数的第一句调用函数copy_boot_params(), 这个函数依然在本文件中,作用是拷贝boot参数到第一个内存page,提醒一句,这个时候cpu还是运行在实模式下。copy_boot_params()的实现如下

static void copy_boot_params(void)
{
    struct old_cmdline {
        u16 cl_magic;
        u16 cl_offset;
    };
    const struct old_cmdline * const oldcmd =
        (const struct old_cmdline *)OLD_CL_ADDRESS;

    BUILD_BUG_ON(sizeof boot_params != 4096);
    memcpy(&boot_params.hdr, &hdr, sizeof hdr);

    if (!boot_params.hdr.cmd_line_ptr &&
        oldcmd->cl_magic == OLD_CL_MAGIC) {
        /* Old-style command line protocol. */
        u16 cmdline_seg;

        /* Figure out if the command line falls in the region
           of memory that an old kernel would have copied up
           to 0x90000... */
        if (oldcmd->cl_offset < boot_params.hdr.setup_move_size)
            cmdline_seg = ds();
        else
            cmdline_seg = 0x9000;

        boot_params.hdr.cmd_line_ptr =
            (cmdline_seg << 4) + oldcmd->cl_offset;
    }
}

这个函数逻辑是简单的,我并不想说这个,注意这一句memcpy(&boot_params.hdr, &hdr, sizeof hdr);中hdr这个变量,这个结构体变量在main.c里面并没有定义,然后我惊讶地发现这个hdr居然在linux内核代码中所有的h文件和c文件中都没有定义,出了在boot.h中声明了一下extern struct setup_header hdr;

最后把目光发在head.s这个汇编文件上,打开一看,果然hdr这个变量是在这个汇编文件中定义的。

在header.s中,实现了内核启动执行main函数(如上文说的)之前做的动作,包括定义hdr变量并赋值,分配stack,然后调用main函数,以及内核不能正确启动的打印信息等等。

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值