娇小w搡bbbb搡bbb,《第一次の人妻》,中国成熟妇女毛茸茸,边啃奶头边躁狠狠躁视频免费观看

ARM Linux內核啟動過程

發布者:溫馨陽光最新更新時間:2024-09-25 來源: elecfans關鍵字:ARM  Linux 手機看文章 掃描二維碼
隨時隨地手機看文章

LinuxKernelStartARM  

ARM Linux內核啟動過程.

Updated Feb 24, 2011 by swordhui...@gmail.com

注: 本文轉自ChinaUnix 作者為XPL.

本文針對arm linux, 從kernel的第一條指令開始分析,一直分析到進入 start_kernel()函數. 我們當前以linux-2.6.19內核版本作為范例來分析,本文中所有的代碼,前面都會加上行號以便于和源碼進行對照, 例: 在文件init/main.c中: 00478: asmlinkage void init start_kernel(void) 前面的'00478:' 表示478行,冒號后面的內容就是源碼了.

在分析代碼的過程中,我們使用縮進來表示各個代碼的調用層次.

由于啟動部分有一些代碼是平臺特定的,雖然大部分的平臺所實現的功能都比較類似,但是為了更好的對code進行說明,對于平臺相關的代碼,我們選擇 at91(ARM926EJS)平臺進行分析.

另外,本文是以uncompressed kernel開始講解的.對于內核解壓縮部分的code,在 arch/arm/boot/compressed中,本文不做討論.

一. 啟動條件

通常從系統上電到執行到linux kenel這部分的任務是由boot loader來完成. 關于boot loader的內容,本文就不做過多介紹. 這里只討論進入到linux kernel的時候的一些限制條件,這一般是boot loader在最后跳轉到kernel之前要完成的:
  • 1. CPU必須處于SVC(supervisor)模式,并且IRQ和FIQ中斷都是禁止的;

  • 2. MMU(內存管理單元)必須是關閉的, 此時虛擬地址對物理地址;

  • 3. 數據cache(Data cache)必須是關閉的

  • 4. 指令cache(Instruction cache)可以是打開的,也可以是關閉的,這個沒有強制要求;

  • 5. CPU 通用寄存器0 (r0)必須是 0;

  • 6. CPU 通用寄存器1 (r1)必須是 ARM Linux machine type (關于machine type, 我們后面會有講解)

  • 7. CPU 通用寄存器2 (r2) 必須是 kernel parameter list 的物理地址(parameter list 是由boot loader傳遞給kernel,用來描述設備信息屬性的列表,詳細內容可參考'Booting ARM Linux'文檔).

二. starting kernel

首先,我們先對幾個重要的宏進行說明(我們針對有MMU的情況):

位置默認值說明
KERNEL_RAM_ADDRarch/arm/kernel/head.S +260xc0008000kernel在RAM中的的虛擬地址
PAGE_OFFSETinclude/asm-arm/memeory.h +500xc0000000內核空間的起始虛擬地址
TEXT_OFFSETarch/arm/Makefile +1370x00008000內核相對于存儲空間的偏移
TEXTADDRarch/arm/kernel/head.S +490xc0008000kernel的起始虛擬地址
PHYS_OFFSETinclude/asm-arm/arch-xxx/memory.h平臺相關RAM的起始物理地址
內核的入口是stext,這是在arch/arm/kernel/vmlinux.lds.S中定義的:

        00011: ENTRY(stext)

對于vmlinux.lds.S,這是ld script文件,此文件的格式和匯編及C程序都不同,本文不對ld script作過多的介紹,只對內核中用到的內容進行講解,關于ld的詳細內容可以參考ld.info 這里的ENTRY(stext) 表示程序的入口是在符號stext. 而符號stext是在arch/arm/kernel/head.S中定義的: 下面我們將arm linux boot的主要代碼列出來進行一個概括的介紹,然后,我們會逐個的進行詳細的講解.

 

