国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Linux > 正文

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

2024-06-28 13:23:53
字體:
來源:轉載
供稿:網友
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 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 段,對應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進程的??臻g。

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


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 宁安市| 息烽县| 鹤壁市| 玉溪市| 松原市| 南丰县| 海盐县| 锦屏县| 云和县| 南漳县| 寻甸| 元氏县| 陵水| 平安县| 故城县| 绵竹市| 高要市| 莎车县| 马公市| 鹤庆县| 辰溪县| 邳州市| 康平县| 佛坪县| 邹城市| 苏尼特右旗| 湖南省| 鹤岗市| 綦江县| 若羌县| 海宁市| 荣成市| 阿拉尔市| 金坛市| 沙河市| 安塞县| 长葛市| 都安| 东海县| 永德县| 鸡泽县|