1. 程式人生 > >ARM linux解析之壓縮核心zImage的啟動過程 二

ARM linux解析之壓縮核心zImage的啟動過程 二

3. .text段開始,先是核心解壓地址的確定

 再往下看,程式碼如下:

 .text

#ifdef CONFIG_AUTO_ZRELADDR

 @ determine final kernel image address

 mov r4, pc

 and r4, r4, #0xf8000000

 add r4, r4, #TEXT_OFFSET

#else

 ldr r4, =zreladdr

#endif

~~~~ 不要小這一段程式碼,東西好多啊。如哪入手呢?好吧,先從linux基本引數入手吧,見表.1,裡面我寫的很詳細,因為表格我要放一頁,解釋我就寫在上面了。

TEXT_OFFSET是程式碼相對於實體記憶體的偏移,通常選為32k=0x8000。這個是有原因的,具體的原因後面會說。先看CONFIG_AUTO_ZRELADDR這個巨集所含的內容,它的意思是如果你不知道ZRELADDR地址要定在記憶體什麼地方,那麼這段程式碼就可以幫你。看到0xf8000000了吧,那麼後面有多少個0呢?答案是27個,那麼227次方就是128M,這就明白了,只要你把解壓程式放在你最後解壓完成後的核心空間的128M之內的偏移的話,就可以自動設定好解壓後核心要執行的地址ZRELADDR

如果你沒有定義的話,那麼,就會去取zreladdr作為最後解壓的核心執行地。那麼這個zreladdr是從哪裡來的呢?答案是在:

arch/arm/boot/compressed/Makefile中定義的

# Supply ZRELADDR to the decompressor via a linker symbol.

ifneq ($(CONFIG_AUTO_ZRELADDR),y)

LDFLAGS_vmlinux += --defsym zreladdr=$(ZRELADDR)

endif

ZRELADDR這又是哪裡定義的呢?答案是在:arch/arm/boot/Makefile中定義的

ifneq ($(MACHINE),)

include $(srctree)/$(MACHINE)/Makefile.boot

endif

# Note: the following conditions must always be true:

# ZRELADDR == virt_to_phys(PAGE_OFFSET + TEXT_OFFSET)

# PARAMS_PHYS must be within 4MB of ZRELADDR

# INITRD_PHYS must be in RAM

ZRELADDR := $(zreladdr-y)

PARAMS_PHYS:= $(params_phys-y)

INITRD_PHYS:= $(initrd_phys-y)

而裡面的幾個引數是在每個arch/arm/Mach-xxx/ Makefile.boot裡面定義的,內容如下:

 zreladdr-y := 0x20008000

params_phys-y := 0x20000100

initrd_phys-y := 0x21000000

這下知道了,繞了一大圈,終於知道r4存的是什麼了,就是最後核心解壓的起址,也是最後解壓後的核心的執行地址,記住,這個地址很重要。

解壓核心引數

解壓時symbol 

解釋

ZTEXTADDR

千成不要看成ZTE啊,呵,這裡是zImage的執行的起始地址,當核心從nor flash中執行的時候很重要,如果在ram中執行,這個設為0

ZBSSADDR

這個地址也是一樣的,這個是BSS的地址,如果在nor中執行解壓的話,這個地址很重要。這個要放在RAM

ZRELADDR

這個地址很重要,這個是解壓後核心存放的地址,也是最後解壓後核心的執行起址。

一般設為記憶體起址的32K之後,如ARM: 0x20008000

ZRELADDR = PHYS_OFFSET + TEXT_OFFSET

INITRD_PHYS

RAM disk的實體地址

INITRD_VIRT

RAM disk的虛擬地址

__virt_to_phys(INITRD_VIRT) = INITRD_PHYS

PARAMS_PHYS

核心引數的實體地址

核心引數

PHYS_OFFSET

實際RAM的實體地址

對於當前ARM來說,就是0x20000000

PAGE_OFFSET

核心空間的起始虛擬地址,通常: 0xC0000000,高階1G

__virt_to_phys(PAGE_OFFSET) = PHYS_OFFSET

TASK_SIZE

使用者程序的記憶體的最太值(以位元組為單位)

TEXTADDR

核心啟執行的虛擬地址的起址,通常設為0xC0008000

TEXTADDR = PAGE_OFFSET + TEXT_OFFSET

__virt_to_phys(TEXTADDR) = ZRELADDR

TEXT_OFFSET

相對於記憶體起址的核心程式碼存放的偏移,通常設為 32k (0x8000)

DATAADDR

這個是核心資料段的虛擬地址的起址,當用zImage的時候不要定義。

.1 核心引數解釋

4. 開啟ARM系統的cache,為加快核心解壓做好準備

 可以看到,開啟cache的就一個函式,如下:

bl cache_on

看起來很少,其實展開後內容還是很多的。我們來看看這個cache_on在哪裡,可以找到程式碼如下:

 .align 5

cache_onmov r3, #8 @ cache_on function

 b call_cache_fn

這裡設計的很精妙的,只可意會,注意mov r3, #8,不多解釋,跟進去call_cache_fn

call_cache_fn: adr r12, proc_types

#ifdef CONFIG_CPU_CP15

 mrc p15, 0, r9, c0, c0 @ get processor ID

#else

 ldr r9, =CONFIG_PROCESSOR_ID

#endif

