




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
1、nand 啟動時 bank0 失效,即用不了NOP FLASHnand flash 前4K被強(qiáng)制復(fù)制到片內(nèi) SRAM 4K內(nèi)存中,然后CPU會從零地址(SRAM)開始執(zhí)行。nor 啟動時 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í)行往也要返回。啟動文件: 調(diào)用 main,調(diào)用完之后要返回,所以要設(shè)置返回地址。最后要進(jìn)行一些清理工作。軟件初始化: 設(shè)置棧 /*設(shè)置棧就是把棧指針SP指向某個內(nèi)存,假如指向S
2、DRAM則要先初始化SDRAM才能設(shè)置棧 */設(shè)置返回地址 /*bl指令會跳轉(zhuǎn)到main函數(shù),并且把返回地址保存在LR寄存器里面。*/調(diào)用main清理工作硬件初始化:關(guān)看門狗 /*上電時候看門狗啟動,會倒數(shù)計時三秒內(nèi)沒有關(guān)閉就會重啟系統(tǒng)。所以要關(guān)掉*/初始化時鐘 /*想要跑的更快要初始化時鐘*/初始化SDRAM/*/設(shè)置返回地址:blmain /*bl指令會跳轉(zhuǎn)到main函數(shù),并且把返回地址保存在LR寄存器里面。*/ /*bl 指令會把返回地址存在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對應(yīng)的GPF4/5/6三個引腳設(shè)為輸出按位操作:想要清零 : 按位與 /*例如清bit3 則 a&=(1<<3)*/想要置“1” : 按位或 /*例如置bit3 則 a|= (1<<3)*/SRAM在芯片手
4、冊里面稱為 steppingstoneCPU通過存儲管理器才知道怎么訪問外部的設(shè)備 例如 SDRAM DM9000網(wǎng)卡等想訪問一個芯片,需要哪些條件1:地址線(例如SDRAM 行地址13位,列地址9位) 看芯片手冊2:數(shù)據(jù)線 /* 8/16/32位 數(shù)據(jù)寬度 例如SDRAM 位寬32位 SDRAM32位,所以 ADDR0,ADDR1就不需要使用。 */ 看原理圖3:時鐘/頻率 (刷新周期 8192/64ms 即刷新8192次需要64ms)看芯片手冊4:芯片相關(guān):例如SDRAM(行地址,列地址,Bank) 看芯片手冊SDRAM32位,所以 ADDR0,ADDR1就不需要使用。因?yàn)?440的地址的
5、單位是byte(8位),所以CPU發(fā)出的0,1,2,3這四個地址都是訪問到SDRAM地址中的同一個單元。返回都是返回同一個四字節(jié)(32位)的數(shù)據(jù)。假如訪問的芯片去16位的,則ADDR0 就不需要使用。想要訪問某個芯片(如SDRAM)先要配置存儲管理器(位寬,行列地址,刷新周期)。所謂配置也就是設(shè)置寄存器。2440可以接8個外設(shè)(SDRAM,DM9000網(wǎng)卡,NOR FLASH等等),因?yàn)橛?個Bank,有8條片選信號(CS信號)。 Bank05都是一樣的結(jié)構(gòu)。Bank67比較特別,它們可以接SDRAM。 內(nèi)存可以分為SRAM,SDRAM,DDR等等。SRAM很快但是比較貴,使用方法簡單,直接發(fā)
6、地址信號就可以了。SDRAM比較便宜且訪問比較復(fù)雜,它的地址還分為Bank地址,行地址,列地址。還要不斷的刷新SDRAM(REFRESH寄存器就是用來設(shè)置刷新周期的),不刷新數(shù)據(jù)就會丟失。網(wǎng)卡,NOR FLASH它們的接口跟根SRAM的接口是一樣的,術(shù)語上稱為 RAM like。每個Bank可以外接128M的東西,尋址空間是128M。bank7/bank6可以組(128M/128M,64M/64M,32M/32M等)大程序啟動過程:1:一上電nand flash前4K被拷貝到SRAM中。2:程序會先關(guān)看門狗,初始化存儲管理寄存器,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)行時程序“應(yīng)該”位于哪里。所以head.s 就應(yīng)該從片內(nèi)SRAM拷到SDRAM中去。當(dāng)前PC值 = 當(dāng)前指令的地址 + 8 / pc = 當(dāng)前指令地址 + 8MMU:權(quán)限管理,地址映射。使用MMU時,使用CPU發(fā)出的地址是虛擬地址?;蛘呤钦鎸?shí)的物理地址。CPU發(fā)出的是物理地址還是虛擬地址CPU是不在乎的,CPU沒有虛擬地址和物理地址概念。寫程序的時候
8、,我們說的地址例如鏈接地址,也沒有虛擬地址,物理地址概念。就是一個單純的地址。地址只是從CPU角度看到的。虛擬地址(VA)怎么轉(zhuǎn)換為物理地址(PA)。 對于mips架構(gòu)來說 VA=0xA000,0000 + PA /* VA=fun(PA)*/對于ARM結(jié)構(gòu)來說:表格: 一級頁表,二級頁表。 對于ARM來說有兩種映射:段和頁段映射: 表格里面每一個表項(xiàng)對應(yīng)一段,表示大小是 1M。假如CPU的地址數(shù)是4G,則需要的表格數(shù)位4G/1M=4*1024=4096個。創(chuàng)建頁表:啟動前和啟動瞬間,地址要連續(xù)。A:所以04096的虛擬地址要對應(yīng)04096的物理地址使用MMU會加快程序的運(yùn)行速度,因?yàn)橛蠨CA
9、CH,ZCACH。這些會加快程序運(yùn)行速度。1,MMU首先知道你創(chuàng)建的這些頁表項(xiàng)都放在哪里;2,MMU通過虛擬地址的高12位可以找到對應(yīng)的頁表項(xiàng),并且這個頁表項(xiàng)的高12位就是物理地址的高12位;3,虛擬地址的低20位就是物理地址的低20位;4,頁表項(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; 此語句是將指針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用來存放頁表 */ 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”地址不是一個概
12、念。那Nand flash 是怎么編址的呢?從原理圖上,Nand flash 與CPU相連的只有 數(shù)據(jù)總線,控制總線。所以CPU發(fā)出的 地址,命令都是由數(shù)據(jù)總線進(jìn)行傳輸。但是如何分辨是 地址還是命令呢?顯然是通過控制總線進(jìn)行區(qū)分。 CLE(高電平) 信號是命令, ALE(高電平) 信號是地址, 兩個信號都無效的話 傳輸?shù)木褪菙?shù)據(jù)。 是讀數(shù)據(jù) 還是寫數(shù)據(jù) 又由 nFWE(讀) 引腳 nFRE(寫)引腳控制。Nand flash 的典型結(jié)構(gòu)是 大頁,一個大頁有2K 也就是2048字節(jié)。有64頁。 注意:每一個大頁中都有一個叫 OOB的空間(64字節(jié))。一般來說用不到OOB這個空間,例如我們要訪問第
13、2049這個字節(jié)空間,不會訪問到OOB這個空間而是訪問第二頁開始的第二個字節(jié)。所以真實(shí)的一頁是 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,連接的時
14、候,main.c中的代碼都存在NAND Flash地址4096開始處 mov r2, #2048 3. 復(fù)制長度= 2048(bytes),對于本實(shí)驗(yàn)的main.c,這是足夠了 bl nand_read 匯編和C語言傳遞參數(shù): 如上例子,r0為傳遞給C函數(shù)(nand_read)的第一個參數(shù),r1為第二個,r2為第三個。 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ù)取終止時進(jìn)入該模式,可用于虛擬存儲及存儲保護(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í)行時進(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個模式下的寄存器不相同。其中 快中斷模式 擁有7個獨(dú)立寄存器,其余模式都是 r13 r14 兩個寄存器獨(dú)立。中斷也是一種異常發(fā)生了異常之后:1:CPU 強(qiáng)制進(jìn)入異常模式,就是切換寄存器(如上) /*這里就是說發(fā)生異常之后CPU進(jìn)入異常模式 2:PC(r15) = 異常入口 然后程序自動跳到異常入口*/設(shè)置棧,棧 sp 就是 r13。
18、異常入口是什么: 就是CPU固定的地址。 如下:* 異常向量,本程序中,除Reset和HandleIRQ外,其它異常都沒有使用* .extern main.text .global _start _start: _start 表示0地址入口復(fù)位異常的入口就是0地址,發(fā)生復(fù)位之后CPU自動跳到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會不斷重啟 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 計算返回地址 /*這個是ARM架構(gòu)決定的,所以就是這個。*/ stmdb sp!, r0-r12,lr 保存使用到的寄存器 注意,此時的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)先級寄存器 設(shè)置棧,棧 sp 就是 r13。 切換到中斷模式(或其他異常模式)時,要重新設(shè)置棧,因?yàn)閞13 (sp)是每個模式下獨(dú)有的。怎么進(jìn)入中斷? msr cpsr_c, #0xd2 進(jìn)入中斷模式,運(yùn)行這個msr cps
23、r_c 指令就可以進(jìn)入中 斷,而x0d2表示進(jìn)入哪個中斷。具體如下。0xd2 二進(jìn)制為:110 10010除r0 r15 這16個寄存器外 還有第17個寄存器 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)時鐘:2440 CPU : 400M (FCLK) 如果什么都不設(shè)置,CPU 是以晶振的頻率 12M HZ 在跑。SDRAM,MD900,NOR FLASH等: 100M 133M (HCLK)UART,定時器,I2C等 : 50M (PCLK)2440 的晶振只有12M設(shè)置 PLL 寄存器 設(shè)置頻率怎么設(shè)置 FCLK PCLK HCLK1:晶振PLL400M HZ PLL (LOCKTIME)鎖定時間寄存器(使用默認(rèn)值就可以了),MPLLCON 設(shè)置晶振頻率的寄存器2:400M
25、HZ 分頻(HCLK PCLK) 分頻寄存器 CLKDIVN 設(shè)置 波特率 UBRDIVn(n=01) 有一個公式 看數(shù)據(jù)手冊位置相關(guān):PCnew = 某個絕對值引入一個新的概念:位置無關(guān)碼 bl和b 指令就是位置無關(guān)碼。 PCnew = PC(當(dāng)前) +偏移 /*偏移值是編譯器幫我們算好的。*/ PCnew = (4+8) + 0x28 =0x34 /* +8是ARM架構(gòu)決定的。 */那怎么寫位置無關(guān)碼的代碼?1:匯編中使用 bl或 b 指令進(jìn)行跳轉(zhuǎn)2:C語言中不使用全局變量,靜態(tài)變量 當(dāng)PC指針跳到應(yīng)該位于的位置時 就不用考慮全局變量,靜態(tài)變量這些限制 以上詳情看 視頻例子 UART 的代
26、碼。關(guān)于位置無關(guān)的一些心得:當(dāng)程序被拷貝到4K RAM里面開始執(zhí)行。如果用位置無關(guān)碼寫程序,程序之間的跳轉(zhuǎn)都是用相對跳轉(zhuǎn)的(PC = 當(dāng)前地址 + XXX)。而不是用絕對地址(鏈接地址)也就是說,當(dāng)程序再4K里面運(yùn)行的時候,PC的值就是在這4K里面,當(dāng)用相對跳轉(zhuǎn)的時候,要跳轉(zhuǎn)的地址也就只能出現(xiàn)在4K。但是如果用了位置相關(guān)碼,那么一跳轉(zhuǎn)就到SDRAM了LCD原理圖:有哪些信號:1:垂直方向的同步信號 VSYNC2:水平方向的同步信號 HSYNC3:使能信號 VDEN4:背光信號 LED- LED+ GPB0 輸出高電平 背光芯片才會工作 LCD才會點(diǎn)亮。 所以第一步就是要設(shè)置 GPB0 為輸出高
27、電平5:時鐘信號 VCLK6:數(shù)據(jù)信號 VD0 VD23寫程序:1:打開背光2:時序設(shè)置3:在Frame Buffer寫數(shù)據(jù)LCD選定之后,像素寬度是固定的。 JZ2440的 LCD的像素寬度就是 16bpp(一個像素用16位數(shù)據(jù)表示)JZ2440 LCD 上每一個像素對應(yīng) Frame Buffer 里的2字節(jié)(因?yàn)?6bpp)。那要使LCD的像素與 Frame Buffer 對應(yīng)? 設(shè)置BSWP HWSWP兩個寄存器。詳情見手冊。因?yàn)長CD 的像素寬度是固定的16bpp,但是如果硬是要使用 8bpp。就要涉及 “調(diào)色板(Palette)”。8bpp 的數(shù)據(jù)寬度可以有 256 種顏色。 所以調(diào)
28、色板(Palette)中也是256中顏色,但是為了跟LCD的 16bpp 對應(yīng)。所以調(diào)色板(Palette)上 用16位來存一種顏色。要使用調(diào)色板,需要將調(diào)色板初始化 LCD 控制器: LCDCONn (n=15)清屏: 可以將一種顏色 發(fā)給 TPAL寄存器,然后使能 TPAL寄存器。之后 2440 LCD控制器就會從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要我們怎么做我們就怎么做 沒什么好說的。UBOOT 的最終目的是要 啟動內(nèi)核 1:從flash 讀出內(nèi)核,放到SDRAM 2:啟動內(nèi)核所以UBOOT要實(shí)現(xiàn)的核心功能:1:讀flash,寫flash。2:初始化SDRAM,初始化時鐘,關(guān)看門狗。3:從flash 讀出內(nèi)核4:啟動內(nèi)核為了開發(fā)方便: 開發(fā)功能:1:燒寫flas
30、h2:初始化網(wǎng)卡(用網(wǎng)絡(luò)下載文件)3:初始化USB(用USB下載文件)4:初始化串口(在PC機(jī)上中斷操作UBOOT)UBOOT make 的時候?yàn)槭裁粗酪?make 100ask_24x0.config? 是因?yàn)閁BOOT文件中有一個 README 文件。里面寫有了關(guān)于UBOOT的約定。分析UBOOT文件源碼時首先要分析 MakeFile 找到鏈接地址,然后根據(jù)鏈接地址找到第一個源文件,然后根據(jù)源文件一路分析貫通。 視頻以后多看幾遍。UBOOT heads.S 完成步驟1:設(shè)為svc 管理模式2:關(guān)看門狗3:屏蔽中斷4:初始化SDRAM5:設(shè)置棧6:初始化時鐘7:重定位(將代碼從 nand
31、 flash 中拷到 SDRAM )8:清bss段。所謂bss段就是,未定義的一些靜態(tài)變量,全局變量。以免占用內(nèi)存。9:調(diào)用 start_armboot C函數(shù)。UBOOT的核心是命令,讀出內(nèi)核以及啟動內(nèi)核都是需要命令的。所以可以想象到UBOOT的代碼中一定有一個命令的結(jié)構(gòu)體,這個結(jié)構(gòu)體中包含了所有的命令,當(dāng)我們在UBOOT界面上輸入命令是會去匹配,匹配到哪個命令就執(zhí)行哪個命令。內(nèi)核啟動流程分析:1:解壓縮2:打補(bǔ)丁 打補(bǔ)丁用 patch 命令 patch -p_ <某個目錄下的補(bǔ)丁文件3:配置 配置有三種方式 a:make menuconfig b:使用默認(rèn)配置在上面修改 c:使用廠家
32、提供的配置文件 如果直接 make menuconfig 的話里面成千上萬的配置選項(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 后就會在s3c2410_defconfig 的基礎(chǔ)上出現(xiàn)一個配置菜單,然后就可
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)行分析以一個配置項(xiàng)為例:CONFIG_DM90001:c源碼中定義了 CONFIG_DM9000 是個宏 宏對C語言來說只能在C語言和頭文件中定義。所以這個宏來源于autoconfig.h2:子目錄下Makefile :drivers/
34、net/makefile3:include/config/autoconfig 中定義了 CONFIG_DM9000 。4:include/linux/autoconfig.h 由名字可以知道autoconfig.h是配置的時候自動根據(jù).config生成的。查看autoconfig.h的時候發(fā)現(xiàn)里面的宏大部分都被定義為“1”。也就是說在配置內(nèi)核的時候無論配置項(xiàng)(DM9000)被設(shè)置為“Y” “N” 還是“M”都被定義為“1”。那么 Y N M 之間的差別怎么體現(xiàn)呢?竟然C語言和頭文件中不能體現(xiàn)區(qū)別,那么只能在子目錄中的Makefile中體現(xiàn)。這里插講一下子目錄的Makefile。 格式比較簡單
35、 obj-y +=xxx.o 表明xxx.c這個文件最后會編譯進(jìn)內(nèi)核 obj-m += yyy.o 表示 yyy.c這個文件最后會變編譯成一個可加載的模塊。所以子目錄中的Makefile 寫成 obj-$(config_DM9000) +=dm9000.o 分析內(nèi)核的Makefile 可以找到第一個文件,還有鏈接腳本。第一個文件 arch/arm/kernel/head.s鏈接腳本 arch/arm/kernel/vmlinux.lds內(nèi)核: 最終目的是要運(yùn)行應(yīng)用程序1:處理UBOOT傳入的參數(shù) a:判斷是否支持這個CPU b:判斷是否支持這個單板(UBOOT啟動內(nèi)核時傳入的機(jī)器ID) c:使
36、能MMU d:跳到start_kernel2:掛接根文件系統(tǒng)內(nèi)核怎樣啟動第一個應(yīng)用程序1:打開一個設(shè)備open(dev/console) /*這三個程序代表 printf scanf err() */ sys_dup(0) sys_dup(0)2:然后用run_init_process(某個目錄下的程序); 例如:run_init_process(“/sbin/init”); 這個函數(shù)啟動某個程序busybox:ls cp cd等等的組合 我們執(zhí)行l(wèi)s cp cd 等命令時,實(shí)際上就是執(zhí)行busybox這個程序 ls cp cd 等都是指向busybox內(nèi)核的最終目的不是啟動第一個文件 sbi
37、n/init 而是要啟動用戶程序。但是怎么知道要啟動什么程序呢? 做手機(jī)的啟動手機(jī)程序 做監(jiān)控的啟動監(jiān)控程序。 所以需要一個配置文件 指定應(yīng)用程序還有指定何時執(zhí)行。 而內(nèi)核的配置文件一般來說在etc/目錄下如果沒有配置文件的話,內(nèi)核會自動執(zhí)行一個默認(rèn)的配置項(xiàng)。busybox-> init_main parse_inittab() file = fopen(INITTAB,"r"); /打開配置文件 /etc/inittab 如果沒有配置文件的話,內(nèi)核會自動執(zhí)行一個默認(rèn)的配置項(xiàng) 如果有的話就會對配置文件進(jìn)行解析,例如 #開頭的忽略當(dāng)做注釋,為id加個/dev/的前綴。
38、解析完之后最終要調(diào)用 new_init_action(a->action,command,id) new_init_action 要做什么事情 1:創(chuàng)建一個init_action結(jié)構(gòu),這個結(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)程不會等待它執(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í)行時機(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.*/由上可知,一個最小的
43、根文件系統(tǒng)需要的項(xiàng):1: /dev/console /dev/null2:init->busybox3:/etc/inittab /*配置文件*/4: 配置文件里指定的應(yīng)用程序5:庫 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)的,為了避免破壞整個系統(tǒng)。 所以我們應(yīng)該安裝到我們指定的目錄里面*/ 配置 busybox 的時候 配置上 Tab completion 以后使用的時候比較好用。 Tab completion (Tab 補(bǔ)全) 輸入命令的時候按 tab鍵會自動補(bǔ)全命令 例如:cd /work/ cd/wo此時按tab鍵 會自動補(bǔ)全為 cd /work/ make menuconfig 后 make 編譯busybox 的時候可能會出現(xiàn)錯誤,出現(xiàn)措錯誤的話就重新編譯,將出現(xiàn)錯誤的命令配置項(xiàng)去掉。如果實(shí)在是
45、想要用這個命令就上網(wǎng)搜。解決辦法。make好之后千萬不要直接 make install 因?yàn)槟J(rèn)安裝到 PC機(jī),這樣會破壞我們的電腦。先創(chuàng)建一個目錄(/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:庫 創(chuàng)建最小的根文件系統(tǒng)(在 /work/nfs_root 目錄下)第一 創(chuàng)建 /dev/console /dev
46、/null 這兩個設(shè)備文件。怎么創(chuàng)建呢? 用sudo mknod console 【設(shè)備類型】 【主設(shè)備號】 【次設(shè)備號】先看看PC機(jī)上/dev/console /dev/null 這兩個文件是怎么回事。 用 ls /dev/console /dev/null -l 命令行查看設(shè)備的 主設(shè)備號 次設(shè)備號 crw-1 root root 5,1 2010-11-26-07:47 /dev/console /*開頭的“C”表示該設(shè)備是字符設(shè)備,“5”是主設(shè)備號,“1”是次設(shè)備號*/ crw-rw-rw-1 root root 1,3 2010-11-26-07:47 /dev/null /*開頭的
47、“C”表示該設(shè)備是字符設(shè)備,“1”是主設(shè)備號,“3”是次設(shè)備號*/由上可知 sudo mknod console c 5 1 sudo mknod null c 1 3 第二 要構(gòu)造一個 inittab第三 安裝glibc庫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庫的目錄下。cp *.so* /work/nfs_root/first_root/lib -d 將glibc庫拷貝到 最小根文件系統(tǒng)目錄下。注意拷貝的時候要加個“-d”選項(xiàng),否則庫文件會很大。至此我們已經(jīng)做好了最少根文
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 會計用賬本AI應(yīng)用行業(yè)深度調(diào)研及發(fā)展戰(zhàn)略咨詢報告
- 低碳餐飲服務(wù)企業(yè)制定與實(shí)施新質(zhì)生產(chǎn)力戰(zhàn)略研究報告
- 運(yùn)動賽事贊助合作服務(wù)企業(yè)制定與實(shí)施新質(zhì)生產(chǎn)力戰(zhàn)略研究報告
- 足球新聞資訊門戶行業(yè)跨境出海戰(zhàn)略研究報告
- 農(nóng)藥生產(chǎn)能效提升企業(yè)制定與實(shí)施新質(zhì)生產(chǎn)力戰(zhàn)略研究報告
- 會計用賬本AI應(yīng)用企業(yè)制定與實(shí)施新質(zhì)生產(chǎn)力戰(zhàn)略研究報告
- 雨季施工現(xiàn)場管理與技術(shù)措施
- 2025年秋季德育與心理健康結(jié)合計劃
- 2025年教育行業(yè)軟件正版化實(shí)施計劃范文
- 2025年中國御膳豬蹄市場調(diào)查研究報告
- 2024年中國郵政儲蓄銀行廣東省分行招聘筆試真題
- 危重患者護(hù)理操作流程
- 2025-2030年中國噴涂加工行業(yè)市場全景調(diào)研及未來趨勢研判報告
- 人工智能素養(yǎng)測試題及答案(初中版)
- 人教版八年級下冊語文第三單元測試題含答案
- 四年級下冊《生活·生命.安全》全冊教案
- 2025年河南工業(yè)和信息化職業(yè)學(xué)院單招職業(yè)技能測試題庫帶答案
- 《園林微景觀設(shè)計與制作》課件-項(xiàng)目一 園林微景觀制作準(zhǔn)備
- 打開“心”世界與“壓力”和解-2025年春季學(xué)期初中生心理健康主題教育班會課件
- 肝淤血病理切片
- 教育強(qiáng)國背景下的“五育”新解與實(shí)踐路徑
評論
0/150
提交評論