NBOOT - 基于VS2005的编程与编译(一)

    技术2022-05-20  35

    一、写在前面

          WinCE 6.0涉及到2个关键二进制烧录文件:eboot.nb0和nk.bin。其中eboot是CE的bootloader,主要工作是初始化芯片的各寄存器和外设,比如sdram、串口、网络等,然后把nk.bin从flash copy到sdram启动;nk.bin是CE内核映像文件。

          当系统采用NORFlash+S3C2410架构时,上电时,NORFlash被映射到0x0000_0000-0x0800_0000地址,可以直接执行烧录在NORFlash的eboot,启动系统。

          当系统采用NandFlash+S3C2410架构时(NandFlash便宜),由于NandFlash的特殊设计(没有地址线,采用地址、数据、命令复用8根数据线来读写),S3C2410无法把NandFlash映射到某个地址。因而,上电时,S3C2410以硬件的方式将NandFlash前4K的数据copy到internal RAM(叫作steppingstone)执行,然后以软件的方式,在4K数据中编写程序把NandFlash中其他更多的数据copy到外部sdram来执行。

          直接从WinCE6.0 Emulator Clone出来的eboot,其"first 4k”没有包含从NandFlash copy 数据的程序,因此需要手动来添加。一种方式为:修改startup.s文件,编写汇编程序(eboot的main函数入口地址已远远超过4K,无法用C语言来实现);另一种方式为:做个简单程序,大小不超过4K,把eboot从Flash copy到sdram来执行。这个简单的程序被叫做"nboot"。

          因此,nboot的功能仅包括:1,启动CPU(禁watch dog,初始化clock,sdram,NandFlash controller等);2,copy data from Flash to sdram and lauch eboot in sdram。

          下面介绍以VS2005来编写nboot的过程(另注:以ADS来做nboot会简单得多)

     

    二、建立nboot工程

          在S3C2410的BSP中,"/src/bootloader/"新建nboot文件夹,并从eboot目录下copy文件:source,boot.bib,makefiel,makefile.inc,startup.s,main.c文件;

          1、修改source文件,TARGETNAME就是要生成.exe的文件名(nboot.exe);TARGETLIBS只保留fulllibc.lib(除法运算有用到它),其他lib用不到删除;SOURCE先添加startup.s和main.c

    1 TARGETNAME = nboot 2 ...... 3 TARGETLIBS = / 4 $(_COMMONOAKROOT)/lib/$(_CPUINDPATH)/fulllibc.lib 5 ...... 6 SOURCES = / 7 startup.s / 8 main.c /

     

          2、修改boot.bib文件。bib文件的修改在我另一篇文章里有详细介绍。

    代码 1 MEMORY 2 ; Name Start Size Type 3 ; ------- -------- -------- ---- 4 NBOOT 30000000 00004000 RAMIMAGE 5 STACK 30004000 00004000 RESERVED 6 RAM 30008000 00004000 RAM 7 8 9 CONFIG 10 COMPRESSION = OFF 11 PROFILE = OFF 12 KERNELFIXUPS = ON 13 14 SRE = ON 15 ROMSTART = 30001000 16 ROMWIDTH = 32 17 ROMSIZE = 00002000 18 19 MODULES 20 ; Name Path Memory Type 21 ; -------------- ---------------------------------------------- ----------- 22 nk.exe $(_TARGETPLATROOT)/target/$(_TGTCPU)/$(WINCEDEBUG)/nboot.exe NBOOT

     

          3、修改makefile.inc,把eboot改为nboot即可。

    代码 1 ! IF " $(NOLINK) " == "" 2 romimage boot.bib 3 4   ! IF " $(WINCEREL) " == " 1 " 5 copy $(_PLATFORMROOT)/$(_TGTPLAT)/target/$(_TGTCPU)/$(WINCEDEBUG)/nboot.nb0 $(_FLATRELEASEDIR) 6 copy $(_PLATFORMROOT)/$(_TGTPLAT)/target/$(_TGTCPU)/$(WINCEDEBUG)/nboot.bin $(_FLATRELEASEDIR) 7 copy $(_PLATFORMROOT)/$(_TGTPLAT)/target/$(_TGTCPU)/$(WINCEDEBUG)/nboot.sre $(_FLATRELEASEDIR) 8   ! ENDIF 9   ! ENDIF

     

          4、修改main.c;其中,pTOC这个全局变量必须声明,pTOC是个大有来头的结构指针。build过程中,romimage.exe 会查找pTOC指针,然后将boot.bib中定义的RAM、ROM等地址信息填充到nb0文件的TOC结构中。因此,这个全局变量不定义,就无法生产nb0文件,只有bin文件(bin文件不采用TOC结构,而是直接在文件头保存,more information please refer:Windows Embedded CE Binary Image Data Format in MSDN)。

    1 2 #include < windows.h > 3 #include < blcommon.h > 4 5 ROMHDR * volatile const pTOC = (ROMHDR * ) - 1 ; // Gets replaced by RomLoader with real address 6   7   void main( void ) 8 { 9 // to be added 10   } 11  

     

          5、进过以上步骤,nboot subproject 的框架已实现,build project可生成nboot.nb0,只是还未实现具体功能。下面将实现系统初始化,串口通讯、NANDFLASH读写等功能。

     

    三、CPU初始化,修改startup.s

          nboot采用物理地址,把startup.s文件内mmu部分代码删除,line320-lin420;

          starup.s文件内的sleep和poweroff相关代码没用删除(留着也无妨);

          整理余下的代码,关键的部分如下,其中PHYBASE改为0x3000_0000,即boot.bib中的RAMIMAGE START值      PHYBASE         EQU     0x30000000

          代码的line16作用是跳到SDRAM去执行,若用mov pc, r0执行,将会从头(0x3000_1000)开始又执行一编,没必要。

          代码的line20-21设置的堆栈地址,等于boot.bib定义的STACK地址。

          startup.s的部分代码如下:

     

    代码 1 ; ------------------------------------------------------------------------------ 2 ; Copy boot loader to memory 3   4 ; This is the loop that perform copying. 5 ldr r0, = 0x1000 ; the first 4K of nb0 file 6 add r0, r0, #PHYBASE ; add physical base 7 mov r1, r0 ; (r1) copy destination 8 ldr r2, =0x0 ; (r2) flash started at physical address 0 9 ldr r3, =0x10000 ; counter (0x40000/4) 10 10 ldr r4, [r2], # 4 11 str r4, [r1], # 4 12 subs r3, r3, # 1 13 bne
    转载请注明原文地址: https://ibbs.8miu.com/read-2219982.html

    最新回复(0)