start_kernel 之 2

来源:互联网 发布:摩根华鑫证券知乎 编辑:程序博客网 时间:2024/06/10 14:57

linux-2.6.14/arch/arm/kernel/setup.c

 

void __init setup_arch(char **cmdline_p)

{

    struct tag *tags = (struct tag *)&init_tags;

    struct machine_desc *mdesc;

    char *from = default_command_line;

 

    setup_processor();

    mdesc = setup_machine(machine_arch_type);

    /*

       MACHINE_START(SMDK2410, "SMDK2410")

       .phys_ram  = S3C2410_SDRAM_PA,          //0x30000000

        .phys_io       = S3C2410_PA_UART,

        .io_pg_offst  = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,

        .boot_params  = S3C2410_SDRAM_PA + 0x100, //0x30000100

        .map_io       = smdk2410_map_io,

        .init_irq      = smdk2410_init_irq,

        .timer     = &s3c24xx_timer,

        .init_machine = smdk2410_init_lcd,

       MACHINE_END

    */

 

    machine_name = mdesc->name;        //SMDK2410

 

    if (mdesc->soft_reboot)

       reboot_setup("s");

 

    if (mdesc->boot_params)

       tags = phys_to_virt(mdesc->boot_params);

    /*

       #define PHYS_OFFSET      (0x30000000UL)

       #define PAGE_OFFSET      (0xC0000000UL)

       #define __phys_to_virt(x)   ((x) - PHYS_OFFSET + PAGE_OFFSET)

       #define __va(x)          ((void *)__phys_to_virt((unsigned long)(x)))

       static inline void *phys_to_virt(unsigned long x)

       {

           return (void *)(__phys_to_virt((unsigned long)(x)));

       }

       将引导参数存放位置从物理地址0x30000100转换到虚拟地址0xC0000100

 

 

    */

 

    /*

     * If we have the old style parameters, convert them to

     * a tag list.

     */

    if (tags->hdr.tag != ATAG_CORE)

       convert_to_tag_list(tags);

    if (tags->hdr.tag != ATAG_CORE)

       tags = (struct tag *)&init_tags;

 

    if (mdesc->fixup)    //此成员函数很少在处理器中有定义,所以为空

       mdesc->fixup(mdesc, tags, &from, &meminfo);

 

    if (tags->hdr.tag == ATAG_CORE) {

       if (meminfo.nr_banks != 0)

           squash_mem_tags(tags);

       parse_tags(tags);

    }

 

    init_mm.start_code = (unsigned long) &_text;

    init_mm.end_code   = (unsigned long) &_etext;

    init_mm.end_data   = (unsigned long) &_edata;

    init_mm.brk      = (unsigned long) &_end;

 

    memcpy(saved_command_line, from, COMMAND_LINE_SIZE);

    saved_command_line[COMMAND_LINE_SIZE-1] = '/0';

 

    parse_cmdline(cmdline_p, from);

/*

    mdesc->fixup = 0

    tags->hdr.tag = 1413545985

    _text = c0029000, _etext = c031de18, _edata = c03828f0, _end = c03abc70

*/

 

    paging_init(&meminfo, mdesc);

    request_standard_resources(&meminfo, mdesc);

 

    cpu_init();

 

    /*

     * Set up various architecture-specific pointers

     */

    init_arch_irq = mdesc->init_irq;

    system_timer = mdesc->timer;

    init_machine = mdesc->init_machine;

 

#ifdef CONFIG_VT

#if defined(CONFIG_VGA_CONSOLE)

    conswitchp = &vga_con;

#elif defined(CONFIG_DUMMY_CONSOLE)

    conswitchp = &dummy_con;

#endif

#endif

}

 

 

static void __init setup_processor(void)

{

    struct proc_info_list *list;

 

    /*

     * locate processor in the list of supported processor

     * types.  The linker builds this table for us from the

     * entries in arch/arm/mm/proc-*.S

     */

    list = lookup_processor_type();

    /*

       根据汇编代码中获取的ARM处理器的主ID寄存器的值processor_id,从.proc.info

       中找到该处理器对应的处理器信息结构struct proc_info_list型变量

    */

 

    if (!list) {

       printk("CPU configuration botched (ID %08x), unable "

              "to continue./n", processor_id);

       while (1);

    }

 

    cpu_name = list->cpu_name;      //处理器名字

 

#ifdef MULTI_CPU

    processor = *list->proc;        //处理器处理函数组结构指针

#endif

#ifdef MULTI_TLB

    cpu_tlb = *list->tlb;           //TLB操作函数组结构指针

#endif

#ifdef MULTI_USER

    cpu_user = *list->user;         //处理器用户空间操作函数组

#endif

#ifdef MULTI_CACHE

    cpu_cache = *list->cache;       //cache操作函数组

#endif

 

    printk("CPU: %s [%08x] revision %d (ARMv%s)/n",

           cpu_name, processor_id, (int)processor_id & 15,

           proc_arch[cpu_architecture()]);

 

 

 

//打印出上图中第四行的信息。

 

    sprintf(system_utsname.machine, "%s%c", list->arch_name, ENDIANNESS);

    //保存处理器架构名字字符串加”b”big endian)或”l”little endian

    sprintf(elf_platform, "%s%c", list->elf_name, ENDIANNESS);

    //保存体系架构名字字符串加”b”big endian)或”l”little endian

    elf_hwcap = list->elf_hwcap;

    //保存处理器硬件能力标志字

    cpu_proc_init();

    //处理器初始化函数指针,ARM体系下基本什么也不做

}

 

 

#define MACH_TYPE_SMDK2410             193

#ifdef CONFIG_ARCH_SMDK2410

# ifdef machine_arch_type

#  undef machine_arch_type

#  define machine_arch_type  __machine_arch_type

# else

#  define machine_arch_type  MACH_TYPE_SMDK2410

# endif

# define machine_is_smdk2410()  (machine_arch_type == MACH_TYPE_SMDK2410)

#else

# define machine_is_smdk2410()  (0)

#endif

 

mdesc = setup_machine(machine_arch_type)  // machine_arch_type = 193

static struct machine_desc * __init setup_machine(unsigned int nr)

{

    struct machine_desc *list;

 

    list = lookup_machine_type(nr);

    /*

       根据machine_arch_type(193)从当前系统的硬件平台编号从.arch.info中找到其对应    的平台描述结构machine_desc型变量。

    */

 

    if (!list) {

       printk("Machine configuration botched (nr %d), unable "

              "to continue./n", nr);

       while (1);

    }

 

    printk("Machine: %s/n", list->name);

 

//打印出上图中第五行的信息。

 

    return list;

}

原创粉丝点击