Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1205923
  • 博文数量: 50
  • 博客积分: 6069
  • 博客等级: 准将
  • 技术积分: 5092
  • 用 户 组: 普通用户
  • 注册时间: 2009-07-23 10:09
文章存档

2011年(4)

2010年(15)

2009年(31)

分类: 嵌入式

2009-12-11 09:52:26

嵌入式Linux之我行,主要讲述和总结了本人在学习嵌入式linux中的每个步骤。一为总结经验,二希望能给想入门嵌入式Linux的朋友提供方便。如有错误之处,谢请指正。

一、移植环境

  • 主  机:VMWare--Fedora 9
  • 开发板:Mini2440--64MB Nand,
  • 编译器:
  • u-boot:

二、移植步骤

上接u-boot-2009.08在2440上的移植详解(一)

4)准备进入u-boot的第二阶段(在u-boot中添加对我们开发板上Nor Flash的支持)
通常,在嵌入式bootloader中,有两种方式来引导启动内核:从Nor Flash启动和从Nand Flash启动。u-boot中默认是从Nor Flash启动,再从上一节这个运行结果图中看,还发现几个问题:第一,我开发板的Nor Flash是2M的,而这里显示的是512kB;第二,出现Warning - bad CRC, using default environment的警告信息。不是u-boot默认是从Nor Flash启动的吗?为什么会有这些错误信息呢?这是因为我们还没有添加对我们自己的Nor Flash的支持,u-boot默认的是其他型号的Nor Flash,而我们的Nor Flash的型号是SST39VF1601。另外怎样将命令行提示符前面的SMDK2410变成我自己定义的呢?

下面我们一一来解决这些问题,让u-boot完全对我们Nor Flash的支持。首先我们修改头文件代码如下:

#gedit include/configs/my2440.h //修改命令行前的名字和Nor Flash参数部分的定义

#define CONFIG_SYS_PROMPT   "[MY2440]#"  //将命令行前的名字改成[MY2440]

 

/*-----------------------------------------------------------------------
 * FLASH and environment organization
 */

#if 0    
//注释掉下面两个类型的Nor Flash设置,因为不是我们所使用的型号
#define CONFIG_AMD_LV400     1 /* uncomment this if you have a LV400 flash */
#define CONFIG_AMD_LV800     1 /* uncomment this if you have a LV800 flash */
#endif

#define CONFIG_SYS_MAX_FLASH_BANKS 1  /* max number of memory banks */

#ifdef CONFIG_AMD_LV800
#define PHYS_FLASH_SIZE            0x00100000  /* 1MB */
#define CONFIG_SYS_MAX_FLASH_SECT  (19)        /* max number of sectors on one chip */
#define CONFIG_ENV_ADDR            (CONFIG_SYS_FLASH_BASE + 0x0F0000) /* addr of environment */
#endif
#ifdef CONFIG_AMD_LV400
#define PHYS_FLASH_SIZE            0x00080000  /* 512KB */
#define CONFIG_SYS_MAX_FLASH_SECT  (11)        /* max number of sectors on one chip */
#define CONFIG_ENV_ADDR            (CONFIG_SYS_FLASH_BASE + 0x070000) /* addr of environment */
#endif
#define CONFIG_SST_39VF1601        1        
//添加mini2440开发板Nor Flash设置
#define PHYS_FLASH_SIZE            0x200000 //我们开发板的Nor Flash是2M
#define CONFIG_SYS_MAX_FLASH_SECT  (512)    //根据SST39VF1601的芯片手册描述,对其进行操作有两种方式:块方式和扇区方式。现采用扇区方式(sector),1 sector = 2Kword = 4Kbyte,所以2M的Nor Flash共有512个sector
#define CONFIG_ENV_ADDR            (CONFIG_SYS_FLASH_BASE + 0x040000) //暂设置环境变量的首地址为0x040000(即:256Kb)

然后添加对我们mini2440开发板上2M的Nor Flash(型号为SST39VF1601)的支持。在u-boot中对Nor Flash的操作分别有初始化、擦除和写入,所以我们主要修改与硬件密切相关的三个函数flash_init、flash_erase、write_hword,修改代码如下:

#gedit board/samsung/my2440/flash.c

//修改定义部分如下:

//#define MAIN_SECT_SIZE   0x10000
#define MAIN_SECT_SIZE     0x1000
  //定义为4k,刚好是一个扇区的大小

