Chinaunix首页 | 论坛 | 博客
  • 博客访问: 245785
  • 博文数量: 35
  • 博客积分: 1415
  • 博客等级: 上尉
  • 技术积分: 334
  • 用 户 组: 普通用户
  • 注册时间: 2009-11-10 21:31
文章分类

全部博文(35)

文章存档

2010年(22)

2009年(13)

我的朋友

分类: 嵌入式

2009-11-25 16:32:14

一、wince 启动过程分析
    我用的是utu2440的开发板,板子自带的启动文件包括NBOOT1、NBOOT2、EBOOT、wince内核,各个文件作用是:

NBOOT1:S3C2440对于NAND FLash,最大加载4K的代码运行,可以直接运行这个程序,NBOOT1启动后会从FLASH中加载NBOOT2

NBOOT2:主要实现从FLASH中读取wince内核、加载eboot、显示启动画面

EBOOT:实现对FLASH进行分区、格式化和烧写WINCE内核镜像文件,这里要注意的是EBOOT在烧写wince内核镜像的过程中会把NK.bin解压为NB.nb0再写入到flash中。

二、分析UBOOT启动wince的可能性
    对于NBOOT1、NBOOT2的功能完全可以用UBOOT代替,本身UBOOT已经实现NAND falsh 启动,再就是wince内核文件 NK.nb0 可以直接加载到内存的 0x30200000,然后使用 uboot的 go 指令直接运行wince内核文件。

    比较难办的就是eboot功能的uboot实现,eboot的分区功能在flash中创建了一个binfs的分区用于存放wince内核镜像文件,在wince中可以直接支持binfs分区,可以看到镜像文件。如果要在uboot中实现这个功能,则必须为uboot添加对flash分区的功能,为了测试实现的可能性花了两天做了不少实现,发现要想做好这个功能实在是太花时间、精力了,只好作罢(如果哪位兄弟能提供帮助就太好了)。

    在去掉binfs支持后,uboot可以实现将NK.nb0烧写到flash中,然后启动时读取到0x30200000位置,最后用go命令加载启动wince,这么来看应该是很简单的事了(后来证明此时的想法太。。。。。。)

三、测试可能性

    使用uboot将nk.nb0加载到0x3020000中,然后go 0x30200000,等了一会果真看到了wince的界面,这一步成功了,下一步就可以直接烧写了。但是很快发现,使用这种方法启动一次wince后就无法再启动uboot,通过读取flash的内容发现,wince把uboot的flash块给格式化了。是什么原因呢?

    原来是因为这个wince内核有自动分区格式化功能,上面已经说了uboot中不实现分区格式化的功能,所以在wince中就必须添加这个功能。但是这样一来wince就会格式化uboot,通过阅读eboot发现,eboot在格式化的时候会把eboot区标记为坏块,这样wince就不会进行格式化了,看来必须首先解决这个问题。

四、FLASH 管理区域划分

    我的FLASH大小是64M,wince 内核文件加上uboot不超过32M,这样就定义FLASH的前32M由uboot进行管理,这32M对wince来说是不存在的,后32M归于wince进行存储,在wince中进行管理。

    如果要阻止wicne格式化前32M,可以再uboot中对前32M全部标记为坏块,但是这样一来uboot本身对flash所有操作也会首先做坏块检测。如果这么做的话,每次uboot对flash读写时取消坏块标记,操作完成后在标记为坏块。思路应该是可行的,但是感觉这么做太麻烦了。当然条条大路通罗马,我们可以逆向思维一下,为何不能修改wince内核来屏蔽前32M flash空间呢?

    通过阅读wince的bsp,发现有个很重要的宏定义

loader.h中

// NAND Boot (loads into SteppingStone) @ Block 0

#define NBOOT_BLOCK 0
#define NBOOT_BLOCK_SIZE 1
#define NBOOT_SECTOR BLOCK_TO_SECTOR(NBOOT_BLOCK)

// TOC @ Block 1

