ArmLinux BOOTLOADER全程詳解

2021-04-13 09:26:35 字數 4937 閱讀 3853

.幾個重要的概念

compressed kernel and decompressed kernel

jffs2 file system

ramdisk

啟動引數(摘自ibm developer)

2.開發環境和開發板配置:

3.啟動方式:

4.**分析

網上關於linux的bootloader文章不少了,但是大都是vivi,blob等比較龐大的程式,讀起來不太方便,編譯出的檔案也比較大,而且更多的是面向開發用的引導**,做成產品時還要裁減,這一定程度影響了開發速度,對初學者學習開銷也比較大,在此分析一種簡單的bootloader,是在三星公司提供的2410 bootloader上稍微修改後的結果,編譯出來的檔案大小不超過4k,希望對大家有所幫助.

1.幾個重要的概念

compressed kernel and decompressed kernel

壓縮後的kernel,按照文件資料,現在不提倡使用decompressed kernel,而要使用compressed kernel,它包括了解壓器.因此要在ram分配時給壓縮和解壓的kernel提供足夠空間,這樣它們不會相互覆蓋.

當執行指令跳轉到compressed kernel後,解壓器就開始工作,如果解壓器探測到解壓的**會覆蓋掉compressed kernel,那它會直接跳到compressed kernel後存放資料,並且重新定位kernel,所以如果沒有足夠空間,就會出錯.

jffs2 file system

可以使armlinux應用中產生的資料儲存在flash上,我的板子還沒用到這個.

ramdisk

使用ramdisk可以使root file system在沒有其他裝置的情況下啟動.一般有兩種載入方式,我就介紹最常用的吧,把compressed ramdisk image放到指定位址,然後由bootloader把這個位址通過啟動引數的方式atag_initrd2傳遞給kernel.具體看**分析.

啟動引數(摘自ibm developer)

在呼叫核心之前,應該作一步準備工作,即:設定 linux 核心的啟動引數。linux 2.4.x 以後的核心都期望以標記列表(tagged list)的形式來傳遞啟動引數。啟動引數標記列表以標記 atag_core 開始,以標記 atag_none 結束。每個標記由標識被傳遞引數的 tag_header 結構以及隨後的引數值資料結構來組成。資料結構 tag 和 tag_header 定義在 linux 核心原始碼的include/a**/setup.h 標頭檔案中.

在嵌入式 linux 系統中,通常需要由 bootloader 設定的常見啟動引數有:atag_core、atag_mem、atag_cmdline、atag_ramdisk、atag_initrd等。

(注)引數也可以用commandline來設定,在我的bootloader裡,我兩種都用了.

2.開發環境和開發板配置:

cpu:s3c2410,bank6上有64m的sdram(兩塊),bank0上有32m nor flash,串列埠當然是逃不掉的.這樣,按照資料手冊,位址分配如下:

0x4000_0000開始是4k的片內dram.

0x0000_0000開始是32m flash 16bit寬度

0x3000_0000開始是64m sdram 32bit寬度

注意:控制暫存器中的bank6和bank7部分必須相同.

0x4000_0000(片內dram)存放4k以內的bootloader image

0x3000_0100開始存放啟動引數

0x3120_0000 存放compressed kernel image

0x3200_0000 存放compressed ramdisk

0x3000_8000 指定為decompressed kernel image address

0x3040_0000 指定為decompressed ramdisk image address

開發環境:redhat linux,armgcc toolchain, armlinux kernel

如何建立armgcc的編譯環境:建議使用toolchain,而不要自己去編譯armgcc,偶試過好多次,都以失敗告終.

將arm-linux-gcc-3.3.2.tar.bz2 解壓到 /toolchain

# tar jxvf arm-linux-gcc-3.3.2.tar.bz2

# mv /usr/local/arm/3.3.2 /toolchain

在makefile 中在把arch=arm cross_compile設定成toolchain的路徑

還有就是include = -i ../include -i /root/my/usr/local/arm/3.3.2/include.,否則庫函式就不能用了

3.啟動方式:

可以放在flash裡啟動,或者用jtag**器.由於使用nor flash,根據2410的手冊,片內的4k dram在不需要設定便可以直接使用,而其他儲存器必須先初始化,比如告訴memory controller,bank6裡有兩塊sdram,資料寬度是32bit,= =.否則memory control會按照復位後的預設值來處理儲存器.這樣讀寫就會產生錯誤.

