WinCE下在系统进行内核更新问题
最近在研究WINCE系统下进行内核nb0文件的更新,采用的方式是这样的:
将新的NK.nb0文件通过activesync拷贝到系统的FLASH的某个目录下,应用程序打开该文件成功后,会对系统内核所在的FLASH区域进行格式化,然后将NK.nb0文件读出并进行相应区域的数据写入。
我的区域存放于FLASH的Block6-389区域,因为我之前使用JTAG进行烧写也是将对应的NK.nb,文件烧写到同样的区域实现,但是使用应用程序进行写入就不正常。
使用JTAG读出数据,发现前面几个block的数据不正常,很多被写成了00,后面区块的数据是正常的。
应用程序调用的方式是 使用CreatFile打开FLASH驱动,试用ReadFile将数据分块读出,再使用FLASH驱动的DeviceIoControl发送对应的参数给底层驱动进行写入,驱动中对FLASH的驱动 FMD.c中的FMD_OEMIoControl进行了修改,增加了写入FMD_WriteSector和擦除FMD_EraseBlock的指令,擦除是正常的,对应的区域被擦成了全FF。写入则是部分正确。
另外我尝试在程序中使用CreatFile创建一个读一个写句柄,将NK.nb0使用ReadFile读出,用WriteFile写入NK2.NB0,发现NK2.nb0是正确的,那这应该读数据是没有问题的,为啥写入FLASH就不正常呢?
如果写保护,应该不能擦除的才对的,我看了下代码,也没有对这些区域进行保护。
[解决办法]
我没这样写过,应该考虑写的驱动是否有问题。
[解决办法]
我之前發表過了
目的:
S5PV210 BSP WinCE6.0
讓WinCE6.0開機進入shell後還能燒錄NK的方法
通常開發板都是透過工具然後在eboot階段燒錄NK
但是這對一各產品而言不實用
我們的產品配備有一各PC開發工具,會有一各更新OS的功能
所以需要在WinCE6.0開機進入shell後還能燒錄NK的方法
我敎大家怎嚜實現
過程:
一般而言都只有在eboot才能夠燒錄NK Image
利用什麼Dragin V1.26.2.exe還是DNW.exe來弄
要在WinCE6.0開機進入shell後還能燒錄NK
首先記得空板子第一次燒錄OS的時候
記得你在切割NandFlash區塊的時候,建議切割固定的OS區塊,固定的User區塊
當然這需要改程式c:\WINCE600\PLATFORM\SMDKV210\SRC\BOOTLOADER\EBOOT\nand.cpp
WriteFlashNK函式裡面BP_OpenPartition配固定大小就可以解決
然後記得OS區塊之前的部份block要打上FMD_SetBlockStatus的BLOCK_STATUS_RESERVED狀態
然後寫Code支援fmd ioctl可以跳過微軟filesystem直接存取NandFlash block
#define IOCTL_XXX_READBLOCK IOCTL_DISK_USER(13)
#define IOCTL_XXX_WRITEBLOCK IOCTL_DISK_USER(14)
#define IOCTL_XXX_ERASEBLOCK IOCTL_DISK_USER(15)
#define IOCTL_XXX_GETBLOCKSTATUS IOCTL_DISK_USER(16)
c:\WINCE600\PLATFORM\SMDKV210\SRC\COMMON\NANDFLASH\FMD\fmd.cpp
FMD_OEMIoControl函式增加上面功能
利用函式FMD_GetBlockStatus,FMD_ReadSector,FMD_WriteSector,FMD_EraseBlock
這些函式來組合這些功能
程式應該會寫吧
再來是燒錄NK最好按照bootpart.cpp步驟
是否為bad block,是就跳過到下一各block
IS_BLOCK_UNUSABLE(dwBlock)
讀block資料,目的是為了sectorinfotable
這各內容在partition建立時,有特殊的值,也就是logic sector number會被寫入
ReadBlock(dwBlock, NULL, g_pSectorInfoBuf)
抹除block
FMD_EraseBlock(dwBlock)
燒錄block
WriteBlock(dwBlock, pbBuffer, g_pSectorInfoBuf)
再來看看nk.bin內容 , 因為nk.bin內容是Record壓縮格式
直接燒錄到NandFlash是不能使用的
可以打開VS2005->PB6.0環境的DOS CMD下輸入
Viewbin –toc nk.bin > output.txt
Viewbin –r nk.bin > output1.txt
可以看到些重要的資料,需要去填寫到eboot控管的TOC Block內容
這樣Lanuch NK的時候才會正確
Image Start = 0x80020000, length = 0x028839E8
Start address = 0x80027E9C
Checking record #166 for potential TOC (ROMOFFSET = 0xFE975FC8)
Checking record #256 for potential TOC (ROMOFFSET = 0xFF469FC8)
Checking record #259 for potential TOC (ROMOFFSET = 0xFF47C020)
Checking record #313 for potential TOC (ROMOFFSET = 0x00000000)
Found pTOC = 0x8289efe0
ROMOFFSET = 0x00000000
ROMHDR ----------------------------------------
DLL First : 0x4001C001
DLL Last : 0x41DCC119
Physical First : 0x80020000
Physical Last : 0x828A39E8
RAM Start : 0x828B0000
RAM Free : 0x828BF000
RAM End : 0x86B00000
Kernel flags : 0x00000000
Prof Symbol Offset : 0x00000000
Num Copy Entries : 2
Copy Entries Offset : 0x80891FD0
Num Modules : 356
Num Files : 267
MiscFlags : 0x00000002
CPU : 0x01c2 (Thumb)
Extensions : 0x80021180
Record [ 0] : Start = 0x80020000, Length = 0x00000004, Chksum = 0x000001AE
Record [ 1] : Start = 0x80020040, Length = 0x00000008, Chksum = 0x000003EA
Record [ 2] : Start = 0x80020048, Length = 0x00000004, Chksum = 0x00000258
Record [ 3] : Start = 0x80021000, Length = 0x00012FF8, Chksum = 0x005F6BBD
Record [ 4] : Start = 0x80035000, Length = 0x0003A208, Chksum = 0x017BC52C
Record [ 5] : Start = 0x80070000, Length = 0x0000A078, Chksum = 0x003EE570
Record [ 6] : Start = 0x8007B000, Length = 0x00083FFC, Chksum = 0x0352F22B
Record [ 7] : Start = 0x800FEFFC, Length = 0x000180C0, Chksum = 0x00686E92
所以了解了吧 , 要把相對應的Record解開到相對應的位址去
很慶幸的 原始檔叫做NK.nb0 在你的專案產出目錄下面就可以找到
所以只要把NK.nb0燒到NandFlash就是正確的啦 ,
不過通常NK.nb0後面都是00是不需要的
可以參考實際viewbin看到的length做裁切,把後面多出的0x00資料部份去掉
還有在NandFlash上的OS區塊是會先看到MBR
所以會是MBR(2K) + NK.nb0 這樣才會正確喔
MBR的說明如下
MBR and partition table
Windows CE 有在看 parition table,partition table 的
system 依照 partition table 的內容,filesystem type,load 對應的 driver 進來。
msdn 說 partition table 是 mbr 的一部分,描述 disk 的 partition layout。最多可以包含 4 個 partition。
mbr 會有一個 end mark : 0x55AA。
在這個 end mark 的前面,擺 partition table [4]。
一般的mbr 是 512 bytes,所以parition table 的 offset 就是:
512 - 2 - (16x4) =
partition table 的entry (一個parititon) 的structure 定義在
c:\WINCE600\PUBLIC\COMMON\OAK\INC\bootpart.h
typedef struct _PARTENTRY {
BYTE Part_BootInd; // If 80h means this is boot partition
BYTE Part_FirstHead; // Partition starting head based 0
BYTE Part_FirstSector; // Partition starting sector based 1
BYTE Part_FirstTrack; // Partition starting track based 0
BYTE Part_FileSystem; // Partition type signature field
BYTE Part_LastHead; // Partition ending head based 0
BYTE Part_LastSector; // Partition ending sector based 1
BYTE Part_LastTrack; // Partition ending track based 0
DWORD Part_StartSector; // Logical starting sector based 0
DWORD Part_TotalSectors; // Total logical sectors in partition
} PARTENTRY;
size是16 bytes.
Part_BootInd 的value 也定義在 bootpart.h;
// Flags for Part_BootInd
#define PART_IND_ACTIVE 0x1
#define PART_IND_READ_ONLY 0x2
#define PART_IND_HIDDEN 0x4
其中Filesystem 定義在
c:\WINCE600\PUBLIC\COMMON\OAK\INC\bootpart.h
#define PART_UNKNOWN 0
#define PART_DOS2_FAT 0x01 // legit DOS partition
#define PART_DOS3_FAT 0x04 // legit DOS partition
#define PART_EXTENDED 0x05 // legit DOS partition
#define PART_DOS4_FAT 0x06 // legit DOS partition
#define PART_DOS32 0x0B // legit DOS partition (FAT32)
#define PART_DOS32X13 0x0C // Same as 0x0B only "use LBA"
#define PART_DOSX13 0x0E // Same as 0x06 only "use LBA"
#define PART_DOSX13X 0x0F // Same as 0x05 only "use LBA"
// CE only partition types for Part_FileSystem
#define PART_CE_HIDDEN 0x18
#define PART_BOOTSECTION 0x20
#define PART_BINFS 0x21 // BINFS file system
#define PART_XIP 0x22 // XIP ROM Image
#define PART_ROMIMAGE 0x22 // XIP ROM Image (same as PART_XIP)
#define PART_RAMIMAGE 0x23 // XIP RAM Image
#define PART_IMGFS 0x25 // IMGFS file system
#define PART_BINARY 0x26 // Raw Binary Data
關於head , sector , track可以參考bootpart.cpp
函式LBAtoCHS & AddPartitionTableEntry
再來看一下eboot TOC內容需要什麼
只需要去回填ID[3]的NK Launch內容
TOC {
dwSignature: 0x434F544E
BootCfg{…}
ID[0] {…}
ID[1] {…}
ID[2] {…}
ID[3]
{
dwVersion: 0x1
dwSignature: 0x48534643
String: NK
dwImageType: 0x8
dwTtlSectors: 0x5108
dwLoadAddress: 0x80020000
dwJumpAddress: 0x80027E9C
dwStoreOffset: 0x0
}
ID[4] {…}
還記得剛剛的
Viewbin –toc nk.bin > output.txt
Viewbin –r nk.bin > output1.txt
Image Start = 0x80020000, length = 0x028839E8
Start address = 0x80027E9C
ROMOFFSET = 0x00000000
dwTtlSectors: 0x5108
dwLoadAddress: 0x80020000
dwJumpAddress: 0x80027E9C
dwStoreOffset: 0x0
會填了吧 除了dwTtlSectors , 然後sector size為2048
算法是dwTtlSectors = (length / sectorsize) + (length % sectorsize)
dwTtlSectors = (0x028839E8 / 2048) + (0x028839E8 % 2048)
= 0x5107 + 0x1 = 0x5108
這樣會了吧 , 就是這麼簡單 , 就可以在WinCE開機下燒錄 NK Image了
燒錄完要重開機才會有效喔 , 重新由NandFlash load NK到DRAM執行
如果你是使用Soft Reset在S5PV210 BSP Stepldr還要修改
c:\WINCE600\PLATFORM\SMDKV210\SRC\BOOTLOADER\STEPLDR\startup.s
裡面去掉這段
; ldr r0, =RST_STAT
; ldr r1, [r0]
; and r1, r1, #BP_SWRESET
; cmp r1, #BP_SWRESET
; bne Normal_Boot_Sequence ; Normal Booting (Not SW Reset)
; JUMP_TO_KERNEL ; SW Reset jump to Kernel
; b .
stepldr才會乖乖的把NandFlash OS區塊重新load到DRAM執行喔
恩沒了就這樣