#define TOC_BLOCK 1
#define TOC_BLOCK_SIZE 1
#define TOC_SECTOR BLOCK_TO_SECTOR(TOC_BLOCK)

// Eboot @ Block 2

#define EBOOT_BLOCK 2
#define EBOOT_SECTOR_SIZE FILE_TO_SECTOR_SIZE(EBOOT_RAM_IMAGE_SIZE)
#define EBOOT_BLOCK_SIZE SECTOR_TO_BLOCK(EBOOT_SECTOR_SIZE)
#define EBOOT_SECTOR BLOCK_TO_SECTOR(EBOOT_BLOCK)

//#define RESERVED_BOOT_BLOCKS (NBOOT_BLOCK_SIZE + TOC_BLOCK_SIZE + EBOOT_BLOCK_SIZE)/*这个参数是定义预览 block 的数量,默认是NBOOT + TOC + EBOOT,我为了屏蔽前面32M空间,需要修改此定义*/

#define RESERVED_BOOT_BLOCKS SECTOR_TO_BLOCK(FILE_TO_SECTOR_SIZE(0x2000000))

// Images start after OEM Reserved Blocks

#define IMAGE_START_BLOCK RESERVED_BOOT_BLOCKS
#define IMAGE_START_SECTOR BLOCK_TO_SECTOR(IMAGE_START_BLOCK)

    修改RESERVED_BOOT_BLOCKS 后重新编译wince(由于我用的是win7,不支持wince5的编译,只好用虚拟机来编译,速度真是太折磨人了),希望能够一次成功,重烧uboot,下载wince内核文件NK.nb0,启动wince,失望,还是失望,uboot依旧被擦除了。

    为了搞清楚问题的原因,打开wince的调试信息(http://blog.chinaunix.net/u3/105764/showart_2101341.html),特别是NAND FLash驱动的所有调试信息。重新编译、下载运行。发现wince开始擦除的位置是正确的,在擦除未完时此时我复位了开发板,uboot可以正常启动。重来,等擦除操作完成了以后我再复位,发现uboot不能启动了,这可真是奇怪了,开始擦除的位置是正确的,每次block会递增,怎么会擦除前面的 block 呢?再来一遍,发现问题了,wince的整个擦除起始位置是正确的,但是结束 block 是错误的,我的FLASH整个 block 是4096个,wince从正确的起始位置开始,擦除了 4096 个块,估计就是这个原因导致把 uboot 给擦除了。

    阅读了一下wince的fmd驱动,这里初始化flash,发现有一句很不可理解

// pFlashInfo->dwNumBlocks            = NUM_BLOCKS ;/*这是原来的定义,修改为下面的值*/

    pFlashInfo->dwNumBlocks            = NUM_BLOCKS - IMAGE_START_BLOCK ;

 

    按照道理来讲,初始化flash block数量时至少应该屏蔽nbot eboot两部分,但是这个bsp中未屏蔽,在网上查询了一下,的确有的bsp是定义为
NUM_BLOCKS - IMAGE_START_BLOCK,我觉得这样定义更合理。也许是bsp从三星出来到我手上中间经过不少人修改,留下了这个bug吧。

    重新编译,加载,一切正常,wince可正常启动。

    最后把wince内核文件烧写到flash中,uboot启动时自动加载,一切正常。

    经过这样修改以后,wince启动时如果没有检测到有效的mbr,则会自动分区格式化,第二次再启动时就不会再格式化了,剩余的32M空间可以存储用户文件。在wince的存储管理中可以看到flash大小为32M,的确已经成功屏蔽了前面的32M空间。

至此,该工作告一段落,uboot可以正常烧写、加载wince了。

 

原创文章,转载请注明:转载自 风雨无阻博客(http://Apollo5520.cublog.cn

本文链接地址:http://blog.chinaunix.net/u3/105764/showart_2103793.html

 


阅读(4087) | 评论(2) | 转发(0) |
给主人留下些什么吧!~~

chinaunix网友2010-07-28 11:21:22

社会就需要你这样的人

chinaunix网友2010-04-18 12:35:27

赞一个!