yaffs2中,mount mtd block設(shè)備后,insmod就死掉了
但是,最新發(fā)現(xiàn)一個(gè)很詭異的問(wèn)題:
本文引用地址:http://www.ex-cimer.com/article/201611/318891.htm在mount /dev/mtdblock4 /mnt/usb_msc 后,自動(dòng)掛載成yaff2文件系統(tǒng)之后,再去insmod任何一個(gè)ko,都會(huì)死掉,而且還是沒有任何輸出信息的,連kernel的oops,對(duì)應(yīng)ko里面第一行打印,都沒有。
【解決過(guò)程】
1.后來(lái)經(jīng)過(guò)測(cè)試,發(fā)現(xiàn),對(duì)于pagesize是2K的nand flash來(lái)說(shuō)(此處由于特殊需要(硬件HW ECC占用太多),所以需要進(jìn)制yaffs2的tag ecc(以節(jié)省空間存放HW ECC)),都是可以正常工作的,但是對(duì)于4K Pagesize的nand,就工作不正常。而之前已經(jīng)用mtd test的一系列工具驗(yàn)證了,2K和4K的nand的驅(qū)動(dòng),都是可以正常工作的。
2.去看了下mtd層關(guān)于2K和4K的,有什么不一樣的地方,發(fā)現(xiàn)對(duì)應(yīng)的includemtd-abi.h中,struct nand_ecclayout中,eccpos還是64,所以將其改為128,再去測(cè)試,問(wèn)題如故。
3.其他的,找不到原因了,所以,推斷是yaffs2與MTD的兼容等方面的問(wèn)題。
4.后來(lái)又經(jīng)過(guò)測(cè)試,以/dev/mtdblock4作為參數(shù),用
insmod dwc_otg.ko
insmod gadgetfs.ko
insmod g_file_storage.ko file=/dev/mtdblock4 stall=0 removable=1
去掛載了usb masstorage,去windows中格式化該U盤成fat32,然后去板子上,去
mount /dev/mtdblock4 /mnt/usb_msc -t vfat
掛載成fat分區(qū),然后這樣,就可以避開yaffs2,只是和mtd層有關(guān)系,結(jié)果測(cè)試下來(lái),
數(shù)據(jù)讀寫,都還是對(duì)的,但是還是先mount,后面再執(zhí)行其他的,涉及到內(nèi)核數(shù)據(jù)結(jié)果的操作,就還是死掉
即不論是掛載成yaffs2:
mount /dev/mtdblock4 /mnt/usb_msc
還是
mount /dev/mtdblock4 /mnt/usb_msc -t vfat
后面對(duì)該分區(qū)的數(shù)據(jù)讀寫都是OK的,但是就是之后再去
insmod ***.ko 或者其他的loadkmap 等等涉及內(nèi)核的操作的程序,都會(huì)導(dǎo)致內(nèi)核死掉,而且此處的死掉,
和一般的oops,空指針等還不同,完全沒有任何輸出。
死掉后,去用rvds連接板子,發(fā)現(xiàn)pc始終在0xFFFF000C,對(duì)應(yīng)的就是ARM 的預(yù)取指中止異常:
ARM體系結(jié)構(gòu)所支持的異常類型
異常類型
復(fù)位
未定義指令
軟件中斷
指令預(yù)取中止
數(shù)據(jù)中止
IRQ
FIQ
異常向量表(Exception Vectors)
地址
0x0000,0000
ox0000,0004
0x0000,0008
0x0000,000c
0x0000,0010
0x0000,0014
0x0000,0018
0x0000,001c
也就是說(shuō)明,最后出錯(cuò)的預(yù)取指中止,就是去本來(lái)應(yīng)該存儲(chǔ)對(duì)應(yīng)的指令(代碼)的地方,去讀取指令,
結(jié)果實(shí)際取指取出來(lái)的是非法的,所以出現(xiàn)此預(yù)取指中止異常,死掉了。
5.最后發(fā)現(xiàn),問(wèn)題出在
includelinuxmtdnand.h中:
struct nand_buffers {
uint8_t ecccalc[MTD_NAND_MAX_OOBSIZE];
uint8_t ecccode[MTD_NAND_MAX_OOBSIZE];
uint8_t databuf[MTD_NAND_MAX_PAGESIZE + MTD_NAND_MAX_OOBSIZE];
};
databuf的對(duì)應(yīng)的宏:
#define MTD_NAND_MAX_PAGESIZE 2048
#define MTD_NAND_MAX_OOBSIZE 64
因此,在
int nand_scan_tail(struct mtd_info *mtd)
{
...
if (!(chip->options & NAND_OWN_BUFFERS))
...
}
kmalloc去申請(qǐng)的空間,就是2048bytes了,這樣,對(duì)于2K pagesize的nand,肯定是工作正常的,但是對(duì)于4K pagesize的,如果上層,比如yaffs2,通過(guò)mtd去讀取數(shù)據(jù),一個(gè)page的數(shù)據(jù)就是4K了,然后會(huì)放到這個(gè)buffer里面,結(jié)果后面2048的系統(tǒng)數(shù)據(jù),就被沖掉了,如果系統(tǒng)之后用到這部分的數(shù)據(jù)或指令,就會(huì)有問(wèn)題。而此處出現(xiàn)的預(yù)取指中止異常,那就是說(shuō)明,后面這2048字節(jié),里面很可能包含了某些系統(tǒng)相關(guān)的指令(和其他數(shù)據(jù)),結(jié)果系統(tǒng)執(zhí)行到這里,取指不正常,所以掛掉了。
【解決辦法】
解決辦法也很簡(jiǎn)單,就是把對(duì)應(yīng)的宏,該成足夠大,比如:
#define MTD_NAND_MAX_PAGESIZE 8192
#define MTD_NAND_MAX_OOBSIZE
這樣,以后即使是8K的nand,也可以很好的支持了。
評(píng)論