Linux arm Æô¶¯ cÓïÑÔ²¿·ÖÏê½âµÚÒ»½²(from Start kernel) ÏÂÔØ±¾ÎÄ

ÄÚÈÝ·¢²¼¸üÐÂʱ¼ä : 2026/4/5 22:18:51ÐÇÆÚÒ» ÏÂÃæÊÇÎÄÕµÄÈ«²¿ÄÚÈÝÇëÈÏÕæÔĶÁ¡£

[Ô­´´]Linux arm Æô¶¯ cÓïÑÔ²¿·ÖÏê½âµÚÒ»½²£¨from Start kernel£©

?? ??

??written by leeming ??

??×÷ΪÎÒÃÇʵÑéÊÒµÄÒ»¸öѧÊõ½»Á÷£¬ÎÒ˳×ÅfpµÄlinux armÆô¶¯»ã±à²¿·Ö¼ÌÐøÏÂÈ¥¡£ÎÒÃÇ¿ÉÒÔ¿´µ½Æäʵlinux»ã±à²¿·ÖµÄÆô¶¯´óÁ¿µÄ¹¤×÷ÊǶÔzimageµÄ½âѹ£¬Öض¨Î»µÈ²Ù×÷£¬Èç¹ûÊÇimage£¨Ò²¾ÍÊÇzimage½âÑ¹ÖØ¶¨Î»½áÊøºó£©À´Ëµ£¬ÆäʵÖ÷Òª¾Í×öÁËÒÔÏÂÕâô¼¸¼þÊÂÇ飺1.½¨Á¢Æô¶¯Ê±µÄÒ»¼¶Ò³±í£¬2.´ò¿ªmmu£¬3.±£´æ»úÆ÷ºÅµÈ²ÎÊý¡£ ??

??Òò´Ë¶ÔÓÚÕû¸ö´¦ÀíÆ÷ϵͳÀ´Ëµ»¹ÐèÒª×ö´óÁ¿µÄ¹¤×÷£¬¶ÔÓÚÒÆÖ²ÄÚºËÀ´Ëµ£¬Ö»ÓÐÕæÕýÁ˽âÁËÕⲿ·ÖÄã²Å»áÃ÷°×ÔÚarch/arm/mach-sep4020Õâ¸öĿ¼ÖеÄÎļþΪʲôÐèÒªÕâÑùд¡£½øÈëÕýÌ⣺ ??

??1.½øÈëstart_kernel£¬Ïê½âsetup_arch£¨´¦ÀíÆ÷µÄÒÆÖ²£¬Ò³±í½¨Á¢¶¼ÔÚÕâÀïʵÏֵģ© ??

??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(); ?? ?? ??

??       //ÕâÀïÊǺ͸߶ËÄÚ´æÏà¹ØµÄ²Ù×÷£¬armÖв»Éæ¼° ??

??       page_address_init(); ??

??       //Õâ¸öÖ»ÊÇprintkµÄµÈ¼¶£¬µ«ÊÇΪʲôÔÚ¿ØÖÆÌ¨²»ÏÔʾ£¬´ý¿´ ??

??       //Õâʱºò¿ØÖÆÌ¨»¹Ã»Óгõʼ»¯£¬Òò´ËËùÓеÄÐÅÏ¢¶¼ÊÇÔÚ

log_bufÀï ??

??       printk(KERN_NOTICE); ??

??       printk(linux_banner); ??

??       setup_arch(&command_line); ??

??       ¡­¡­ ??

??       ¡­¡­ ?? ?? ??

??µ½ÕâÀï¾ÍÅöµ½ÁËÎÒÃÇÏê½âstart kernelµÄµÚÒ»µÀ¿²£¬setup_arch(&command_line);±ð¿´¾ÍÒ»¾ä»°£¬ÆäʵÕâ¸öº¯Êý±¾ÉíÊǷdz£ÅÓ´óµÄ£¬ÏÂÃæÎÒÃÇÀ´¾ßÌå¿´ÍêÕûµÄsetup_archº¯Êý¡£ ??

??void __init setup_arch(char **cmdline_p) ?? ??{ ??

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

?? struct machine_desc *mdesc; ??

??//in the arch/arm/kernel/setup.c ??

??//static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE; ??

??//ÔÚÎÒÃǵÄÅäÖÃÖÐ#define CONFIG_CMDLINE "root=/dev/ram0 rw console=ttyS0,115200" ??

?? char *from = default_command_line; ??

?? //¾ÍÊDzéÕÒÄãÊÇʲô°æ±¾µÄ´¦ÀíÆ÷¼Ü¹¹£¬×îºó¾ÍÊǵ÷Óà ??

?? //ÁËlookup_processor_typeÕâ¸öº¯Êý£¬ËüÔÚ»ã±à²¿·ÖÒ²Ìáµ½¹ý ??

?? setup_processor(); ??

?? //machine_arch_type ¾ÍÊÇÎÒÃǵĻúÆ÷ºÅ0xc2 ??

?? mdesc = setup_machine(machine_arch_type);

??

?? machine_name = mdesc->name; ??

?? //Õâ¸ö±äÁ¿³õʼֵΪ"h",Èç¹ûÕâÀïÉèÖóÉsoftboot£¬Ëü»á½«Õâ¸ö³õʼֵ±äΪ"s" ??

?? if (mdesc->soft_reboot) ??

??  reboot_setup("s"); ??

?? //boot_params Èç¹ûΪ0Ôò±íʾbootloaderûÓд«²ÎÊý ??

?? //Ò»°ãĬÈÏΪ0x30000100λÖà ??

?? 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); ??