1:  ldr r1, [r12, #0] @ get value

 ldr r2, [r12, #4] @ get mask

 eor r1, r1, r9 @ (real ^ match)

相關推薦

ARM linux解析壓縮核心zImage啟動過程

ARM linux解析之壓縮核心zImage的啟動過程 首先,我們要知道在zImage的生成過程中,是把arch/arm/boot/compressed/head.s和解壓程式碼misc.c,decompress.c加在壓縮核心的最前面最終生成zImag

ARM linux解析壓縮核心zImage啟動過程

3. .text段開始,先是核心解壓地址的確定  再往下看,程式碼如下:  .text #ifdef CONFIG_AUTO_ZRELADDR  @ determine final kernel image address  mo

linux shell 嘗試編寫 企業級 啟動腳本

nginx data err 企業級 開機自啟 註意 sbin 分享 fin 企業Shell面試題10:開發企業級MySQL啟動腳本 說明: MySQL啟動命令為: 1 /bin/sh mysqld_safe --pid-file=$mysqld_pid_

Linux命令壓縮

linux gzip bzip2 壓縮1.壓縮的概念1)壓縮的目的在網絡傳遞文件時,可以先將文件壓縮,然後傳遞壓縮後的文件,從而減少網絡帶寬接收者接受文件後,解壓即可2)壓縮的類型有損壓縮和無損壓縮a)有損壓縮如MP4視頻文件,即使壓縮過程中減少了很多幀數據,對觀看者而言也沒有影響。當然MP

L-1-17 Linux命令壓縮與歸檔命令

/tmp command filename 刪除 文件的 sca img 之前 zip [bzip2]bzip2 <file>將文件壓縮成bz2格式,並刪除原文件。//適合大文件壓縮 -d <*.bz2> 解壓 -<num> 指定

linux 操作壓縮與解壓

壓縮與解壓   壓縮格式:zip , rar , 7z , iso , exe     gzip     (以下是命令操作)     gzip [檔名]  #壓縮成gz格式 , 原來的檔案消失 , 不支援目錄.     bzip2 -d [壓縮檔名] #解壓     bzip

Linux命令壓縮壓縮命令

壓縮解壓縮命令 命令名稱:gzip 命令原意:gnu zip 命令路徑:/bin/gzip 執行許可權:所有使用者功能描述:壓縮檔案 語法:gzip   選項  [檔案] 壓縮後文件格式:.gz  命令名稱:gunzip 命令原意:gnu

Linux指令壓縮和解

1.gzip/gunzip gzip用於壓縮,gunzip用於解壓。 gzip 檔名 :壓縮檔案 gunzip 檔名.gz :解壓縮檔案 gzip hello.txt :將hello.txt檔案進行壓縮 gunzip hello.txt.gz :將hello.txt.gz檔案進行解壓縮 (使

ARMCortex M3的啟動過程

                EXPORT  WWDG_IRQHandler                   [WEAK]                                                        EXPORT  PVD_IRQHandler             

linux整理壓縮壓縮、加密、分卷

=========================================壓縮解壓縮======================================================= .tar 解包:tar xvf FileName.tar 打包:tar

移植完linux-3.4.2核心啟動系統後使用命令ifconfig -a檢視網路配置,沒有eth0

問題: / # ifconfig / # ifconfig eth0  ifconfig: eth0: error fetching interface information: Device not

移植完linux-3.4.2核心啟動系統後使用命令ifconfig -a檢視網路配置只有一個local backloop

問題如下: / # ifconfig / # ifconfig eth0 ifconfig: eth0: error fetching interface information: Device n

Dubbo原理和原始碼解析“微核心+外掛”機制

private void loadFile(Map<String, Class<?>> extensionClasses, String dir) { //...... BufferedReader reader = new BufferedReader(new

Linux 0.11核心啟動過程

Linux 0.11核心的啟動過程 一、Image檔案的構成 1.1 Makefile中的相關命令 Linux 0.11的主Makefile檔案中,有如下欄位: tools/build: tools/build.c $(CC) $(CFLAGS) \ -o tools/bu

Linux0.11核心引導啟動過程概述

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

《16.核心啟動過程分析》

《16.核心的啟動過程分析》 第一部分、章節目錄 2.16.1.做好核心分析的準備工作 2.16.2.head.S檔案分析1 2.16.3.核心啟動的彙編階段 2.16.4.核心啟動的C語言階段1 2.16.5.核心啟動的C語言階段2 2.16.6.核心啟動的C語言階段3 2.16.7.

Spark core原始碼分析spark叢集的啟動

2.2 Worker的啟動 org.apache.spark.deploy.worker 1 從Worker的伴生物件的main方法進入 在main方法中首先是得到一個SparkConf例項conf,然後將conf和啟動Worker傳入的引數封裝得到Wor

資料結構圖文解析:樹的簡介及叉排序樹C++模板實現.

  閱讀目錄 0. 資料結構圖文解析系列 1. 樹的簡介 1.1 樹的特徵 1.2 樹的相關概念 2. 二叉樹簡介 2.1 二叉樹的定義 2.2 斜樹、滿二叉樹、完全二叉樹、二叉查詢樹 2

Linux0 11核心引導啟動過程概述

Linux0.11僅支援x86架構。它的核心引導啟動程式在資料夾boot內,共有三個彙編程式碼檔案。按照啟動流程依次是:     (1)bootsect.s。boot是啟動引導的意思,sect即sector,是扇區的意思,二者合在一起啟動引導扇區。這是 磁碟載

Linux學習多執行緒程式設計(

言之者無罪,聞之者足以戒。 ——《詩序》 (二)、執行緒的基本控制 1、終止程序: 如果程序中的任意一個程序呼叫了exit、_exit、_Exit,那麼整個程序就會終止 普通的單個程序有以下3種退出方式,這樣不會終止程序: (1)從啟動例程中返回,返回值是執行緒的退