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

一、写在前面

      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的部分代码如下:

 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 %b10
14
15 ; Restart from the RAM position after copying.
16 add pc, pc, r0 ; R0 = PHYBASE + 0x1000
17 nop
18 nop
19
20 20 mov sp, #0x30000000
21 add sp, sp, #0x4000
22 b main

转自:http://www.cnblogs.com/wincee/articles/1688869.html

原文地址:https://www.cnblogs.com/wenziqi/p/1814644.html