在arch/arm/kernel/head.S中 72 - 94 行,是arm linux boot的主代碼: 00072: ENTRY(stext)                                                        
00073:         msr        cpsr_c, #PSR_F_BIT | PSR_I_BIT | SVC_MODE @ ensure svc mode
00074:                                                 @ and irqs disabled        
00075:         mrc        p15, 0, r9, c0, c0                @ get processor id         
00076:         bl        __lookup_processor_type                @ r5=procinfo r9=cpuid     
00077:         movs        r10, r5                                @ invalid processor (r5=0)?
00078:         beq        __error_p                        @ yes, error 'p'           
00079:         bl        __lookup_machine_type                @ r5=machinfo              
00080:         movs        r8, r5                                @ invalid machine (r5=0)?  
00081:         beq        __error_a                        @ yes, error 'a'           
00082:         bl        __create_page_tables                                       
00083:                                                                     
00084:         /*                                                                 
00085:          * The following calls CPU specific code in a position independent
00086:          * manner.  See arch/arm/mm/proc-*.S for details.  r10 = base of   
00087:          * xxx_proc_info structure selected by __lookup_machine_type      
00088:          * above.  On return, the CPU will be ready for the MMU to be      
00089:          * turned on, and r0 will hold the CPU control register value.     
00090:          */                                                               
00091:         ldr        r13, __switch_data                @ address to jump to after
00092:                                                 @ mmu has been enabled     
00093:         adr        lr, __enable_mmu                @ return (PIC) address     
00094:         add        pc, r10, #PROCINFO_INITFUNC                                

其中,73行是確保kernel運行在SVC模式下,并且IRQ和FIRQ中斷已經關閉,這樣做是很謹慎的.

arm linux boot的主線可以概括為以下幾個步驟:

  • 1. 確定 processor type (75 - 78行)

  • 2. 確定 machine type (79 - 81行)

  • 3. 創建頁表 (82行)

  • 4. 調用平臺特定的cpu_flush函數 (在struct proc_info_list中) (94 行)

  • 5. 開啟mmu (93行)

  • 6. 切換數據 (91行)

最終跳轉到start_kernel (在switch_data的結束的時候,調用了 b start_kernel)

下面,我們按照這個主線,逐步的分析Code.

1. 確定 processor type

 

arch/arm/kernel/head.S中:

00075:         mrc        p15, 0, r9, c0, c0                @ get processor id         
00076:         bl        __lookup_processor_type                @ r5=procinfo r9=cpuid     
00077:         movs        r10, r5                                @ invalid processor (r5=0)?
00078:         beq        __error_p                        @ yes, error 'p'          

75行: 通過cp15協處理器的c0寄存器來獲得processor id的指令. 關于cp15的詳細內容可參考相關的arm手冊

76行: 跳轉到lookup_processor_type.在lookup_processor_type中,會把processor type 存儲在r5中

77,78行: 判斷r5中的processor type是否是0,如果是0,說明是無效的processor type,跳轉到error_p(出錯)

lookup_processor_type 函數主要是根據從cpu中獲得的processor id和系統中的proc_info進行匹配,將匹配到的proc_info_list的基地址存到r5中, 0表示沒有找到對應的processor type.

下面我們分析lookup_processor_type函數

arch/arm/kernel/head-common.S中:

00145:         .type        __lookup_processor_type, %function
00146: __lookup_processor_type:
00147:         adr        r3, 3f
00148:         ldmda        r3, {r5 - r7}
00149:         sub        r3, r3, r7                        @ get offset between virt&phys
00150:         add        r5, r5, r3                        @ convert virt addresses to
00151:         add        r6, r6, r3                        @ physical address space
00152: 1:        ldmia        r5, {r3, r4}                        @ value, mask
00153:         and        r4, r4, r9                        @ mask wanted bits
00154:         teq        r3, r4
00155:         beq        2f
00156:         add        r5, r5, #PROC_INFO_SZ                @ sizeof(proc_info_list)
00157:         cmp        r5, r6
00158:         blo        1b
00159:         mov        r5, #0                                @ unknown processor
00160: 2:        mov        pc, lr
00161:
00162: /*
00163:  * This provides a C-API version of the above function.
00164:  */
00165: ENTRY(lookup_processor_type)
00166:         stmfd        sp!, {r4 - r7, r9, lr}
00167:         mov        r9, r0
00168:         bl        __lookup_processor_type
00169:         mov        r0, r5
00170:         ldmfd        sp!, {r4 - r7, r9, pc}
00171:
00172: /*
00173:  * Look in include/asm-arm/procinfo.h and arch/arm/kernel/arch.[ch] for
00174:  * more information about the __proc_info and __arch_info structures.
00175:  */
00176:         .long        __proc_info_begin
00177:         .long        __proc_info_end
00178: 3:        .long        .
00179:         .long        __arch_info_begin
00180:         .long        __arch_info_end