//#define MEM_FLASH_ADDR1  (*(volatile u16 *)(CONFIG_SYS_FLASH_BASE + (0x00000555 << 1)))
//#define MEM_FLASH_ADDR2  (*(volatile u16 *)(CONFIG_SYS_FLASH_BASE + (0x000002AA << 1)))
#define MEM_FLASH_ADDR1    (*(volatile u16 *)(CONFIG_SYS_FLASH_BASE + (0x00005555 << 1)) //这两个参数看SST39VF1601手册      

#define MEM_FLASH_ADDR2    (*(volatile u16 *)(CONFIG_SYS_FLASH_BASE + (0x00002AAA << 1)))

 

//修改flash_init函数如下:
#elif defined(CONFIG_AMD_LV800)
            (AMD_MANUFACT & FLASH_VENDMASK) |
            (AMD_ID_LV800B & FLASH_TYPEMASK);
#elif defined(CONFIG_SST_39VF1601)   //在CONFIG_AMD_LV800后面添加CONFIG_SST_39VF1601         

            (SST_MANUFACT & FLASH_VENDMASK) |
            (SST_ID_xF1601 & FLASH_TYPEMASK)
;

for (j = 0; j < flash_info[i].sector_count; j++) {
    
//if (j <= 3) {
    
//    /* 1st one is 16 KB */
    
//    if (j == 0) {
    
//        flash_info[i].start[j] = flashbase + 0;
    
//    }

    
//    /* 2nd and 3rd are both 8 KB */
    
//    if ((j == 1) || (j == 2)) {
    
//        flash_info[i].start[j] = flashbase + 0x4000 + (j - 1) * 0x2000;
    
//    }

    
//    /* 4th 32 KB */
    
//    if (j == 3) {
    
//        flash_info[i].start[j] = flashbase + 0x8000;
    
//    }
    
//} else {
    
//    flash_info[i].start[j] = flashbase + (j - 3) * MAIN_SECT_SIZE;
    
//}

    flash_info[i].start[j] = flashbase + j * MAIN_SECT_SIZE;

}

 

//修改flash_print_info函数如下:   

case (AMD_MANUFACT & FLASH_VENDMASK):
    printf ("AMD: ");
    break;
case (SST_MANUFACT & FLASH_VENDMASK):    
//添加SST39VF1601的
    printf ("SST: ");
    break;

case (AMD_ID_LV800B & FLASH_TYPEMASK):
    printf ("1x Amd29LV800BB (8Mbit)\n");
    break;
case (SST_ID_xF1601 & FLASH_TYPEMASK):   
//添加SST39VF1601的
    printf ("1x SST39VF1610 (16Mbit)\n");
    break;

 

//修改flash_erase函数如下:
//if ((info->flash_id & FLASH_VENDMASK) !=
// (AMD_MANUFACT & FLASH_VENDMASK)) {
//    return ERR_UNKNOWN_FLASH_VENDOR;
//}
if ((info->flash_id & FLASH_VENDMASK) !=

 (SST_MANUFACT & FLASH_VENDMASK)) {
    return ERR_UNKNOWN_FLASH_VENDOR;
}

///* wait until flash is ready */
//chip = 0;
//do {
//    result = *addr;
//    /* check timeout */
//    if (get_timer_masked () >
//     CONFIG_SYS_FLASH_ERASE_TOUT) {
//        MEM_FLASH_ADDR1 = CMD_READ_ARRAY;
//        chip = TMO;
//        break;
//    }

//    if (!chip
//     && (result & 0xFFFF) & BIT_ERASE_DONE)
//        chip = READY;

//    if (!chip
//     && (result & 0xFFFF) & BIT_PROGRAM_ERROR)
//        chip = ERR;
//} while (!chip);

//MEM_FLASH_ADDR1 = CMD_READ_ARRAY;

//if (chip == ERR) {
//    rc = ERR_PROG_ERROR;
//    goto outahere;
//}

//if (chip == TMO) {
//    rc = ERR_TIMOUT;
//    goto outahere;
//}
while (1)

{
    if ((*addr & 0x40) != (*addr & 0x40))
        continue;

    if (*addr & 0x80)
    {
        rc = ERR_OK;
        break;
    }
}

 

