平台移植的部分分析

来源:互联网 发布:天津教育出版社淘宝 编辑:程序博客网 时间:2024/04/19 23:22

 

Regulation:
Don’t care the multiple processor for the moment;
       All code analysis is based the ARM architecture;
2008-2-29
Begin from the setup_arch(), it is called by the start_kernel().
 
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_name = mdesc->name;
 
       if (mdesc->soft_reboot)
              reboot_setup("s");
 
       if (mdesc->boot_params)
              tags = phys_to_virt(mdesc->boot_params);
 
       /*
        * 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);
       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
}
 
setup_processor():This function get the processor information.
lookup_processor_type() It is defined in the file “head.s”, it get the processor information which defined in the proc-*.s. for example, in arch/arm/mm/proc-v6.s,define the armv6 processor information as follows:
__v6_proc_info:
       .long       0x0007b000
       .long       0x0007f000
       .long   PMD_TYPE_SECT | /
              PMD_SECT_BUFFERABLE | /
              PMD_SECT_CACHEABLE | /
              PMD_SECT_AP_WRITE | /
              PMD_SECT_AP_READ
       b     __v6_setup
       .long       cpu_arch_name
       .long       cpu_elf_name
       .long       HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_VFP|HWCAP_EDSP|HWCAP_JAVA
       .long       cpu_v6_name
       .long       v6_processor_functions
       .long       v6wbi_tlb_fns
       .long       v6_user_fns
       .long       v6_cache_fns
       .size __v6_proc_info, . - __v6_proc_info
If the processor is based ARMV6(The platform I used is MX31,it is based ARM11 that is ARMV6 architecture), after call the lookup_processor_type(), the variable list will point to the __v6_proc_info, the printk will print the processor information like this:
“CPU: Some Random V6 Processor [4107b364] revision 4 (ARMv6TEJ)”
At last, call the function cpu_proc_init(), it is defined in the file /include/asm-arm/cpu-multi32.h:
#define cpu_proc_init()                processor._proc_init()
The processor information is in the proc-v6.s, of course, the proc_init too, it is the cpu_v6_proc_init.
 
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();
       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;
#endif
#ifdef MULTI_USER
       cpu_user = *list->user;
#endif
#ifdef MULTI_CACHE
       cpu_cache = *list->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);
       sprintf(elf_platform, "%s%c", list->elf_name, ENDIANNESS);
       elf_hwcap = list->elf_hwcap;
 
       cpu_proc_init();
}
setup_machine(): just like the setup_processor(),it is get the machine descriptor, the machine descriptor is defined in the platform file which path is /arch/arm/mach-*/
static struct machine_desc * __init setup_machine(unsigned int nr)
{
       struct machine_desc *list;
 
       /*
        * locate machine in the list of supported machines.
        */
       list = lookup_machine_type(nr);
       if (!list) {
              printk("Machine configuration botched (nr %d), unable "
                     "to continue./n", nr);
              while (1);
       }
 
       printk("Machine: %s/n", list->name);
 
       return list;
}
lookup_machine_type(): it is defined in the head.s too.
The parameter machine_arch_type is defined in /include/asm-arm/Match-type.h, it is different in different platform.
 
reboot_setup(): Set the soft boot mode, my platform doesn’t initialize the soft_reboot, so it doesn’t call it.
If your platform have the boot parameter, the tags will point its address, otherwise it will point to the default tag init_tags. Because the boot parameter is physical address, it need to be change to virtual address.
       if (mdesc->boot_params)
              tags = phys_to_virt(mdesc->boot_params);
If we have a old style parameters, convert them to the tag list, if the conversion is fail, still use the default tags.
       if (tags->hdr.tag != ATAG_CORE)
              convert_to_tag_list(tags);
       if (tags->hdr.tag != ATAG_CORE)
              tags = (struct tag *)&init_tags;

 

原创粉丝点击