问题: kernel 启动后,运行到下面行挂起。
[42949373.810000] nx_2016: Found 1 x16 devices at 0x0 in 16-bit bank
[42949373.820000] Intel/Sharp Extended Query Table at 0x0035
[42949373.820000] Using buffer write method
[42949373.830000] cfi_cmdset_0001: Erase suspend on write enabled
[42949373.830000] Creating 0 MTD partitions on "nx_2016":
[42949373.840000] NAND device: Manufacturer ID: 0x20, Chip ID: 0x76 (ST Micro NAND 64MiB 3,3V 8-bit)
挂起的函数调用层次关系:
-------------------------------------------------------------------------------------------------------------------------------------------
module_init(nx_nand_init)
nx_nand_init(){
nx_nand_driver.probe = nx_nand_probe;
platform_driver_register(nx_nand_driver)
}
=>
nx_nand_probe()
=>
nand_scan_tail()
=>
nand_default_bbt() //Select a default bad block table for the device
=>
nand_scan_bbt() //scan, find, read and maybe create bad block table(s)
=>
search_read_bbts() //scan the device for bad block table(s)
=>
search_bbt() //scan the device for a specific bad block table
=>
scan_read_raw() //Scan read raw data from flash
=>
nand_read_oob() //NAND read data and/or out-of-band
=>
nand_do_read_ops() //Read data with ECC
=>
nx_nand_command(NAND_CMD_READ0) //Command function for small page chips
=>
tmhwEfmc_SetDmaConfig() //This function will setup the DMA configuration for the data transfer to/from NAND flash devices connected the EFMC.
=>
TMVH_GEN_WRITE( regs, regVal );
-------------------------------------------------------------------------------------------------------------------------------------------
最后TMVH_GEN_WRITE()挂起,问题应该是和Nand有关,据说是Nand坏?
检查u-boot里面的环境变量altflash为NAND,由运行过的命令"gcs sel NAND"产生,如果altflash设置为空,启动没有问题。
A. gcs学习
我们在u-boot下面运行#gcs info
*******************************
GCS Flash Info--
BOOT Device:--NOR Flash.
ALT Flash Device:--NAND Flash.
*******************************
其中,Boot Device通过RGU_CNFG_TRAPS_REG获取。
注:RGU_CNFG_TRAPS_REG
见<<ApolloUG>>,Reset Generation Unit(RGU)中的Chip Configuration Register。该寄存器在复位并稳定的过程中采样得到。
而ALT Flash Device,u-boot在初始化时读取$altflash获得,并且可以通过#gcs sel命令进行修改。
B. altflash设置为空,如何影响kernel启动?
nx_nand_probe()
=>
nand_scan_ident()
=>
nand_get_flash_type()
读取到的device id为0x50,匹配不到对应的device type,所以也不去scan bbt。
而,altflash为NAND时,
读取到的device_id为0x76,匹配到的device type为“NAND 64MiB 3,3V 8-bit”。
读取device_id的函数是,nx_nand_read_byte(),是通过Efmc完成,完全硬件实现。
为何有这种区别呢?
因为altflash设为NAND时,u-boot对该设备进行过初始化和命令的传递。而altflash为空时,u-boot没有对该设备进行访问。结果两种情况下得到的device_id不一致,且皆不正确---因为kernel对该设备的驱动有问题(?)。
C. 问题的解决
分析是驱动的问题,需要加载正确的驱动。
幸好上海同事已经有解决,拖过来分析如下:
arch/arm/mach-apollo/nand.c
arch_initcall(apollo_nand_init);
static int __init apollo_nand_init(void)
{
#if 1
/**
* FIXME: This configuration must come from bootloader
**/
void * __iomem base = ioremap(apollo_ip2017_resources[0].start,
APOLLO_IP2017_LEN);
if (base == NULL) {
printk(KERN_ERR "NAND_DEVICE: out of memory?!\n");
return -ENOMEM;
}
#if 0
writel(0x014, base + 0x04C);
#ifdef CONFIG_EXECUTE_ON_EMULATOR
writel(0x02644448, base + 0x050); /* Set timings */
writel(0x00108444, base + 0x054);
#endif
#ifdef CONFIG_PCI
writel(0x3FE, base + 0x010);
#else
writel(0x3F, base + 0x010);
#endif
#endif
iounmap(base);
#endif /* FIXME: Remove it once the bootloader is updated */
return platform_device_register (&apollo_ip2017_device);
}
解决的关键是#if 0里面的处理。............. 缺少IP2017资料,将来有机会再理解吧。。。
D. mtdparts, bootargs, nandboot
gcs sel NAND
setenv bootcmd "dhcp; run nandboot;"
setenv uboot_cmdline 1
setenv mtdids "nand0=nx_2017,nor0=nx_2016"
setenv mtdparts "mtdparts=nx_2016:1536k(boot),-(extra);nx_2017:1536k(unused),5m(kernel),32m(root),32m(appfs),-(nandextra)"
save
setenv bootargs "noinitrd console=ttyS1,115200n8 $mtdparts root=/dev/mtdblock6 rw rootfstype=jffs2 ${extra}"
save
E. attach相关的uldr&u-boot
附上uldr和u-boot相关的改动。
EagleKingdom nand flash issue and boot setting
原创jiangjqian ©著作权
©著作权归作者所有:来自51CTO博客作者jiangjqian的原创作品,请联系作者获取转载授权,否则将追究法律责任
上一篇:内核调试
提问和评论都可以,用心的回复会被更多人看到
评论
发布评论
相关文章
-
NAND FLASH 理解数据 数据存储 寄存器 地址寄存器 i++
-
android flash分区(nand flash)
android nand flash 分区及对应功能介绍
flash android shell 电话 2010