//修改write_hword函数如下:
MEM_FLASH_ADDR1 = CMD_UNLOCK1;
MEM_FLASH_ADDR2 = CMD_UNLOCK2;
//MEM_FLASH_ADDR1 = CMD_UNLOCK_BYPASS;
MEM_FLASH_ADDR1 = CMD_PROGRAM;
   
//*addr = CMD_PROGRAM;
*addr = data;

///* wait until flash is ready */
//chip = 0;
//do {
//    result = *addr;
//    /* check timeout */
//    if (get_timer_masked () > CONFIG_SYS_FLASH_ERASE_TOUT) {
//        chip = ERR | TMO;
//        break;
//    }

//    if (!chip && ((result & 0x80) == (data & 0x80)))
//        chip = READY;

//    if (!chip && ((result & 0xFFFF) & BIT_PROGRAM_ERROR)) {
//        result = *addr;

//        if ((result & 0x80) == (data & 0x80))
//            chip = READY;
//        else
//            chip = ERR;
//    }
//} while (!chip);

//*addr = CMD_READ_ARRAY;

//if (chip == ERR || *addr != data)
//    rc = ERR_PROG_ERROR;
while (1)

{
    if ((*addr & 0x40) != (*addr & 0x40)) 
        continue;

    if ((*addr & 0x80) == (data & 0x80))
    {
        rc = ERR_OK;
        break; 
    }
}

修改完后重新编译u-boot,下载到RAM中运行结果如下图:

从运行结果图看,Nor Flash的大小可以正确检测到了,命令行前面的名字也由原来的SMDK2410改成我自己定义的[MY2440]了,但是还会出现bad CRC的警告信息,其实这并不是什么问题,只是还没有将环境变量设置到Nor Flash中,我们执行一下u-boot的:saveenv命令就可以了。如下图:

再重新下载u-boot.bin文件到RAM中运行,可以观察到不会出现警告信息了,这时候u-boot已经对我们开发板上的Nor Flash完全支持了。如下:

 

 
 
阅读(23524) | 评论(24) | 转发(46) |
给主人留下些什么吧!~~

chinaunix网友2010-04-07 23:59:54

看明白了,原来是在datasheet的第三页讲了~~

chinaunix网友2010-04-07 23:49:56

你好,在flash_erase中 while (1) { if ((*addr & 0x40) != (*addr & 0x40)) continue; if (*addr & 0x80) { rc = ERR_OK; break; } } 请问0x40和0x80是用来判断什么的啊?我看SST39VF1601的datasheet也没怎么看明白

lanlovehua2010-04-06 09:43:09

我用的也是mini2440的板子,移植一我顺利地做完了。可是到移植二却出现了一个奇怪的问题: U-Boot 2009.08 (Apr 02 2010 - 17:21:50) DRAM: 64 MB Flash: 0 kB In: serial Out: serial Err: serial my2440 # 这里Flash显示是0KB,可是当我用flinfo查看时又显示了2M,请问是哪里的问题啊,谢谢了。 my2440 # flinfo Bank # 1: SST: 1x SST39VF1610 (16Mbit) Size: 2 MB in 512 Sectors Sector Start Addresses: 00000000 (RO) 00001000 (RO) 00002000 (RO) 00003000 (RO) 00004000 (RO) 00005000 (RO) 00006000 (RO) 00007000 (RO) 00008000 (RO) 00

chinaunix网友2010-04-03 19:23:37

呵呵,找了一个下午终于找到原因了,我把一个==敲成!=了 while (1) { if ((*addr & 0x40) != (*addr & 0x40)) continue; if ((*addr & 0x80) == (data & 0x80)) //汗,把这里的==敲成了!= { rc = ERR_OK; break; } } Net: CS8900-0 mini2440_benson# saveenv Saving Environment to Flash... Un-Protected 16 sectors Erasing Flash...Erasing sector 64 ... ok. Erasing sector 65 ... ok. Erasing sector 66 ... ok. Erasing sector 67 ... ok. Erasing sector 68 ... ok. Erasing sector 69 .

chinaunix网友2010-04-03 15:58:41

高手,我用的也是mini2440的板子子,照着你的方法做,执行saveenv的时候。最后停在了writing to flash...上了。没有done。程序就挂在那边了,请问这是怎么回事呢? 对了,我用的u-boot是2009-11版的