yaffs2中,mount mtd block設(shè)備后,insmod就死掉了
但是,最新發(fā)現(xiàn)一個很詭異的問題:
本文引用地址:http://m.butianyuan.cn/article/201611/318891.htm在mount /dev/mtdblock4 /mnt/usb_msc 后,自動掛載成yaff2文件系統(tǒng)之后,再去insmod任何一個ko,都會死掉,而且還是沒有任何輸出信息的,連kernel的oops,對應(yīng)ko里面第一行打印,都沒有。
【解決過程】
1.后來經(jīng)過測試,發(fā)現(xiàn),對于pagesize是2K的nand flash來說(此處由于特殊需要(硬件HW ECC占用太多),所以需要進(jìn)制yaffs2的tag ecc(以節(jié)省空間存放HW ECC)),都是可以正常工作的,但是對于4K Pagesize的nand,就工作不正常。而之前已經(jīng)用mtd test的一系列工具驗(yàn)證了,2K和4K的nand的驅(qū)動,都是可以正常工作的。
2.去看了下mtd層關(guān)于2K和4K的,有什么不一樣的地方,發(fā)現(xiàn)對應(yīng)的includemtd-abi.h中,struct nand_ecclayout中,eccpos還是64,所以將其改為128,再去測試,問題如故。
3.其他的,找不到原因了,所以,推斷是yaffs2與MTD的兼容等方面的問題。
4.后來又經(jīng)過測試,以/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é)果測試下來,
數(shù)據(jù)讀寫,都還是對的,但是還是先mount,后面再執(zhí)行其他的,涉及到內(nèi)核數(shù)據(jù)結(jié)果的操作,就還是死掉
即不論是掛載成yaffs2:
mount /dev/mtdblock4 /mnt/usb_msc
還是
mount /dev/mtdblock4 /mnt/usb_msc -t vfat
后面對該分區(qū)的數(shù)據(jù)讀寫都是OK的,但是就是之后再去
insmod ***.ko 或者其他的loadkmap 等等涉及內(nèi)核的操作的程序,都會導(dǎo)致內(nèi)核死掉,而且此處的死掉,
和一般的oops,空指針等還不同,完全沒有任何輸出。
死掉后,去用rvds連接板子,發(fā)現(xiàn)pc始終在0xFFFF000C,對應(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
也就是說明,最后出錯的預(yù)取指中止,就是去本來應(yīng)該存儲對應(yīng)的指令(代碼)的地方,去讀取指令,
結(jié)果實(shí)際取指取出來的是非法的,所以出現(xiàn)此預(yù)取指中止異常,死掉了。
5.最后發(fā)現(xià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的對應(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去申請的空間,就是2048bytes了,這樣,對于2K pagesize的nand,肯定是工作正常的,但是對于4K pagesize的,如果上層,比如yaffs2,通過mtd去讀取數(shù)據(jù),一個page的數(shù)據(jù)就是4K了,然后會放到這個buffer里面,結(jié)果后面2048的系統(tǒng)數(shù)據(jù),就被沖掉了,如果系統(tǒng)之后用到這部分的數(shù)據(jù)或指令,就會有問題。而此處出現(xiàn)的預(yù)取指中止異常,那就是說明,后面這2048字節(jié),里面很可能包含了某些系統(tǒng)相關(guān)的指令(和其他數(shù)據(jù)),結(jié)果系統(tǒng)執(zhí)行到這里,取指不正常,所以掛掉了。
【解決辦法】
解決辦法也很簡單,就是把對應(yīng)的宏,該成足夠大,比如:
#define MTD_NAND_MAX_PAGESIZE 8192
#define MTD_NAND_MAX_OOBSIZE
這樣,以后即使是8K的nand,也可以很好的支持了。
評論