WinCE下在系统进行内核更新问题

时间:2022-03-21 07:51:09
最近在研究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就不正常呢?
如果写保护,应该不能擦除的才对的,我看了下代码,也没有对这些区域进行保护。

4 个解决方案

#1


WinCE下在系统进行内核更新问题无人理会……没有大侠给个建议吗?

#2


我没这样写过,应该考虑写的驱动是否有问题。

#3


我之前發表過了
目的:
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執行喔

恩沒了就這樣

#4


引用 3 楼 glchild514 的回复:
我之前發表過了
目的:
S5PV210 BSP WinCE6.0
讓WinCE6.0開機進入shell後還能燒錄NK的方法
通常開發板都是透過工具然後在eboot階段燒錄NK
但是這對一各產品而言不實用
我們的產品配備有一各PC開發工具,會有一各更新OS的功能
所以需要在WinCE6.0開機進入shell後還能燒錄NK的方法
我敎大家怎嚜實現

過程:
一般而言都只有在ebo……


使用JTAG将FLASH数据读出后,我发现是在执行FMD_WriteSector时,没有传递SPARE区数据,记过将FLASH的SPARE数据擦除了,导致写入后加载失败……
不过很感谢,我对FLASH不太熟悉,看了这个又加深了了解,为下一步做分区准备 WinCE下在系统进行内核更新问题

#1


WinCE下在系统进行内核更新问题无人理会……没有大侠给个建议吗?

#2


我没这样写过,应该考虑写的驱动是否有问题。

#3


我之前發表過了
目的:
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執行喔

恩沒了就這樣

#4


引用 3 楼 glchild514 的回复:
我之前發表過了
目的:
S5PV210 BSP WinCE6.0
讓WinCE6.0開機進入shell後還能燒錄NK的方法
通常開發板都是透過工具然後在eboot階段燒錄NK
但是這對一各產品而言不實用
我們的產品配備有一各PC開發工具,會有一各更新OS的功能
所以需要在WinCE6.0開機進入shell後還能燒錄NK的方法
我敎大家怎嚜實現

過程:
一般而言都只有在ebo……


使用JTAG将FLASH数据读出后,我发现是在执行FMD_WriteSector时,没有传递SPARE区数据,记过将FLASH的SPARE数据擦除了,导致写入后加载失败……
不过很感谢,我对FLASH不太熟悉,看了这个又加深了了解,为下一步做分区准备 WinCE下在系统进行内核更新问题