[1] [2] [3] [4] [5] [6]
關鍵字:ARM  Linux 引用地址:ARM Linux內核啟動過程

上一篇:玩轉S3C6410之一 交叉工具鏈制作(gcc4.5.1-armv6-vfp)
下一篇:s3c6410學習筆記-燒寫uboot+構建文件系統

推薦閱讀最新更新時間:2025-06-16 17:04

ARM矩陣鍵盤設計及其linux驅動實現
在嵌入式系統開發中,經常通過鍵盤來實現人機交互。本文介紹了一種直接利用ARM的I/O口擴展矩陣鍵盤的方法。同時以TQ2440開發板為例,對硬件電路連接和相應的linux驅動設計方法都作了詳細說明。 1.引言 ARM微處理器已廣泛應用于工業控制、消費類電子產品、通信系統等領域。矩陣鍵盤是一種常用的鍵盤形式,它將按鍵設計成M行N列,這樣共需M+N根信號線,卻可驅動M×N個按鍵,大大節約了I/O資源。本文介紹了一種利用TQ2440開發板的GPIO口擴展5×4矩陣鍵盤的方法,并將所有按鍵重新布局成手持終端的鍵盤形式,方便操作。 2.硬件設計 本設計擴展5行4列的矩陣鍵盤,如圖1所示。其中行線ROW1-ROW5連接S3C24
[單片機]
<font color='red'>ARM</font>矩陣鍵盤設計及其<font color='red'>linux</font>驅動實現
ARM Linux中斷分析
簡介:linux在初始化的時候已經把每個中斷向量的地址準備好了!就是說添加中斷服務程序的框架已經給出,當某個中斷發生時,將會到確定的地址處去找指令,所以我們做驅動程序時,只需要經過request_irq來掛接自己編寫的中斷服務程序即可。 ARM體系結構中,把復位、中斷、快速中斷等都看作‘異常’,當這些‘異常’發生時,CPU會到固定地址處去找指令,他們對應的地址如下: 地址 異常類型 進入時的工作模式 0x00000000 Reset Supervisor 0x00000004 Und Undefined 0x00000008 Soft interupt Supervisor 0x0000000c Abort(prefetc
[單片機]
ARM筆記:Linux內核移植到JZ2440
一、準備工作: 1、Linux內核:Linux2.6.22.6,可從 www.kernel.org 上下載; 2、交叉工具編譯鏈:arm-linux-gcc-3.4.5-glibc-2.3.6; 3、yaffs2文件代碼; 4、ubuntu9.10; 5、JZ2440; 二、內核移植: 1、修改Makefile: 修改內核源碼根目錄下的Makefile文件 #ARCH ?= arm #CROSS_COMPILE ?=arm-linux- 2、修改晶振 修改arch/arm/mach-s3c2440/mach-smdk2440.c static void __init smdk2440_map_io(void) {
[單片機]
LCD的ARM編程方式,LCD Linux程序如何寫入
????隨著單片機技術的飛速發展,新型的儀器儀表呈現出操作簡單、便攜化的趨勢。LCD模塊能夠滿足嵌入式系統日益增長的要求,它可以顯示漢字、字符和圖形,同時還具有低壓、低功耗、體積小、重量輕等諸多優點,因而應用十分廣泛。   液晶顯示模塊(LCM)是由控制器、行驅動器、列驅動器、顯示存儲器和液晶顯示屏等器件通過PCB組裝成一體的低成本輸出設備,被廣泛用于各種儀器儀表等設備中。其核心部件LCD控制器是可編程接口芯片,它一方面提供與微控制器(MCU)的接口,一方面連接行/列驅動器。用戶對LCD控制器編程就是實現對LCM的操作控制。LCD控制器的功能是接收計算機發來的指令和數據,并向計算機反饋所需的數據信息。 T6963控制模塊 T696
[嵌入式]
ARM Linux啟動分析headarmv.S內幕
__create_page_tables: pgtbl r4, r5 @ page table address /* Clear the 16K level 1 swapper page table */ mov r0, r4 mov r3, #0 add r2, r0, #0x4000 1: str r3, , #4 str r3, , #4 str r3, , #4 str r3, , #4 teq r0, r2 bne 1b /* * Create identity mapping
[單片機]
IMX6ULL開發平臺Linux-LED實驗
在前面的章節中,我們學習了解了字符設備驅動,以及如何在設備樹文件中添加設備信息,接下來就來看一下i.MX6UL終結者開發板的實際硬件是如何添加的。我們先以最簡單的LED設備來看一下具體的注冊流程。 36.1 LED設備注冊流程 在i.MX6UL終結者開發板上有一個LED設備,如果想要通過Linux系統/dev目錄下的設備節點來控制LED,就需要在內核中添加LED的驅動,具體的流程可以分為下面幾個步驟: ① 硬件原理圖分析,確定控制LED的GPIO信息。 ② 根據GPIO信息在設備樹文件中添加pinctrl信息 ③ 在設備樹中創建LED的設備節點,并加入GPIO信息 ④ 編寫LED設備驅動程序 接下來根據上面這四步來添加一下LED的
[單片機]
IMX6ULL開發平臺<font color='red'>Linux</font>-LED實驗
IMX6ULL學習筆記(10)——通過TFTP燒錄Linux內核
一、搭建環境 1.1 搭建TFTP服務 通過以下方式完成TFTP網絡系統的搭建: 更新APT包 sudo apt update 安裝TFTP服務器端 sudo apt install xinetd tftp tftpd -y 創建TFTP共享目錄 我這里使用和NFS共同的目錄,你們也可以選擇自己熟悉的目錄 mkdir /home/nfs sudo chmod -R 777 /home/nfs 編輯指定目錄 sudo vim /etc/xinetd.d/tftp 添加入下代碼 service tftp{socket_type = dgram protocol = udp wait = yes user = root
[單片機]
Linux下GPIO驅動(五) ----misc_register();
// struct miscdevice { int minor; const char *name; const struct file_operations *fops; struct list_head list; struct device *parent; struct device *this_device; const char *nodename; mode_t mode; }; int misc_register(struct miscdevice * misc);//注冊為雜項設備 int misc_deregister(struct miscdevice *misc)
[單片機]
<font color='red'>Linux</font>下GPIO驅動(五) ----misc_register();
小廣播
設計資源 培訓 開發板 精華推薦

最新單片機文章
何立民專欄 單片機及嵌入式寶典

北京航空航天大學教授,20余年來致力于單片機與嵌入式系統推廣工作。

 
EEWorld訂閱號

 
EEWorld服務號

 
汽車開發圈

 
機器人開發圈

電子工程世界版權所有 京ICP證060456號 京ICP備10001474號-1 電信業務審批[2006]字第258號函 京公網安備 11010802033920號 Copyright ? 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
主站蜘蛛池模板: 新野县| 施甸县| 潞西市| 玉林市| 徐水县| 铅山县| 昌宁县| 富川| 北安市| 武强县| 南靖县| 疏勒县| 旬邑县| 体育| 开原市| 霍邱县| 沅陵县| 平乐县| 资中县| 康定县| 张家港市| 梁山县| 尉氏县| 鹤峰县| 宽甸| 沙雅县| 林周县| 东阳市| 灵石县| 尼勒克县| 彭水| 手机| 静乐县| 呼伦贝尔市| 瑞丽市| 丰顺县| 千阳县| 隆昌县| 白玉县| 漳浦县| 青海省|