Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1205931
  • 博文数量: 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完全支持了。如下:

 

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

chinaunix网友2010-04-03 15:56:51

高手,我用的也是mini2440的板子子,照着你的方法做,执行saveenv的时候。最后停在了writing to flash...上了。没有done。程序就挂在那边了,请问这是怎么回事呢? Out: serial Err: serial 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 ... ok. Erasing sector 70 ... ok. Erasing sector 71 ... ok. Erasing sector 72 ... ok. Erasing sector

lanlovehua2010-04-02 08:39:04

最近我也在做这个。看看啊。

chinaunix网友2010-03-15 17:46:04

看了你的文章,做完了移植一,当做移植二的时候按照你的设置结合我具体的板子,我也全部改写完后,编译通不过,显示 uboot-1.1.6/include/environment.h:103:error: 'CFG_ENV_SIZE' undeclared here (not in a function),能告诉我为什么吗?

chinaunix网友2010-02-27 11:58:43

你好,我按照你的步骤做到移植二完后,加载到RAM后,打印下面的信息 U-Boot 2009.08 (Feb 27 2010 - 11:33:43) DRAM: 64 MB Flash: 2 MB *** Warning - bad CRC, using default environment In: serial Out: serial Err: serial 然后我用saveenv设置环境变量后打印下面信息,就又回到提示符下面,请问是哪里出了问题,我是新手,请多多指点 Saving Environment to Flash... Un-Protected 16 sectors Erasing Flash...Erased 16 sectors

chinaunix网友2010-02-09 15:38:23

你好, 很感谢你能共享你的Linux经验,我受益匪浅。但是有个问题,想请教一下,我按照你的说明一步步走下来。可以修改通过设置IO口的高低电平,可以控制led灯的亮灭,但是到下一步串口输出,我用串口调试助手,波特率115200.不能像你说明的那样,串口没反应啊,没有任何输出信息。 我用的开发板是优龙的2440开发板,把文件烧到nandflash中启动,我一直设置从nandflash启动。 请楼主协助解决,谢谢。