kernel mtd 分区与UBOOT 分区的理解
static struct mtd_partition smdk_default_nand_part[] = {
????? [0] = {
?????????? .name???? = "uboot",
?????????? .offset = 0x00000000,
?????????? .size???? = 0x00040000,
????? },
????? [1] = {
?????????? .name???? = "kernel",
?????????? .offset = 0x00200000,
?????????? .size???? = 0x00300000,
????? },
????? [2] = {
?????????? .name???? = "yaffs2",
?????????? .offset = 0x00500000,
?????????? .size???? = MTDPART_SIZ_FULL
????? }
};
很顯然,在uboot和kernel分區(qū)中存在間隙,心中產(chǎn)生了疑問(wèn),難道MTD分區(qū)的時(shí)候要有注意的問(wèn)題?通過(guò)各方查找資料和查閱書(shū)籍,找到了原因。不對(duì)的地方還請(qǐng)大家指正。
?
??????? 首先說(shuō)一下Linux下固態(tài)存儲(chǔ)設(shè)備(NAND flash算其中一種)對(duì)系統(tǒng)組件的安排方式,一般為
| ? 引導(dǎo)加載程序 | ? 引導(dǎo)參數(shù) | ? 內(nèi)核 | ? 根文件系統(tǒng) |
?
也就是說(shuō),在NAND flash中,各部分的程序是這樣安排的,但哪一端是高地址是依體系結(jié)構(gòu)不同而不同的,對(duì)于ARM,引導(dǎo)加載程序在最低地址處,因此,無(wú)論是uboot的分區(qū)還是內(nèi)核MTD分區(qū),引導(dǎo)加載程序的分區(qū)都放在了最低地址處。那么,兩個(gè)分區(qū)到底怎么聯(lián)系起來(lái),而我們又該怎么設(shè)置MTD分區(qū)呢?先給出我的開(kāi)發(fā)板uboot的分區(qū)信息:
?
bootargs=noinitrd root=/dev/mtdblock2??init=/linuxrc console=ttySAC0
mtdparts=mtdparts=nandflash0:256k@0(bios),128k(params),128k(toc),512k(eboot),1024k(logo),3m(kernel),-(root)
?
?????? 然后說(shuō)一下MTD分區(qū),這個(gè)分區(qū)是內(nèi)核可以識(shí)別的分區(qū),也就是說(shuō),內(nèi)核的操作都是基于MTD分區(qū)的;而uboot的分區(qū)只是為了方便操作,例如,我想將內(nèi)存中0x30000000地址處的內(nèi)容寫到NAND flash的偏移量為2M的地址處,即uboot分區(qū)中kernel的起始位置,一般情況,我們要寫
nand write 0x30000000 0x00200000
但如果有了uboot的分區(qū),我們可以寫
nand write 0x30000000 kernel
?
??????? 說(shuō)清上面的問(wèn)題,為了進(jìn)一步闡述后面的問(wèn)題,這里再講一下我對(duì)uboot引導(dǎo)過(guò)程的理解,當(dāng)系統(tǒng)啟動(dòng)后,uboot開(kāi)始執(zhí)行,他分兩個(gè)階段完成工作,主要是一些初始化,然后,加載內(nèi)核并傳遞內(nèi)核參數(shù),之后跳入內(nèi)核執(zhí)行,內(nèi)核完成它的初始化工作,其中包括掛載文件系統(tǒng)。
?
?????? 現(xiàn)在,我們可以翻回頭看上面程序中的MTD分區(qū)了。MTD分區(qū)中的uboot分區(qū)明顯對(duì)應(yīng)了uboot分區(qū)中的bios分區(qū)(從0開(kāi)始,大小為128K),而MTD分區(qū)中的kernel和yaffs2分區(qū)的起始地址和大小也分別對(duì)應(yīng)uboot分區(qū)中的kernel和root分區(qū)。而因?yàn)槲覀儾恍枰猽boot分區(qū)中的其他部分,所以在MTD分區(qū)中出現(xiàn)了這一部分空隙。但為什么這么安排呢?
?
?????? 回想我們?cè)跓龑懗绦驎r(shí)候的操作,比如我們選擇燒寫內(nèi)核鏡像,此時(shí),uboot實(shí)際執(zhí)行了一條語(yǔ)句,類似于
?
#define kernel 0x00200000
memcpy(kernel,0x30000000,SZ_3M)
?
?????? 這里我們燒寫程序的入口地址是0x30000000,也就是說(shuō),uboot的下載模式將我們燒寫到內(nèi)存0x30000000處的數(shù)據(jù),搬到了NAND flash的kernel處,保存了起來(lái),因此,這里要清楚,我們燒寫程序時(shí),實(shí)際是將程序先燒寫到了內(nèi)存當(dāng)中,然后由內(nèi)存搬運(yùn)到NAND flash中,如果此時(shí)我們的MTD分區(qū)與uboot中的分區(qū)是一致的,那么內(nèi)核將來(lái)運(yùn)行時(shí)可以很方便的找到內(nèi)核程序所在的位置,同樣,對(duì)文件系統(tǒng)的yaffs2分區(qū)也是如此,而且,與內(nèi)核分區(qū)相比,文件系統(tǒng)的分區(qū)將顯得更加重要,因?yàn)閷⒅苯佑绊懙礁募到y(tǒng)能否掛載,這里是因?yàn)樯厦嫣岬降囊恍?/p>
?
bootargs=noinitrd root=/dev/mtdblock2 init=/linuxrc console=ttySAC0
?
?????? 這里,uboot指定了根文件系統(tǒng)的代碼來(lái)自于mtdblock2,也就是MTD分區(qū)的第三個(gè)分區(qū)(第一個(gè)編號(hào)為0),也就是我上面說(shuō)到的,uboot完成初始化后,加載內(nèi)核,而內(nèi)核要完成文件系統(tǒng)的掛載,他從哪里找文件系統(tǒng)?就是這里!/dev/mtdblock2!
?????? 所以,現(xiàn)在我們看到,MTD分區(qū)的原因,而且最關(guān)鍵的在這里,其他分區(qū)如果與uboot的分區(qū)不一致還情有可原,但如果MTD分區(qū)中文件系統(tǒng)的分區(qū)與uboot中的root分區(qū)不一致,將會(huì)直接導(dǎo)致系統(tǒng)無(wú)法啟動(dòng)!
當(dāng)然,之前操作的都是物理地址,當(dāng)內(nèi)核真正運(yùn)行起來(lái)以后,將開(kāi)始使用虛擬地址。
同樣的,其他幾個(gè)引導(dǎo)參數(shù)也應(yīng)該得到滿足,系統(tǒng)才可能正常運(yùn)行起來(lái)
init=/linuxrc?? init進(jìn)程的位置。
console=ttySAC0? 終端對(duì)應(yīng)tty設(shè)備,因此,在引導(dǎo)系統(tǒng)前,串口驅(qū)動(dòng)移植應(yīng)當(dāng)完成
總結(jié)
以上是生活随笔為你收集整理的kernel mtd 分区与UBOOT 分区的理解的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: BP神经网络模型介绍
- 下一篇: Enum遇到下拉框