国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
[原創(chuàng)]Linux arm 啟動 c語言部分詳解第一講(from Start kernel) - 安裝啟動 - 文檔專區(qū) - Linux論壇
ritten by leeming
作為我們實驗室的一個學(xué)術(shù)交流,我順著fp的linux arm啟動匯編部分繼續(xù)下去。我們可以看到其實linux匯編部分的啟動大量的工作是對zimage的解壓,重定位等操作,如果是image(也就是zimage解壓重定位結(jié)束后)來說,其實主要就做了以下這么幾件事情:1.建立啟動時的一級頁表,2.打開mmu,3.保存機器號等參數(shù)。
因此對于整個處理器系統(tǒng)來說還需要做大量的工作,對于移植內(nèi)核來說,只有真正了解了這部分你才會明白在arch/arm/mach-sep4020這個目錄中的文件為什么需要這樣寫。進入正題:
1.進入start_kernel,詳解setup_arch(處理器的移植,頁表建立都在這里實現(xiàn)的)
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();

       //這里是和高端內(nèi)存相關(guān)的操作,arm中不涉及
       page_address_init();
       //這個只是printk的等級,但是為什么在控制臺不顯示,待看
       //這時候控制臺還沒有初始化,因此所有的信息都是在log_buf里
       printk(KERN_NOTICE);
       printk(linux_banner);
       setup_arch(&command_line);
       ……
       ……

到這里就碰到了我們詳解start kernel的第一道坎,setup_arch(&command_line);別看就一句話,其實這個函數(shù)本身是非常龐大的,下面我們來具體看完整的setup_arch函數(shù)。
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;
//就是查找你是什么版本的處理器架構(gòu),最后就是調(diào)用
//了lookup_processor_type這個函數(shù),它在匯編部分也提到過
setup_processor();
//machine_arch_type 就是我們的機器號0xc2
mdesc = setup_machine(machine_arch_type);
machine_name = mdesc->name;
//這個變量初始值為"h",如果這里設(shè)置成softboot,它會將這個初始值變?yōu)?s"
if (mdesc->soft_reboot)
  reboot_setup("s");
//boot_params 如果為0則表示bootloader沒有傳參數(shù)
//一般默認(rèn)為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);
//是通過標(biāo)簽0x544100**來辨別的,因此uboot中有相應(yīng)的標(biāo)簽字
if (tags->hdr.tag == ATAG_CORE) {
  //已經(jīng)被fixup函數(shù)修改,則將atag中的mem段置為none
  if (meminfo.nr_banks != 0)
   squash_mem_tags(tags);
  //繼續(xù)把atag的參數(shù)傳遞結(jié)束,在這里將把uboot傳遞進來的commandline覆蓋
  parse_tags(tags);
}
//下面幾個參數(shù)是由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;
//因此在這里已經(jīng)是我們uboot的參數(shù)了。
memcpy(saved_command_line, from, COMMAND_LINE_SIZE);
saved_command_line[COMMAND_LINE_SIZE-1] = '\0';
//分析cmdline,這里只分析了當(dāng)中的mem部分。
//內(nèi)核參數(shù)的解析一共有兩處,一處是setup_arch()->parse_cmdline()
//用于解析內(nèi)核參數(shù)中關(guān)于內(nèi)存的部分,另外一處是start_kernel()->parse_option()用于解析其余部分
parse_cmdline(cmdline_p, from);

//非常重要的部分,頁表建立,根據(jù)meminfo,也就是我們在4020.c中的mache_start何mache_end之間的內(nèi)容,它其實就是一個類型是machine_desc的結(jié)構(gòu)體,這里就是把這個結(jié)構(gòu)體中的內(nèi)存信息(fixup函數(shù)中指定的),寄存器信息(sep4020_map_io指定的)建立相應(yīng)的一二級頁表
/*************************************/
       paging_init(&meminfo, mdesc);
/*************************************/
       request_standard_resources(&meminfo, mdesc);

#ifdef CONFIG_SMP
       smp_init_cpus();
#endif

//設(shè)置不同模式的堆棧,包括3種模式,irq,abort,undefine,每種模式的堆棧是12個字節(jié)
       cpu_init();
{
       //gcc內(nèi)嵌匯編的格式是__asm(匯編代碼:輸入:輸出:破壞描述部分);
       //下面的限制字符"r" "I"是把變量放進通用寄存器,立即數(shù)的意思
       __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"
           :
           : "r" (stk),//堆棧空間起始地址
             "I" (PSR_F_BIT | PSR_I_BIT | IRQ_MODE),//切換到irq模式,并禁止irq fiq
             "I" (offsetof(struct stack, irq[0])),//irq[0]的偏移,一下同理
             "I" (PSR_F_BIT | PSR_I_BIT | ABT_MODE),
             "I" (offsetof(struct stack, abt[0])),
             "I" (PSR_F_BIT | PSR_I_BIT | UND_MODE),
             "I" (offsetof(struct stack, und[0])),
             "I" (PSR_F_BIT | PSR_I_BIT | SVC_MODE)
           : "r14");//注意切換svc時,告訴系統(tǒng),r14改變了
}
       /*
        * Set up various architecture-specific pointers
        */

//繼續(xù)將020.c中的mache_start何mache_end之間的內(nèi)容注冊到系統(tǒng)中,這里是把系統(tǒng)初始化函數(shù),中斷,定時器注冊(這幾部分也就是在為一個新的處理器移植內(nèi)核的時候非常重要的地方)
       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_arch函數(shù)解釋完畢,由于setup_arch中還有一個重要函數(shù)paging_init函數(shù)也蠻龐大的,因此在第二講中詳細(xì)說明這個函數(shù)。
本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
淺談分析Arm linux 內(nèi)核移植及系統(tǒng)初始化的過程
[z]Arm linux kernel 啟動之start_kenel
linux 啟動代碼分析--kevy
uClinux cmdline分析以及rootfs掛載
嵌入式Linux內(nèi)核移植相關(guān)代碼分析(zz)
中斷代碼跟蹤
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服