?? //ÊÇͨ¹ý±êÇ©0x544100**À´±æ±ðµÄ£¬Òò´ËubootÖÐÓÐÏàÓ¦µÄ±êÇ©×Ö ??

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

??  //ÒѾ­±»fixupº¯ÊýÐ޸ģ¬Ôò½«atagÖеÄmem¶ÎÖÃΪnone ??

??  if (meminfo.nr_banks != 0) ??

??   squash_mem_tags(tags); ??

??  //¼ÌÐø°ÑatagµÄ²ÎÊý´«µÝ½áÊø£¬ÔÚÕâÀォ°Ñuboot´«µÝ½øÀ´µÄcommandline¸²¸Ç ??

??  parse_tags(tags); ?? ?? } ??

??//ÏÂÃæ¼¸¸ö²ÎÊýÊÇÓÉvmlinux.ldsÎļþ¾ö¶¨µÄ ??

?? 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; ??

?? //Òò´ËÔÚÕâÀïÒѾ­ÊÇÎÒÃÇubootµÄ²ÎÊýÁË¡£ ??

?? memcpy(saved_command_line, from, COMMAND_LINE_SIZE); ??

?? saved_command_line[COMMAND_LINE_SIZE-1] = ¡®\\0¡¯; ??

??//·ÖÎöcmdline£¬ÕâÀïÖ»·ÖÎöÁ˵±ÖеÄmem²¿·Ö¡£ ??

??//Äں˲ÎÊýµÄ½âÎöÒ»¹²ÓÐÁ½´¦£¬Ò»´¦ÊÇsetup_arch()->parse_cmdline() ??

??//ÓÃÓÚ½âÎöÄں˲ÎÊýÖйØÓÚÄÚ´æµÄ²¿·Ö£¬ÁíÍâÒ»´¦ÊÇstart_kernel()->parse_option()ÓÃÓÚ½âÎöÆäÓಿ·Ö ??

?? parse_cmdline(cmdline_p, from); ?? ?? ??

??//·Ç³£ÖØÒªµÄ²¿·Ö£¬Ò³±í½¨Á¢,¸ù¾Ýmeminfo£¬Ò²¾ÍÊÇÎÒÃÇÔÚ4020.cÖеÄmache_startºÎmache_endÖ®¼äµÄÄÚÈÝ£¬ËüÆäʵ¾ÍÊÇÒ»¸öÀàÐÍÊÇmachine_descµÄ½á¹¹Ì壬ÕâÀï¾ÍÊǰÑÕâ¸ö½á¹¹ÌåÖеÄÄÚ´æÐÅÏ¢£¨fixupº¯ÊýÖÐÖ¸¶¨µÄ£©£¬¼Ä´æÆ÷ÐÅÏ¢£¨sep4020_map_ioÖ¸¶¨µÄ£©½¨Á¢ÏàÓ¦µÄÒ»¶þ¼¶Ò³±í ??

??/*************************************/

??

??       paging_init(&meminfo, mdesc); ??

??/*************************************/ ??

??       request_standard_resources(&meminfo, mdesc); ?? ?? ??

??#ifdef CONFIG_SMP ??

??       smp_init_cpus(); ??

??#endif ?? ?? ??

??//ÉèÖò»Í¬Ä£Ê½µÄ¶ÑÕ»£¬°üÀ¨3ÖÖģʽ£¬irq,abort,undefine£¬Ã¿ÖÖģʽµÄ¶ÑÕ»ÊÇ12¸ö×Ö½Ú ??

??       cpu_init(); ?? ??{ ??

??       //gccÄÚǶ»ã±àµÄ¸ñʽÊÇ__asm(»ã±à´úÂë:ÊäÈë:Êä³ö:ÆÆ»µÃèÊö²¿·Ö); ??

??       //ÏÂÃæµÄÏÞÖÆ×Ö·û"r" "I"ÊǰѱäÁ¿·Å½øÍ¨ÓüĴæÆ÷£¬Á¢¼´ÊýµÄÒâ˼ ??

??       __asm__ ( ??

??       "msr       cpsr_c, %1\\n\\t" ??

??       "add      sp, %0, %2\\n\\t" ??

??       "msr       cpsr_c, %3\\n\\t" ??

??       "add      sp, %0, %4\\n\\t" ??

??       "msr       cpsr_c, %5\\n\\t" ??

??       "add      sp, %0, %6\\n\\t" ??

??       "msr       cpsr_c, %7"