|
uclinux-2.4.24-uc0支持44B0X开发板----MTD设备的支持
Flash 芯片访问导致中断处理异常。
我使用的是39VF160 Flash芯片,规划是第一块64K保存Bootloader,下面13 * 64K放Kernel,再下面17 * 64K放rootfs(cramfs),最后一块
放nvram。所以我添加了一个MTD MAP文件,drivers/mtd/maps/sample44b0x.c,分区如下:
static struct mtd_partition sample44b0x_partitions[] = {
{
name: "sample bootloader",
offset: 0x00000000,
size: 0x00010000,
},
{
name: "sample kenrel",
offset: 0x00010000,
size: 0x000d0000,
},
{
name: "sample rootfs",
offset: 0x000e0000,
size: 0x00110000,
},
{
name: "sample nvram",
offset: 0x001f0000,
size: 0x00010000,
},
};
而所遇到的问题是:在Init函数中调用do_map_probe("jedec_probe", &yatech44b0x_map)时,系统当机。原因在与:
Flash 0 地址存放着异常向量表,此时中断已经开启,而jedec_probe需要读取Flash的Manufactory ID & Device ID
读取的过程如下:
enter_sw_id_query_mode();
ManuID = *((u16 *)0);
DevID = *((u16 *)2);
exit_sw_id_query_mode();
也就是说,当39VF160处于ID QUERY MODE时,数据也特殊,这时如果不关中断,就会飞掉。
所以,修改drivers/mtd/chips/jedec_probe.c文件,修改函数jedec_probe_chip():
......
/* Reset */
jedec_reset(base, map, cfi); // 退出sw_id_query_mode
#ifdef CONFIG_BOARD_SAMPLE44B0X
/* John Added, 'cause our interrupt vectors are installed at address 0
* By entering SW PID query mode, interrupts must be disabled.
*/
cli(); // 关中断
#endif
/* Autoselect Mode */ // 进入sw_id_query_mode
if(cfi->addr_unlock1) {
cfi_send_gen_cmd(0xaa, cfi->addr_unlock1, base, map, cfi, CFI_DEVICETYPE_X8, NULL);
cfi_send_gen_cmd(0x55, cfi->addr_unlock2, base, map, cfi, CFI_DEVICETYPE_X8, NULL);
}
cfi_send_gen_cmd(0x90, cfi->addr_unlock1, base, map, cfi, CFI_DEVICETYPE_X8, NULL);
......
jedec_reset(base, map, cfi); // 退出sw_id_query_mode
......
修改jedec_reset()函数:
static inline void jedec_reset(u32 base, struct map_info *map,
struct cfi_private *cfi)
{
/* Reset */
cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL);
/* Some misdesigned intel chips do not respond for 0xF0 for a reset,
* so ensure we're in read mode. Send both the Intel and the AMD command
* for this. Intel uses 0xff for this, AMD uses 0xff for NOP, so
* this should be safe.
*/
cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL);
#ifdef CONFIG_BOARD_SAMPLE44B0X
/* John Added, 'cause our interrupt vectors are installed at address 0
* By entering SW PID query mode, interrupts must be disabled.
* When return, we re-enable the interrupts.
*/
sti(); // 开中断
#endif
}
这样就解决了这个问题。 |
|