<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計應(yīng)用 > arm linux 啟動之一:匯編啟動到start_kernel

          arm linux 啟動之一:匯編啟動到start_kernel

          作者: 時間:2016-11-09 來源:網(wǎng)絡(luò) 收藏
          描述arm linux啟動的概要過程,以S5PV210(Cortex A8)為例,本文描述第一個階段。

          一、arm linux的引導(dǎo)

          本文引用地址:http://www.ex-cimer.com/article/201611/318003.htm

          uboot在引導(dǎo)arm linux(uImage鏡像)到SDRAM之后,通過bootm命令對uImage鏡像的64個字節(jié)頭進(jìn)行解釋,獲取linux的entry入口地址,并賦值給theKernel函數(shù)指針(一般該值是0x38),并將uboot的環(huán)境變量參數(shù)(如平臺的內(nèi)存塊區(qū)域信息、linux啟動命令信息bootargs等)按linux要求的tags形式放置在0x30100起始的地方。接著關(guān)掉MMU,清除icache,dcache,最后通過該函數(shù)將控制權(quán)交給arm linux:

          theKernel (0, machid, bd->bi_boot_params);

          其中,machid是平臺的id,其需要與arch/arm/tools/mach_types 中定義的機(jī)器ID一致,否則無法啟動。bd->bi_boot_params即0x30100,描述了linux啟動所需要的信息。

          二、arm linux啟動的第一部分

          該部分是體系相關(guān)的匯編部分,代碼位于archarmkernelhead.S,入口是ENTRY(stext),其主要完成的工作包括:

          1) 設(shè)置當(dāng)前arm工作模式是svc mode,關(guān)中斷

          2)__lookup_processor_type獲取對應(yīng)的CPU信息數(shù)據(jù)結(jié)構(gòu)地址,主要是arm v7架構(gòu)相關(guān)的信息,如MMU,cache標(biāo)志值等,數(shù)據(jù)結(jié)構(gòu)如下:

          struct proc_info_list {

          unsigned int cpu_val;

          unsigned int cpu_mask;

          unsigned long__cpu_mm_mmu_flags; /* used by head.S */

          unsigned long__cpu_io_mmu_flags; /* used by head.S */

          unsigned long__cpu_flush; /* used by head.S */

          const char *arch_name;

          const char *elf_name;

          unsigned int elf_hwcap;

          const char *cpu_name;

          struct processor *proc;

          struct cpu_tlb_fns *tlb;

          struct cpu_user_fns *user;

          struct cpu_cache_fns *cache;

          };

          arm linux支持各種CPU體系架構(gòu),其描述在.proc.info.init 段,對應(yīng)S5PV210即archarmmmproc-v7.S,lookup_processor_type先通過協(xié)處理器CP15讀出CPU ID并跟cpu_val比較,匹配即可得到數(shù)據(jù)結(jié)構(gòu)地址。該地址是鏈接到虛擬地址,而此時MMU是關(guān)閉的,需要將該地址轉(zhuǎn)為物理地址訪問。

          3)__lookup_machine_type獲取對應(yīng)平臺機(jī)器的數(shù)據(jù)結(jié)構(gòu)地址,主要是平臺板子相關(guān)的數(shù)據(jù)信息,如內(nèi)存起始地址和大小,中斷和timer初始化函數(shù)等,如下:

          struct machine_desc {

          unsigned intnr; /* architecture number */

          unsigned int phys_io; /* start of physicalio */

          unsigned int io_pg_offst; /* byte offsetfor io * page tabe entry */

          const char *name;/* architecture name */

          unsigned long boot_params; /*tagged list */

          unsigned int video_start; /* start of videoRAM */

          unsigned int video_end; /* end ofvideo RAM */

          unsigned int reserve_lp0 :1; /* never haslp0 */

          unsigned int reserve_lp1 :1; /* never haslp1 */

          unsigned int reserve_lp2 :1; /* never haslp2 */

          unsigned int soft_reboot :1; /* softreboot */

          void(*fixup)(struct machine_desc *, struct tag *, char **, struct meminfo *);

          void(*map_io)(void);/* IO mapping function */

          void(*init_irq)(void);

          struct sys_timer *timer;/* system tick timer */

          void(*init_machine)(void);

          };

          arm linux支持各種平臺板子,其描述在.arch.info.init 段,對應(yīng)S5PV210即archarmmach-s5pv210mach-smdkv210.c。UBOOT的machid即用于搜索匹配nr,以取到機(jī)器信息。

          4)檢查uboot傳遞過來的tags是否符合標(biāo)準(zhǔn),并檢測machine數(shù)據(jù)結(jié)構(gòu)的boot_params的值是否等于theKernel傳遞過來的第三個參數(shù)(0x30100)

          5)create_page_tables 創(chuàng)建臨時頁表,均是以1M為單位進(jìn)行映射,所以4G空間需要16K,從0x34到0X38。共映射三個部分:

          i. linux內(nèi)核鏡像空間的映射(0xc8***開始的內(nèi)核空間映射到0x38***)

          ii. 創(chuàng)建頁表到開啟mmu之間還有一段代碼需要運(yùn)行,因?yàn)檫€需要為linux啟動的初始1M空間創(chuàng)建一段直接映射,此時還是0X38+的地址運(yùn)行,所以映射是0X38+映射到0X38+

          iii. uboot傳遞過來的tags參數(shù)也需要進(jìn)行映射(虛擬0XC**映射到0X3**),以進(jìn)行訪問。

          6)ldr r13, __switch_data,將__switch_data數(shù)據(jù)結(jié)構(gòu)的地址入棧。

          7)add pc,r10, #PROCINFO_INITFUNC,即將PC改到archarmmmproc-v7.S的__v7_setup去執(zhí)行,跳轉(zhuǎn)前將__enable_mmu放到lr,即__v7_setup執(zhí)行完就返回到__enable_mmu。__v7_setup主要是CPU體系相關(guān)的初始化,如icache,dcache等。

          8)__enable_mmu打開MMU,cache等,最后將r13出棧,取出arch/arm/kernel/head-common.S的__switch_data的第一個內(nèi)容__mmap_switched函數(shù),并賦給PC:

          __switch_data:

          .long __mmap_switched

          .long__data_loc @ r4

          .long_data @ r5

          .long __bss_start @r6

          .long_end @ r7

          .long processor_id @ r4

          .long __machine_arch_type @ r5

          .long __atags_pointer @r6

          .long cr_alignment @ r7

          .long init_thread_union + THREAD_START_SP @ sp

          9)__mmap_switched初始化data,bss等相關(guān)段,保存相關(guān)的數(shù)據(jù)結(jié)構(gòu)地址到相關(guān)變量。設(shè)置以后系統(tǒng)啟動init進(jìn)程的??臻g。

          10)b start_kernel 跳轉(zhuǎn)到linux啟動的第二部分,為C語言編寫。



          關(guān)鍵詞: armlinux啟

          評論


          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();