




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、nand 啟動(dòng)時(shí) bank0 失效,即用不了NOP FLASHnand flash 前4K被強(qiáng)制復(fù)制到片內(nèi) SRAM 4K內(nèi)存中,然后CPU會(huì)從零地址(SRAM)開始執(zhí)行。nor 啟動(dòng)時(shí) nor flash 零地址在nor flash cpu從零地址執(zhí)行。nor flash特征是可以像內(nèi)存一樣讀數(shù)據(jù),但是不能像內(nèi)存一樣直接寫數(shù)據(jù), 要通過命令先擦除后才能寫數(shù)據(jù)。 GPIO實(shí)驗(yàn):main 沒什么特別的,一樣要被別人調(diào)用,執(zhí)行往也要返回。啟動(dòng)文件: 調(diào)用 main,調(diào)用完之后要返回,所以要設(shè)置返回地址。最后要進(jìn)行一些清理工作。軟件初始化: 設(shè)置棧 /*設(shè)置棧就是把棧指針SP指向某個(gè)內(nèi)存,假如指向S
2、DRAM則要先初始化SDRAM才能設(shè)置棧 */設(shè)置返回地址 /*bl指令會(huì)跳轉(zhuǎn)到main函數(shù),并且把返回地址保存在LR寄存器里面。*/調(diào)用main清理工作硬件初始化:關(guān)看門狗 /*上電時(shí)候看門狗啟動(dòng),會(huì)倒數(shù)計(jì)時(shí)三秒內(nèi)沒有關(guān)閉就會(huì)重啟系統(tǒng)。所以要關(guān)掉*/初始化時(shí)鐘 /*想要跑的更快要初始化時(shí)鐘*/初始化SDRAM/*/設(shè)置返回地址:blmain /*bl指令會(huì)跳轉(zhuǎn)到main函數(shù),并且把返回地址保存在LR寄存器里面。*/ /*bl 指令會(huì)把返回地址存在lr寄存器里面。*/#defineGPFCON (*(volatile unsigned long *)0x56000050) /* volatil
3、e讓編譯器不要優(yōu)化變量*/ #defineGPF4_out(1<<(4*2)#defineGPF5_out(1<<(5*2)#defineGPF6_out(1<<(6*2)#defineGPF7_out(1<<(7*2) GPFCON |= GPF4_out|GPF5_out|GPF6_out;/ 將LED1-3對(duì)應(yīng)的GPF4/5/6三個(gè)引腳設(shè)為輸出按位操作:想要清零 : 按位與 /*例如清bit3 則 a&=(1<<3)*/想要置“1” : 按位或 /*例如置bit3 則 a|= (1<<3)*/SRAM在芯片手
4、冊(cè)里面稱為 steppingstoneCPU通過存儲(chǔ)管理器才知道怎么訪問外部的設(shè)備 例如 SDRAM DM9000網(wǎng)卡等想訪問一個(gè)芯片,需要哪些條件1:地址線(例如SDRAM 行地址13位,列地址9位) 看芯片手冊(cè)2:數(shù)據(jù)線 /* 8/16/32位 數(shù)據(jù)寬度 例如SDRAM 位寬32位 SDRAM32位,所以 ADDR0,ADDR1就不需要使用。 */ 看原理圖3:時(shí)鐘/頻率 (刷新周期 8192/64ms 即刷新8192次需要64ms)看芯片手冊(cè)4:芯片相關(guān):例如SDRAM(行地址,列地址,Bank) 看芯片手冊(cè)SDRAM32位,所以 ADDR0,ADDR1就不需要使用。因?yàn)?440的地址的
5、單位是byte(8位),所以CPU發(fā)出的0,1,2,3這四個(gè)地址都是訪問到SDRAM地址中的同一個(gè)單元。返回都是返回同一個(gè)四字節(jié)(32位)的數(shù)據(jù)。假如訪問的芯片去16位的,則ADDR0 就不需要使用。想要訪問某個(gè)芯片(如SDRAM)先要配置存儲(chǔ)管理器(位寬,行列地址,刷新周期)。所謂配置也就是設(shè)置寄存器。2440可以接8個(gè)外設(shè)(SDRAM,DM9000網(wǎng)卡,NOR FLASH等等),因?yàn)橛?個(gè)Bank,有8條片選信號(hào)(CS信號(hào))。 Bank05都是一樣的結(jié)構(gòu)。Bank67比較特別,它們可以接SDRAM。 內(nèi)存可以分為SRAM,SDRAM,DDR等等。SRAM很快但是比較貴,使用方法簡(jiǎn)單,直接發(fā)
6、地址信號(hào)就可以了。SDRAM比較便宜且訪問比較復(fù)雜,它的地址還分為Bank地址,行地址,列地址。還要不斷的刷新SDRAM(REFRESH寄存器就是用來設(shè)置刷新周期的),不刷新數(shù)據(jù)就會(huì)丟失。網(wǎng)卡,NOR FLASH它們的接口跟根SRAM的接口是一樣的,術(shù)語(yǔ)上稱為 RAM like。每個(gè)Bank可以外接128M的東西,尋址空間是128M。bank7/bank6可以組(128M/128M,64M/64M,32M/32M等)大程序啟動(dòng)過程:1:一上電nand flash前4K被拷貝到SRAM中。2:程序會(huì)先關(guān)看門狗,初始化存儲(chǔ)管理寄存器,SDRAM。3:拷貝到SRAM中的4K代碼再把nand flas
7、h中的代碼拷貝到SDRAM中去,然后繼續(xù)執(zhí)行(在SDRAM中運(yùn)行)。arm-linux-ld -Ttext 0x3000000 -g led_on.o -o led_on_elf (Ttext 0x3000000 是鏈接地址)所謂鏈接地址就是說,運(yùn)行時(shí)程序“應(yīng)該”位于哪里。所以head.s 就應(yīng)該從片內(nèi)SRAM拷到SDRAM中去。當(dāng)前PC值 = 當(dāng)前指令的地址 + 8 / pc = 當(dāng)前指令地址 + 8MMU:權(quán)限管理,地址映射。使用MMU時(shí),使用CPU發(fā)出的地址是虛擬地址。或者是真實(shí)的物理地址。CPU發(fā)出的是物理地址還是虛擬地址CPU是不在乎的,CPU沒有虛擬地址和物理地址概念。寫程序的時(shí)候
8、,我們說的地址例如鏈接地址,也沒有虛擬地址,物理地址概念。就是一個(gè)單純的地址。地址只是從CPU角度看到的。虛擬地址(VA)怎么轉(zhuǎn)換為物理地址(PA)。 對(duì)于mips架構(gòu)來說 VA=0xA000,0000 + PA /* VA=fun(PA)*/對(duì)于ARM結(jié)構(gòu)來說:表格: 一級(jí)頁(yè)表,二級(jí)頁(yè)表。 對(duì)于ARM來說有兩種映射:段和頁(yè)段映射: 表格里面每一個(gè)表項(xiàng)對(duì)應(yīng)一段,表示大小是 1M。假如CPU的地址數(shù)是4G,則需要的表格數(shù)位4G/1M=4*1024=4096個(gè)。創(chuàng)建頁(yè)表:?jiǎn)?dòng)前和啟動(dòng)瞬間,地址要連續(xù)。A:所以04096的虛擬地址要對(duì)應(yīng)04096的物理地址使用MMU會(huì)加快程序的運(yùn)行速度,因?yàn)橛蠨CA
9、CH,ZCACH。這些會(huì)加快程序運(yùn)行速度。1,MMU首先知道你創(chuàng)建的這些頁(yè)表項(xiàng)都放在哪里;2,MMU通過虛擬地址的高12位可以找到對(duì)應(yīng)的頁(yè)表項(xiàng),并且這個(gè)頁(yè)表項(xiàng)的高12位就是物理地址的高12位;3,虛擬地址的低20位就是物理地址的低20位;4,頁(yè)表項(xiàng)的高12位+虛擬地址的低20位=物理地址。SDRAM程序中mem_cfg_val結(jié)構(gòu)體中的的數(shù)字為寄存器BWSCON,BANKCON0,BANKCON1,BANKCON2,BANKCON3,BANKCON4,BANKCON5,BANKCON6,BANKCON7,REFRESH,BANKSIZE,MRSRB6,MRSRB7寄存器賦值。目的是初始化SDR
10、AM。unsigned long *p = (unsigned long *)MEM_CTL_BASE; 此語(yǔ)句是將指針P指向寄存器 0x48000000MMU代碼:/*復(fù)制第二段代碼到SDRAM中*/void copy_2th_to_sdram(void) unsigned int *pdwSrc = (unsigned int *)2048; unsigned int *pdwDest = (unsigned int *)0x30004000;/*地址為0x30004000是因?yàn)榍?6K用來存放頁(yè)表 */ while (pdwSrc < (unsigned int *)4096) *
11、pdwDest = *pdwSrc; pdwDest+; pdwSrc+; 寄存器: NFCMMD NFADDR NFDATANand flash 沒有地址總線跟CPU相連,不同于SDRAM,DM9000網(wǎng)卡,SRAM,寄存器等都有地址總線與CPU相連,所以SDRAM,DM9000網(wǎng)卡,SRAM,寄存器與Nand flash的尋址方式不一樣。SDRAM,DM9000網(wǎng)卡,SRAM,寄存器的地址是CPU發(fā)出來的,或稱為CPU統(tǒng)一編址。 而Nand flash 的地址是Nand flash 自己編址的,CPU “看不到”的。 所以CPU說的“0”地址與Nand flash 說的“0”地址不是一個(gè)概
12、念。那Nand flash 是怎么編址的呢?從原理圖上,Nand flash 與CPU相連的只有 數(shù)據(jù)總線,控制總線。所以CPU發(fā)出的 地址,命令都是由數(shù)據(jù)總線進(jìn)行傳輸。但是如何分辨是 地址還是命令呢?顯然是通過控制總線進(jìn)行區(qū)分。 CLE(高電平) 信號(hào)是命令, ALE(高電平) 信號(hào)是地址, 兩個(gè)信號(hào)都無(wú)效的話 傳輸?shù)木褪菙?shù)據(jù)。 是讀數(shù)據(jù) 還是寫數(shù)據(jù) 又由 nFWE(讀) 引腳 nFRE(寫)引腳控制。Nand flash 的典型結(jié)構(gòu)是 大頁(yè),一個(gè)大頁(yè)有2K 也就是2048字節(jié)。有64頁(yè)。 注意:每一個(gè)大頁(yè)中都有一個(gè)叫 OOB的空間(64字節(jié))。一般來說用不到OOB這個(gè)空間,例如我們要訪問第
13、2049這個(gè)字節(jié)空間,不會(huì)訪問到OOB這個(gè)空間而是訪問第二頁(yè)開始的第二個(gè)字節(jié)。所以真實(shí)的一頁(yè)是 2K+64字節(jié)。只是64字節(jié)基本上不用。那怎么訪問 Nand flash ?1:發(fā)出命令 CLE NFCMMD 寄存器2:發(fā)出地址 ALE NFADDR 寄存器3:發(fā)出數(shù)據(jù) R/W NFDATA 寄存器4:狀態(tài) NFSTAT 寄存器 /發(fā)出擦除命令不可能馬上就擦除成功,用狀態(tài)寄存器確定NAND FLASH的狀態(tài)判斷是否擦除成功代碼: ldr r0, =0x30000000 1. 目標(biāo)地址=0x30000000,這是SDRAM的起始地址 mov r1, #4096 2. 源地址 = 4096,連接的時(shí)
14、候,main.c中的代碼都存在NAND Flash地址4096開始處 mov r2, #2048 3. 復(fù)制長(zhǎng)度= 2048(bytes),對(duì)于本實(shí)驗(yàn)的main.c,這是足夠了 bl nand_read 匯編和C語(yǔ)言傳遞參數(shù): 如上例子,r0為傳遞給C函數(shù)(nand_read)的第一個(gè)參數(shù),r1為第二個(gè),r2為第三個(gè)。 void nand_read(unsigned char *buf, unsigned long start_addr, int size);中斷:ARM體系CPU的7種工作模式:用戶模式(usr):ARM處理器正常的程序執(zhí)行狀態(tài)該模式下的寄存器:r0 r1 r2 r3 r4
15、r5 r6 r7 r8 r9 r10 r11 r12 r13 r14 r15(pc)系統(tǒng)模式(sys):運(yùn)行具有特權(quán)的操作系統(tǒng)任務(wù)該模式下的寄存器:r0 r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12 r13 r14 r15(pc)快速中斷模式(fiq):用于高速數(shù)據(jù)傳輸或通道處理該模式下的寄存器:r0 r1 r2 r3 r4 r5 r6 r7 “r8_fiq” “r9_fiq” “r10_fiq” “r11_fiq” “r12_fiq” “r13_fiq” “r14_fiq” r15(pc)中斷模式(irq):用于通用的中斷處理該模式下的寄存器:r0 r1 r2
16、 r3 r4 r 5 r6 r7 r8 r9 r10 r11 r12 “r13_irq” “r14_irq” r15(pc)管理模式(svc):操作系統(tǒng)使用的保護(hù)模式該模式下的寄存器:r0 r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12 “r13_svc” “r14_svc” r15(pc)數(shù)據(jù)訪問終止模式(abt):當(dāng)數(shù)據(jù)或指令預(yù)取終止時(shí)進(jìn)入該模式,可用于虛擬存儲(chǔ)及存儲(chǔ)保護(hù)該模式下的寄存器:r0 r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12 “r13_abt” “r14_abt” r15(pc)未定義指令中止模式(und):當(dāng)未定
17、義的指令執(zhí)行時(shí)進(jìn)入該模式,可用于支持硬件協(xié)處理器的軟件仿真該模式下的寄存器:r0 r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12 “r13_und” “r14_und” r15(pc)由上可知除了系統(tǒng)模式和用戶模式的寄存器相同,其余的5個(gè)模式下的寄存器不相同。其中 快中斷模式 擁有7個(gè)獨(dú)立寄存器,其余模式都是 r13 r14 兩個(gè)寄存器獨(dú)立。中斷也是一種異常發(fā)生了異常之后:1:CPU 強(qiáng)制進(jìn)入異常模式,就是切換寄存器(如上) /*這里就是說發(fā)生異常之后CPU進(jìn)入異常模式 2:PC(r15) = 異常入口 然后程序自動(dòng)跳到異常入口*/設(shè)置棧,棧 sp 就是 r13。
18、異常入口是什么: 就是CPU固定的地址。 如下:* 異常向量,本程序中,除Reset和HandleIRQ外,其它異常都沒有使用* .extern main.text .global _start _start: _start 表示0地址入口復(fù)位異常的入口就是0地址,發(fā)生復(fù)位之后CPU自動(dòng)跳到0地址取指執(zhí)行 b Reset 0x04: 未定義指令中止模式的向量地址HandleUndef: b HandleUndef /*死循環(huán)*/ 0x08: 管理模式的向量地址,通過SWI指令進(jìn)入此模式HandleSWI: b HandleSWI /*死循環(huán)*/ 0x0c: 指令預(yù)取終止導(dǎo)致的異常的向量地址Ha
19、ndlePrefetchAbort: b HandlePrefetchAbort /*死循環(huán)*/ 0x10: 數(shù)據(jù)訪問終止導(dǎo)致的異常的向量地址HandleDataAbort: b HandleDataAbort /*死循環(huán)*/ 0x14: 保留HandleNotUsed: b HandleNotUsed /*死循環(huán)*/ 0x18: 中斷模式的向量地址 b HandleIRQ 0x1c: 快中斷模式的向量地址HandleFIQ: b HandleFIQ /*死循環(huán)*/Reset: ldr sp, =4096 設(shè)置棧指針,以下都是C函數(shù),調(diào)用前需要設(shè)好棧 bl disable_watch_dog
20、關(guān)閉WATCHDOG,否則CPU會(huì)不斷重啟 msr cpsr_c, #0xd2 進(jìn)入中斷模式 ldr sp, =3072 設(shè)置中斷模式棧指針 msr cpsr_c, #0xd3 進(jìn)入管理模式 ldr sp, =4096 設(shè)置管理模式棧指針, 其實(shí)復(fù)位之后,CPU就處于管理模式, 前面的“l(fā)dr sp, =4096”完成同樣的功能,此句可省略 bl init_led 初始化LED的GPIO管腳 bl init_irq 調(diào)用中斷初始化函數(shù),在init.c中 msr cpsr_c, #0x53 設(shè)置I-bit=0,開IRQ中斷 ldr lr, =halt_loop 設(shè)置返回地址 ldr pc, =m
21、ain 調(diào)用main函數(shù)halt_loop: b halt_loopHandleIRQ: sub lr, lr, #4 計(jì)算返回地址 /*這個(gè)是ARM架構(gòu)決定的,所以就是這個(gè)。*/ stmdb sp!, r0-r12,lr 保存使用到的寄存器 注意,此時(shí)的sp是中斷模式的sp 初始值是上面設(shè)置的3072 ldr lr, =int_return 設(shè)置調(diào)用ISR即EINT_Handle函數(shù)后的返回地址 ldr pc, =EINT_Handle 調(diào)用中斷服務(wù)函數(shù),在interrupt.c中int_return: ldmia sp!, r0-r12,pc 中斷返回, 表示將spsr的值復(fù)制到cpsr怎
22、么用中斷? “被中斷”1:中斷發(fā)生。 要做什么事情? “保存”“別人”的狀態(tài) 先初始化引腳等,然后使能中斷2:中斷處理 分辨中斷源,根據(jù)中斷源進(jìn)行不同的處理,然后進(jìn)行清理工作(清中斷)3:恢復(fù)“別人”的狀態(tài) 就是恢復(fù)寄存器。中斷控制器:1:使能中斷 2:狀態(tài)寄存器(分辨中斷源) 3:設(shè)置 高電平 低電平 上升沿 下降沿 等觸發(fā)。4:引腳設(shè)置 設(shè)置為輸入,輸出,中斷。 5:優(yōu)先級(jí)寄存器 設(shè)置棧,棧 sp 就是 r13。 切換到中斷模式(或其他異常模式)時(shí),要重新設(shè)置棧,因?yàn)閞13 (sp)是每個(gè)模式下獨(dú)有的。怎么進(jìn)入中斷? msr cpsr_c, #0xd2 進(jìn)入中斷模式,運(yùn)行這個(gè)msr cps
23、r_c 指令就可以進(jìn)入中 斷,而x0d2表示進(jìn)入哪個(gè)中斷。具體如下。0xd2 二進(jìn)制為:110 10010除r0 r15 這16個(gè)寄存器外 還有第17個(gè)寄存器 cpsr(當(dāng)前狀態(tài)寄存器) (詳見MSR和MRS文本)控制位:(以0xd2 為例)I中斷禁止位 F快速中斷禁止位 TCPU狀態(tài)位 M4工作模式位 M3工作模式位 M2工作模式位 M1工作模式位 M0工作模式位1 1 0 1 0 0 1 0以上就是表示中斷模式。M4:010000 User 表示用戶模式10001 FIQ 表示快中斷模式10010 IRQ 表示中斷模式10011 Supervisor 表示管理模式10111 Abort 表
24、示數(shù)據(jù)訪問中止模式11011 Undefined 表示未定義指令中止模式11111 System 表示系統(tǒng)模式系統(tǒng)時(shí)鐘:2440 CPU : 400M (FCLK) 如果什么都不設(shè)置,CPU 是以晶振的頻率 12M HZ 在跑。SDRAM,MD900,NOR FLASH等: 100M 133M (HCLK)UART,定時(shí)器,I2C等 : 50M (PCLK)2440 的晶振只有12M設(shè)置 PLL 寄存器 設(shè)置頻率怎么設(shè)置 FCLK PCLK HCLK1:晶振PLL400M HZ PLL (LOCKTIME)鎖定時(shí)間寄存器(使用默認(rèn)值就可以了),MPLLCON 設(shè)置晶振頻率的寄存器2:400M
25、HZ 分頻(HCLK PCLK) 分頻寄存器 CLKDIVN 設(shè)置 波特率 UBRDIVn(n=01) 有一個(gè)公式 看數(shù)據(jù)手冊(cè)位置相關(guān):PCnew = 某個(gè)絕對(duì)值引入一個(gè)新的概念:位置無(wú)關(guān)碼 bl和b 指令就是位置無(wú)關(guān)碼。 PCnew = PC(當(dāng)前) +偏移 /*偏移值是編譯器幫我們算好的。*/ PCnew = (4+8) + 0x28 =0x34 /* +8是ARM架構(gòu)決定的。 */那怎么寫位置無(wú)關(guān)碼的代碼?1:匯編中使用 bl或 b 指令進(jìn)行跳轉(zhuǎn)2:C語(yǔ)言中不使用全局變量,靜態(tài)變量 當(dāng)PC指針跳到應(yīng)該位于的位置時(shí) 就不用考慮全局變量,靜態(tài)變量這些限制 以上詳情看 視頻例子 UART 的代
26、碼。關(guān)于位置無(wú)關(guān)的一些心得:當(dāng)程序被拷貝到4K RAM里面開始執(zhí)行。如果用位置無(wú)關(guān)碼寫程序,程序之間的跳轉(zhuǎn)都是用相對(duì)跳轉(zhuǎn)的(PC = 當(dāng)前地址 + XXX)。而不是用絕對(duì)地址(鏈接地址)也就是說,當(dāng)程序再4K里面運(yùn)行的時(shí)候,PC的值就是在這4K里面,當(dāng)用相對(duì)跳轉(zhuǎn)的時(shí)候,要跳轉(zhuǎn)的地址也就只能出現(xiàn)在4K。但是如果用了位置相關(guān)碼,那么一跳轉(zhuǎn)就到SDRAM了LCD原理圖:有哪些信號(hào):1:垂直方向的同步信號(hào) VSYNC2:水平方向的同步信號(hào) HSYNC3:使能信號(hào) VDEN4:背光信號(hào) LED- LED+ GPB0 輸出高電平 背光芯片才會(huì)工作 LCD才會(huì)點(diǎn)亮。 所以第一步就是要設(shè)置 GPB0 為輸出高
27、電平5:時(shí)鐘信號(hào) VCLK6:數(shù)據(jù)信號(hào) VD0 VD23寫程序:1:打開背光2:時(shí)序設(shè)置3:在Frame Buffer寫數(shù)據(jù)LCD選定之后,像素寬度是固定的。 JZ2440的 LCD的像素寬度就是 16bpp(一個(gè)像素用16位數(shù)據(jù)表示)JZ2440 LCD 上每一個(gè)像素對(duì)應(yīng) Frame Buffer 里的2字節(jié)(因?yàn)?6bpp)。那要使LCD的像素與 Frame Buffer 對(duì)應(yīng)? 設(shè)置BSWP HWSWP兩個(gè)寄存器。詳情見手冊(cè)。因?yàn)長(zhǎng)CD 的像素寬度是固定的16bpp,但是如果硬是要使用 8bpp。就要涉及 “調(diào)色板(Palette)”。8bpp 的數(shù)據(jù)寬度可以有 256 種顏色。 所以調(diào)
28、色板(Palette)中也是256中顏色,但是為了跟LCD的 16bpp 對(duì)應(yīng)。所以調(diào)色板(Palette)上 用16位來存一種顏色。要使用調(diào)色板,需要將調(diào)色板初始化 LCD 控制器: LCDCONn (n=15)清屏: 可以將一種顏色 發(fā)給 TPAL寄存器,然后使能 TPAL寄存器。之后 2440 LCD控制器就會(huì)從TPAL寄存器取顏色發(fā)給LCD(全屏)LCD 代碼中 LCDSADDR1 = (LCDFRAMEBUFFER>>22)<<21) | LOWER21BITS(LCDFRAMEBUFFER>>1); LCDSADDR2 = LOWER21BITS
29、(LCDFRAMEBUFFER+ (LINEVAL_TFT_240320+1)*(HOZVAL_TFT_240320+1)*2)>>1); LCDSADDR3 = (0<<11) | (LCD_XSIZE_TFT_240320*2/2);這一段是2440要我們?cè)趺醋鑫覀兙驮趺醋?沒什么好說的。UBOOT 的最終目的是要 啟動(dòng)內(nèi)核 1:從flash 讀出內(nèi)核,放到SDRAM 2:?jiǎn)?dòng)內(nèi)核所以UBOOT要實(shí)現(xiàn)的核心功能:1:讀flash,寫flash。2:初始化SDRAM,初始化時(shí)鐘,關(guān)看門狗。3:從flash 讀出內(nèi)核4:?jiǎn)?dòng)內(nèi)核為了開發(fā)方便: 開發(fā)功能:1:燒寫flas
30、h2:初始化網(wǎng)卡(用網(wǎng)絡(luò)下載文件)3:初始化USB(用USB下載文件)4:初始化串口(在PC機(jī)上中斷操作UBOOT)UBOOT make 的時(shí)候?yàn)槭裁粗酪?make 100ask_24x0.config? 是因?yàn)閁BOOT文件中有一個(gè) README 文件。里面寫有了關(guān)于UBOOT的約定。分析UBOOT文件源碼時(shí)首先要分析 MakeFile 找到鏈接地址,然后根據(jù)鏈接地址找到第一個(gè)源文件,然后根據(jù)源文件一路分析貫通。 視頻以后多看幾遍。UBOOT heads.S 完成步驟1:設(shè)為svc 管理模式2:關(guān)看門狗3:屏蔽中斷4:初始化SDRAM5:設(shè)置棧6:初始化時(shí)鐘7:重定位(將代碼從 nand
31、 flash 中拷到 SDRAM )8:清bss段。所謂bss段就是,未定義的一些靜態(tài)變量,全局變量。以免占用內(nèi)存。9:調(diào)用 start_armboot C函數(shù)。UBOOT的核心是命令,讀出內(nèi)核以及啟動(dòng)內(nèi)核都是需要命令的。所以可以想象到UBOOT的代碼中一定有一個(gè)命令的結(jié)構(gòu)體,這個(gè)結(jié)構(gòu)體中包含了所有的命令,當(dāng)我們?cè)赨BOOT界面上輸入命令是會(huì)去匹配,匹配到哪個(gè)命令就執(zhí)行哪個(gè)命令。內(nèi)核啟動(dòng)流程分析:1:解壓縮2:打補(bǔ)丁 打補(bǔ)丁用 patch 命令 patch -p_ <某個(gè)目錄下的補(bǔ)丁文件3:配置 配置有三種方式 a:make menuconfig b:使用默認(rèn)配置在上面修改 c:使用廠家
32、提供的配置文件 如果直接 make menuconfig 的話里面成千上萬(wàn)的配置選項(xiàng),是很復(fù)雜的。所以我們用默認(rèn)的配置文件。那我們不知道默認(rèn)的配置文件怎么辦呢? 可以再終端輸入 fine -name "*defconfig*"查找有哪些默認(rèn)的配置文件的目錄,然后在相應(yīng)目錄下找到自己需要的配置文件。2440開發(fā)板 用的配置文件是 s3c2410_defconfig。然后執(zhí)行 make s3c2410_defconfig。最后執(zhí)行 make menuconfig執(zhí)行完 make menuconfig 后就會(huì)在s3c2410_defconfig 的基礎(chǔ)上出現(xiàn)一個(gè)配置菜單,然后就可
33、以自己修改配置項(xiàng)了。由上述的步驟可以知道,當(dāng)執(zhí)行 make s3c2410_defconfig 后,終端提示 所有的配置項(xiàng)被寫入.config里面。所以make menuconfig 是去.config里面讀取需要的配置項(xiàng)。所以使用廠家的配置文件,只需要將廠家的配置文件CP成.config就行了。(cp config_ok .config)結(jié)合makefile進(jìn)行分析以一個(gè)配置項(xiàng)為例:CONFIG_DM90001:c源碼中定義了 CONFIG_DM9000 是個(gè)宏 宏對(duì)C語(yǔ)言來說只能在C語(yǔ)言和頭文件中定義。所以這個(gè)宏來源于autoconfig.h2:子目錄下Makefile :drivers/
34、net/makefile3:include/config/autoconfig 中定義了 CONFIG_DM9000 。4:include/linux/autoconfig.h 由名字可以知道autoconfig.h是配置的時(shí)候自動(dòng)根據(jù).config生成的。查看autoconfig.h的時(shí)候發(fā)現(xiàn)里面的宏大部分都被定義為“1”。也就是說在配置內(nèi)核的時(shí)候無(wú)論配置項(xiàng)(DM9000)被設(shè)置為“Y” “N” 還是“M”都被定義為“1”。那么 Y N M 之間的差別怎么體現(xiàn)呢?竟然C語(yǔ)言和頭文件中不能體現(xiàn)區(qū)別,那么只能在子目錄中的Makefile中體現(xiàn)。這里插講一下子目錄的Makefile。 格式比較簡(jiǎn)單
35、 obj-y +=xxx.o 表明xxx.c這個(gè)文件最后會(huì)編譯進(jìn)內(nèi)核 obj-m += yyy.o 表示 yyy.c這個(gè)文件最后會(huì)變編譯成一個(gè)可加載的模塊。所以子目錄中的Makefile 寫成 obj-$(config_DM9000) +=dm9000.o 分析內(nèi)核的Makefile 可以找到第一個(gè)文件,還有鏈接腳本。第一個(gè)文件 arch/arm/kernel/head.s鏈接腳本 arch/arm/kernel/vmlinux.lds內(nèi)核: 最終目的是要運(yùn)行應(yīng)用程序1:處理UBOOT傳入的參數(shù) a:判斷是否支持這個(gè)CPU b:判斷是否支持這個(gè)單板(UBOOT啟動(dòng)內(nèi)核時(shí)傳入的機(jī)器ID) c:使
36、能MMU d:跳到start_kernel2:掛接根文件系統(tǒng)內(nèi)核怎樣啟動(dòng)第一個(gè)應(yīng)用程序1:打開一個(gè)設(shè)備open(dev/console) /*這三個(gè)程序代表 printf scanf err() */ sys_dup(0) sys_dup(0)2:然后用run_init_process(某個(gè)目錄下的程序); 例如:run_init_process(“/sbin/init”); 這個(gè)函數(shù)啟動(dòng)某個(gè)程序busybox:ls cp cd等等的組合 我們執(zhí)行l(wèi)s cp cd 等命令時(shí),實(shí)際上就是執(zhí)行busybox這個(gè)程序 ls cp cd 等都是指向busybox內(nèi)核的最終目的不是啟動(dòng)第一個(gè)文件 sbi
37、n/init 而是要啟動(dòng)用戶程序。但是怎么知道要啟動(dòng)什么程序呢? 做手機(jī)的啟動(dòng)手機(jī)程序 做監(jiān)控的啟動(dòng)監(jiān)控程序。 所以需要一個(gè)配置文件 指定應(yīng)用程序還有指定何時(shí)執(zhí)行。 而內(nèi)核的配置文件一般來說在etc/目錄下如果沒有配置文件的話,內(nèi)核會(huì)自動(dòng)執(zhí)行一個(gè)默認(rèn)的配置項(xiàng)。busybox-> init_main parse_inittab() file = fopen(INITTAB,"r"); /打開配置文件 /etc/inittab 如果沒有配置文件的話,內(nèi)核會(huì)自動(dòng)執(zhí)行一個(gè)默認(rèn)的配置項(xiàng) 如果有的話就會(huì)對(duì)配置文件進(jìn)行解析,例如 #開頭的忽略當(dāng)做注釋,為id加個(gè)/dev/的前綴。
38、解析完之后最終要調(diào)用 new_init_action(a->action,command,id) new_init_action 要做什么事情 1:創(chuàng)建一個(gè)init_action結(jié)構(gòu),這個(gè)結(jié)構(gòu)的內(nèi)容用new_init_action(a->action,command,id)中的參數(shù)進(jìn)行填充。 2:把這結(jié)構(gòu)放入init_action_list鏈表 run_actions(SYSINIT); /*執(zhí)行*/ waitfor(a,0); /*執(zhí)行程應(yīng)用序,等待它執(zhí)行完畢*/ run(a); /*創(chuàng)建子進(jìn)程,子進(jìn)程就是process里面指定的應(yīng)用程序*/ waitpid(runpid,&am
39、p;status,0); /* 等待它結(jié)束*/ delete_init_action(a); /*把init_action結(jié)構(gòu)在init_action_list鏈表里刪掉,所以用run_actions(SYSINIT); 定義的程序 執(zhí)行一次就被刪掉了。*/ run_actions(WAIT); waitfor(a,0); /*執(zhí)行程應(yīng)用序,等待它執(zhí)行完畢*/ run(a); /*創(chuàng)建子進(jìn)程,子進(jìn)程就是process里面指定的應(yīng)用程序*/ waitpid(runpid,&status,0); /* 等待它結(jié)束*/ delete_init_action(a); /*把init_actio
40、n結(jié)構(gòu)在init_action_list鏈表里刪掉,所以用run_actions(SYSINIT); 定義的程序 執(zhí)行一次就被刪掉了。*/ run_actions(ONCE); /*ONCE 跟前面的 SYSINIT,WAIT有點(diǎn)不一樣,因?yàn)闆]有 waitpid(runpid,&status,0); 所以init進(jìn)程不會(huì)等待它執(zhí)行完畢。*/ run(a); delete_init_action(a); while(1) run_actions(RESPAWN); if (a->pid = 0) a->pid = run(a); run_actions(ASKFIRST);
41、if (a->pid = 0) a->pid = run(a); wpid = wait(NULL); /*等待子進(jìn)程退出*/ while(wpid>0) a->pid = 0; /*退出后,就這是pid=0*/ inittab格式:<id>:<runlevels>:<action>:<process>id-> /dev/id :用作終端,stdin,stdout,stderr: printf scanf err /*<id>: WARNING: This field has a non-traditio
42、nal meaning for BusyBox init!*/runlevels :忽略 /*The runlevels field is completely ignored.*/action :執(zhí)行時(shí)機(jī) /*Valid actions include: sysinit, respawn, askfirst, wait, once, restart, ctrlaltdel, and shutdown.*/process :應(yīng)用程序或腳本 /* Specifies the process to be executed and it's command line.*/由上可知,一個(gè)最小的
43、根文件系統(tǒng)需要的項(xiàng):1: /dev/console /dev/null2:init->busybox3:/etc/inittab /*配置文件*/4: 配置文件里指定的應(yīng)用程序5:庫(kù) init本身,即busybox 編譯busybox在源碼中找到“INSTALL”文件,閱讀文件知道怎么編譯busybox make menuconfig # This creates a file called ".config" make # This creates the "busybox" executable make install # or make C
44、ONFIG_PREFIX=/path/from/root install /*默認(rèn)是安裝到PC機(jī)中的文件系統(tǒng)的,為了避免破壞整個(gè)系統(tǒng)。 所以我們應(yīng)該安裝到我們指定的目錄里面*/ 配置 busybox 的時(shí)候 配置上 Tab completion 以后使用的時(shí)候比較好用。 Tab completion (Tab 補(bǔ)全) 輸入命令的時(shí)候按 tab鍵會(huì)自動(dòng)補(bǔ)全命令 例如:cd /work/ cd/wo此時(shí)按tab鍵 會(huì)自動(dòng)補(bǔ)全為 cd /work/ make menuconfig 后 make 編譯busybox 的時(shí)候可能會(huì)出現(xiàn)錯(cuò)誤,出現(xiàn)措錯(cuò)誤的話就重新編譯,將出現(xiàn)錯(cuò)誤的命令配置項(xiàng)去掉。如果實(shí)在是
45、想要用這個(gè)命令就上網(wǎng)搜。解決辦法。make好之后千萬(wàn)不要直接 make install 因?yàn)槟J(rèn)安裝到 PC機(jī),這樣會(huì)破壞我們的電腦。先創(chuàng)建一個(gè)目錄(/work/nfs_root/first_root/tmp),然后 make CONFIG_PREFIX=/work/nfs_root/tmp install根據(jù)這五項(xiàng):1: /dev/console /dev/null2:init->busybox3:/etc/inittab /*配置文件*/4: 配置文件里指定的應(yīng)用程序5:庫(kù) 創(chuàng)建最小的根文件系統(tǒng)(在 /work/nfs_root 目錄下)第一 創(chuàng)建 /dev/console /dev
46、/null 這兩個(gè)設(shè)備文件。怎么創(chuàng)建呢? 用sudo mknod console 【設(shè)備類型】 【主設(shè)備號(hào)】 【次設(shè)備號(hào)】先看看PC機(jī)上/dev/console /dev/null 這兩個(gè)文件是怎么回事。 用 ls /dev/console /dev/null -l 命令行查看設(shè)備的 主設(shè)備號(hào) 次設(shè)備號(hào) crw-1 root root 5,1 2010-11-26-07:47 /dev/console /*開頭的“C”表示該設(shè)備是字符設(shè)備,“5”是主設(shè)備號(hào),“1”是次設(shè)備號(hào)*/ crw-rw-rw-1 root root 1,3 2010-11-26-07:47 /dev/null /*開頭的
47、“C”表示該設(shè)備是字符設(shè)備,“1”是主設(shè)備號(hào),“3”是次設(shè)備號(hào)*/由上可知 sudo mknod console c 5 1 sudo mknod null c 1 3 第二 要構(gòu)造一個(gè) inittab第三 安裝glibc庫(kù)mkdir /work/nfs_root/first_root/libcd /work/tools/gcc-3.4.5-glibc-2.3.6/arm-linux/lib 進(jìn)入含有g(shù)libc庫(kù)的目錄下。cp *.so* /work/nfs_root/first_root/lib -d 將glibc庫(kù)拷貝到 最小根文件系統(tǒng)目錄下。注意拷貝的時(shí)候要加個(gè)“-d”選項(xiàng),否則庫(kù)文件會(huì)很大。至此我們已經(jīng)做好了最少根文
溫馨提示
- 1. 本站所有資源如無(wú)特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 江蘇省連云港市本年度(2025)小學(xué)一年級(jí)數(shù)學(xué)統(tǒng)編版課后作業(yè)((上下)學(xué)期)試卷及答案
- 非婚生子分手協(xié)議書2022.5
- 中藥鑒定學(xué)試題庫(kù)及參考答案
- 不動(dòng)產(chǎn)測(cè)繪員初級(jí)模擬考試題(含參考答案)
- 2025中西醫(yī)執(zhí)業(yè)醫(yī)師考試用書選擇指南:科學(xué)備考高效通關(guān)
- 玻璃制品的展示設(shè)計(jì)創(chuàng)新考核試卷
- 糖制品營(yíng)銷策略與渠道管理考核試卷
- 航天器空間對(duì)接機(jī)構(gòu)設(shè)計(jì)與測(cè)試考核試卷
- 滾動(dòng)軸承在精密儀器中的使用考核試卷
- 肥料包裝設(shè)計(jì)與市場(chǎng)營(yíng)銷考核試卷
- 家庭教育講座活動(dòng)流程
- 大學(xué)《思想道德與法治》期末考試復(fù)習(xí)題庫(kù)(含答案)
- 麥肯錫入職培訓(xùn)第一課在線閱讀
- 精神障礙社區(qū)康復(fù)服務(wù)投標(biāo)方案
- 省級(jí)課題結(jié)題報(bào)告范本
- 什么叫干槽癥課件
- 神經(jīng)形態(tài)計(jì)算詳述
- 電纜敷設(shè)勞務(wù)分包合同(通用)
- 造價(jià)咨詢公司規(guī)章制度及管理辦法
- 文房四寶(課堂PPT)
- 充電站工程監(jiān)理細(xì)則
評(píng)論
0/150
提交評(píng)論