arm linux 启动之一:汇编启动到start_kernel
描述arm linux啟動的概要過程,以S5PV210(Cortex A8)為例,本文描述第一個階段。
? ? ? ?一、arm linux的引導
? ? ? ?uboot在引導arm linux(uImage鏡像)到SDRAM之后,通過bootm命令對uImage鏡像的64個字節頭進行解釋,獲取linux的entry入口地址,并賦值給theKernel函數指針(一般該值是0x30008000),并將uboot的環境變量參數(如平臺的內存塊區域信息、linux啟動命令信息bootargs等)按linux要求的tags形式放置在0x30000100起始的地方。接著關掉MMU,清除icache,dcache,最后通過該函數將控制權交給arm linux:
? ? ? ?theKernel (0, machid, bd->bi_boot_params);
? ? ? ?其中,machid是平臺的id,其需要與arch/arm/tools/mach_types 中定義的機器ID一致,否則無法啟動。?bd->bi_boot_params即0x30000100,描述了linux啟動所需要的信息。
? ? ? ?二、arm linux啟動的第一部分
? ? ? ?該部分是體系相關的匯編部分,代碼位于arch\arm\kernel\head.S,入口是ENTRY(stext),其主要完成的工作包括:
? ? ? ?1) 設置當前arm工作模式是svc mode,關中斷
? ? ? ?2)__lookup_processor_type?獲取對應的CPU信息數據結構地址,主要是arm v7架構相關的信息,如MMU,cache標志值等,數據結構如下:
?
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體系架構,其描述在.proc.info.init 段,對應S5PV210即arch\arm\mm\proc-v7.S,?lookup_processor_type先通過協處理器CP15讀出CPU ID并跟cpu_val比較,匹配即可得到數據結構地址。該地址是鏈接到虛擬地址,而此時MMU是關閉的,需要將該地址轉為物理地址訪問。
? ? ? ? ?3)__lookup_machine_type獲取對應平臺機器的數據結構地址,主要是平臺板子相關的數據信息,如內存起始地址和大小,中斷和timer初始化函數等,如下:? ? ? ? ??
?
struct machine_desc {
?? unsigned int???nr;????? /* 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 段,對應S5PV210即\arch\arm\mach-s5pv210\mach-smdkv210.c。UBOOT的machid即用于搜索匹配nr,以取到機器信息。
? ? ? ? 4)檢查uboot傳遞過來的tags是否符合標準,并檢測machine數據結構的boot_params的值是否等于theKernel傳遞過來的第三個參數(0x30000100)
? ? ? ? 5)create_page_tables 創建臨時頁表,均是以1M為單位進行映射,所以4G空間需要16K,從0x30004000到0X30008000。共映射三個部分:
? ? ? ? ? ? ? ?i. linux內核鏡像空間的映射(0xc0008***開始的內核空間映射到0x30008***)
? ? ? ? ? ? ? ?ii. 創建頁表到開啟mmu之間還有一段代碼需要運行,因為還需要為linux啟動的初始1M空間創建一段直接映射,此時還是0X30008000+的地址運行,所以映射是0X30008000+映射到0X30008000+
? ? ? ? ? ? ? ?iii. uboot傳遞過來的tags參數也需要進行映射(虛擬0XC**映射到0X3**),以進行訪問。
? ? ? ? 6)ldr r13, __switch_data,將?__switch_data數據結構的地址入棧。
? ? ? ? 7)add?? pc,r10, #PROCINFO_INITFUNC,即將PC改到arch\arm\mm\proc-v7.S的?__v7_setup去執行,跳轉前將__enable_mmu放到lr,即?__v7_setup執行完就返回到__enable_mmu。?__v7_setup主要是CPU體系相關的初始化,如icache,dcache等。
? ? ? ? 8)__enable_mmu打開MMU,cache等,最后將r13出棧,取出arch/arm/kernel/head-common.S的__switch_data的第一個內容__mmap_switched函數,并賦給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等相關段,保存相關的數據結構地址到相關變量。設置以后系統啟動init進程的棧空間。
? ? ? ? 10)b? start_kernel 跳轉到linux啟動的第二部分,為C語言編寫。
轉載于:https://www.cnblogs.com/yueqian-scut/p/arm-linux-boot-1st.html
總結
以上是生活随笔為你收集整理的arm linux 启动之一:汇编启动到start_kernel的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 爱的手势舞是什么歌啊
- 下一篇: WPF中Auto与*的差别