所以第一步,通過**器把執行**放到0x4000_0000,(在編譯的時候,設定text_bas

e=0x40000000)

第二步,通過 axd把linux kernel image放到目標位址(sdram)中,等待呼叫

第三步,執行bootloader**,從串列埠得到除錯資料,引導armlinux

4.**分析

bootloader一般分為2部分,彙編部分和c語言部分,彙編部分執行簡單的硬體初始化,c部分負責複製資料,設定啟動引數,串列埠通訊等功能.

bootloader的生命週期:

1. 初始化硬體,比如設定uart(至少設定乙個),檢測儲存器= =.

2. 設定啟動引數,這是為了告訴核心硬體的資訊,比如用哪個啟動介面,波特率 = =.

3. 跳轉到linux kernel的首位址.

4. 消亡

當然,在引導階段,象vivi等,都用虛位址,如果你嫌煩的話,就用實位址,都一樣.

我們來看**:

2410init.s

.global _start//開始執行處

_start:

//下面是中斷向量

b reset @ supervisor mode//重新啟動後的跳轉

…… ……

reset:

ldr r0,=wtcon /wtcon位址為53000000,watchdog的控制暫存器 */

ldr r1,=0x0 /*關watchdog*/

str r1,[r0]

ldr r0,=intmsk

ldr r1,=0xffffffff /*遮蔽所有中斷*/

str r1,[r0]

ldr r0,=intsubmsk

ldr r1,=0x3ff /*子中斷也一樣*/

str r1,[r0]

/*initialize ports...for display led.*/

ldr r0, =gpfcon

ldr r1, =0x55aa

str r1, [r0]

ldr r0, =gpfup

ldr r1, =0xff

str r1, [r0]

ldr r0,=gpfdat

ldr r1,=poweroffled1

str r1,[r0]

/* setup clock divider control register

* you must configure clkdivn before locktime or mpll upll

* because default clkdivn 1,1,1 set the sdmram timing conflict

nop

* fclk:hclk:pclk = 1:2:4 in this case

*/ ldr r0,=clkdivn

ldr r1,=0x3

str r1,[r0]

/*to reduce pll lock time, adjust the locktime register. */

ldr r0,=locktime

ldr r1,=0xffffff

str r1,[r0]

/*configure mpll */

ldr r0,=mpllcon

ldr r1,=((m_mdivhdr.tag = atag_core;

params->hdr.size = tag_size(tag_core);

params->u.core.flags = 0;

params->u.core.pagesize = 0;

params->u.core.rootdev = 0;

params = tag_next(params); }

static void setup_memory_tags(void)

} }

static void setup_commandline_tag(char *commandline)

static void setup_initrd2_tag(void)

static void setup_ramdisk_tag(void)

static void setup_end_tag(void)

void uart_init(int pclk,int baud)//串列埠是很重要的

經過以上的折騰,接下來就是kernel的活了.能不能啟動kernel,得看你編譯kernel的水平了.

這個bootloader不象blob那樣需要互動資訊,使用虛擬位址,總的來說非常簡潔明瞭.

演算法 KMP演算法超詳好懂理解(附全程式模擬過程)

當前稿件版本1.0 今天為了noip提高組的模擬準備,早上起來 默寫kmp吧!好,提交 tle 改改改 tle 我不信!tle 58 rs wa 終於在一天的努力後,把kmp給a了。痛心疾首,決心寫乙個kmp的詳解,不要讓其他人掉入這個坑里了 在 不用管!只用知道它是乙個高效的字串匹配演算法就行了。...

mysql全程 MySQL索引使用全程分析

建立2張使用者表user user2,表結構相同,但user表使用innodb儲存引擎,而user2表則使用 myisam儲存引擎。複製 如下 table user ddl create table user id int 11 not null auto increment,name varcha...

Sublime Text 全程指南

ctrl shift p開啟命令板,輸入pc應出現package control 控制台 console 使用ctrl 調出 一.基本編輯 1.就是 貼上剪下複製均和系統一致。2.ctrl enter在當前行下面新增一行然後跳至該行 ctrl shift enter在當前行上面增加一行並跳至該行。3...