u-boot在NIA1MCUA单板(MPC7447+TSI108)的移植和启动说明.doc_第1页
u-boot在NIA1MCUA单板(MPC7447+TSI108)的移植和启动说明.doc_第2页
u-boot在NIA1MCUA单板(MPC7447+TSI108)的移植和启动说明.doc_第3页
u-boot在NIA1MCUA单板(MPC7447+TSI108)的移植和启动说明.doc_第4页
u-boot在NIA1MCUA单板(MPC7447+TSI108)的移植和启动说明.doc_第5页
已阅读5页,还剩14页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

文档称:u-boot在NIA1MCUA单板(MPC7447+TSI108)的移植和启动详细说明文档密级内部公开u-boot在NIA1MCUA单板(MPC7447+TSI108)的移植和启动详细说明 作者: 胡慧锋 工号: 05517 部门: 硬件技术部关键词:u-boot,MPC7447A,TSI108,DDR2摘 要:本文的u-boot移植的对象是NIA1MCUA单板,该单板主要由MPC7447A,TSI108,DDR2,FLASH等器件组成。本文主要说明了u-boot在该单板上的移植和启动的详细过程,使读者能够加深对u-boot的了解。Huawei-3Com Technologies Co., Ltd. 华为3Com技术有限公司All rights reserved版权所有 侵权必究目 录1u-boot简介32. NIA1MCUA单板说明43. u-boot交叉编译环境的建立54. u-boot的移植和启动过程54.1 u-boot移植需要修改的文件54.2 u-boot启动流程64.2.1 start.S84.2.2 board_init_f函数124.2.3 board_init_r函数144.2.4 main_loop函数154.2.5 u-boot启动流程小结164.3 u-boot的移植过程165. 结束语18附件181u-boot简介u-boot(也叫Das u-boot),全称Universal Boot Loader,它的前身是ppcboot。它遵守GPL规则,开放其所有的源码。作为系统的引导代码,它支持很多种处理器架构,如:PowerPC系统,ARM,MIPS等,同时,它还支持NetBSD, VxWorks, QNX, RTEMS, ARTOS, LynxOS嵌入式操作系统。其目前要支持的目标操作系统是OpenBSD, NetBSD, FreeBSD,4.4BSD, Linux, SVR4, Esix, Solaris, Irix, SCO, Dell, NCR, VxWorks, LynxOS, pSOS, QNX, RTEMS, ARTOS。它的所有版本的代码都可以从下载。从PPCBOOT向U-Boot的顺利过渡,很大程度上归功于U-Boot的维护人德国DENX软件工程中心Wolfgang Denk以下简称W.D本人精湛专业水平和持着不懈的努力。当前,U-Boot项目正在他的领军之下,众多有志于开放源码BOOT LOADER移植工作的嵌入式开发人员正将各个不同系列嵌入式处理器的移植工作不断展开和深入,以支持更多的嵌入式操作系统的装载与引导。在进行移植前,我们需要了解一些u-boot的主要目录结构:n board:包含多种目标系统,主要是和目标系统板相关的代码定义,例如我所用到的文件board/typhoon/typhoon.c 中有关于处理器的I/O 端口定义等操作n 在common:该目录下主要包含与处理器无关的功能,例如U-Boot 的命令处理,环境变量的设置等n CPU:与CPU 有关的功能,例如:cpu/74xx_7xx/serial.c 是串口的驱动等n disk:主要是磁盘驱动处理的代码n doc:主要是一些readme 文档,用处不是太大n driver:主要是一些设备驱动,如rtl8139.c 是8139 网卡的驱动等n dtt:针对温度设备的驱动n examples:主要是一些应用例子,如hello_world.c,timer.c 等n fs:文件系统的支持n include:U-Boot 头文件,需要修改的文件如include/configs/typhoon.hn lib_generic:公共的库目录,包含CRC 校验,压缩,打印显示等功能n lib_ppc:和PowerPC 系列有关的功能,如lib_ppc/board.c 文件中的初始化功能n net:U-Boot 对网络协议的支持,主要支持bootp/rarp 和tftp 协议n post:目标系统板上电复位自检功能n rtc:硬件实时时钟的驱动n tools:用来生成U-Boot 镜像的一些工具2. NIA1MCUA单板说明NIA1MCUA主要由MPC7447A处理器,TSI108桥片,DDR2内存,BOOTROM,FLASH,PHY芯片,对外接口等器件组成。具体可以参见图1-1。图1-1 NIA1MCUA单板结构框图MPC7447A是本板的处理器单元,所有的指令处理都是在它上面完成的。TSI108是北桥芯片,它通过MPX与CPU(MPC7447A)通信,对外,则提供了PCI,UART,IIC,GMII等接口,通过CPU对TSI108的配置,这些接口就可以正常工作了。BROADCOM是PHY芯片,主要处理以太网数据,同时与TSI108上集成的MAC芯片交换数据。DDR2是内存(512MB),存放系统运行时的数据,指令,堆栈等。BOOTROM(512KB)用于存放u-boot的代码,它可以通过烧写器把u-boot的可执行代码保存在其内部,当上电后,CPU就会从BOOTROM上读取第一条指令。当需要引导内核代码时,512KB的BOOTROM就不够用了,所以系统还增加了32MB的FLASH,用来存放操作系统代码。EPLD是用来保护FLASH被意外破坏的。EEPROM用来存放一些MAC地址,IP地址等信息。3. u-boot交叉编译环境的建立要建立u-boot的编译环境,首先要下载一个u-boot源码,这个源码可从U-Boot的官方网站/projects/U-Boot上获得,里面有各种版本,我使用的是u-boot-1.1.4。在下载完代码后,我们需要在X86上建立一套交叉编译环境,使得MPC7447A能够识别在X86上编译的代码。这里,我们使用了德国的denx软件中心的开发编译环境套件:eldk,即Embedded Linux Development Kit,这个套件可以从/pub/eldk上免费下载。我选用的是ELDK 4.0(for freescale PPC)。现在,我们就可以在Linux上安装这个套件了,我选用的Red Hat 9.0。首先在下载的ELDK根目录下运行./install d /opt/eldk/4.0 ppc_74xx,其中d /opt/eldk/4.0是表示安装的目的路径,ppc_74xx是CPU型号,由于我们选用的是MPC7447A,所以就选用了ppc_74xx。在安装结束后,还需要配置环境变量。在Linux下输入下面几行命令:export ARCH=ppcexport CROSS_COMPILE=ppc_74xx-export PATH=/opt/eldk/4.0/usr/bin:/opt/eldk/4.0/bin:$PATH这样,u-boot的交叉编译环境就建立好了。4. u-boot的移植和启动过程4.1 u-boot移植需要修改的文件很容易从网上了解到,u-boot的移植一般只需要在以下几个步骤进行修改即可:(1) 在board目录下创建typhoon目录(这个目录名可以自己定,我们暂且把它命名为typhoon目录),添加typhoon.h、flash.c、typhoon.c、tsi108.h、makefile等,具体可以见后面; (2) 在cpu目录下创建一个新的目录,用来放CPU相关的函数,主要包含start.s、interrupts.c、cpu.c、serial.c和speed.c等文件。在这里,由于u-boot-1.1.4已经支持MPC7447A这个型号的CPU,因此我们不需要再添加新的目录,而是在已有的目录cpu / 74xx_7xx下进行相应的修改即可; (3) 在include/configs目录下添加typhoon.h,它定义了全局的宏定义等; (4) 修改u-boot根目录下的Makefile文件: typhoon_config: unconfig./mkconfig $(:_config=) ppc 74xx_7xx typhoon由于这部分代码与硬件紧密相关,所以要熟悉单板的硬件配置,可参考各芯片的用户手册。4.2 u-boot启动流程要进行具体的移植,我们首先需要对u-boot的启动流程有一定程序的了解,否则就会无从下手,整个启动流程可以用图4-1(启动的简单概述),图4-2(启动的详细过程)来表示。图4-1 u-boot启动流程略图图4-2 u-boot启动流程详图4.2.1 start.S在u-boot中,任何一款CPU都是从cpu/cpu类型/start.S文件开始运行第一条指令,在我们的单板上,start.S文件在cpu/74xx_7xx目录下。u-boot的启动是从start.S的_start:标号开始执行,下面就u-boot中start.S的关键代码作一下介绍:_start:lir21, BOOTFLAG_COLD/* 正常上电启动 */bboot_cold/* 跳转到boot_cold,并且不再返回 */sync/* 指令同步 */boot_cold:boot_warm:lir0, 0/* r0 = 0 */* mtspr把r0放到特殊目的寄存器中HID0中,The hardware implementation-dependent register 0 (HID0) 主要控制硬件的很多使能位和状态等,这条指令也就是关闭所有的硬件使能位。 */mtsprHID0, r0/* MSR(Machine State Register)寄存器的值为0 */mtmsr0/* 跳转到invalidate_bats标号,通过设置一些特殊寄存器的值,达到使bat无效的效果,执行结束后返回。由于篇幅关系,本文没有列出invalidate_bats的指令,具体可以参见start.S */blinvalidate_bats/* 把CFG_MONITOR_BASE的值放入r3中,由于它是32位的,所以要分两条指令来完成。在全局宏定义文件includeconfigstyphoon.h中, 可以找到它的值:CFG_MONITOR_BASE = TEXT_BASE,它是boot monitor code 的起始地址, TEXT_BASE是在board/typhoon/config.mk中被定义,在刚开始从flash启动时,它的值就是CFG_FLASH_BASE( 0xff000000(512KB) )的值。 */lisr3, CFG_MONITOR_BASEhorir3, r3, CFG_MONITOR_BASEl/* 这三条代码主要作用是程序跳转到标号in_flash:(绝对地址)处,执行结束后不返回 */addir3, r3, in_flash - _start + EXC_OFF_SYS_RESETmtlr r3blrin_flash:/* 跳转到setup_bats标号,这条指令主要实现设置bat的初始状态和tlb的清除。bat(block address translation)是大于一页的有效地址印射到物理地址,bat主要用于实现地址从虚地址到物理地址的转换,通过bat可以对内存或者flash地址实现有效的访问和保护。而tlb(translation lookaside buffer)主要用于清除页表。由于篇幅关系,本文没有列出setup_bats的指令,具体可以参见start.S */ blsetup_bats/* 下面这个指令是可选的。主要用来在初始化的时候防止cache的数据回写到RAM中,由于每次复位后RAM中的数据便无效,所以也可以不锁定cache的回写功能。CFG_INIT_RAM_LOCK在includeconfigstyphoon.h中被定义为#undefCFG_INIT_RAM_LOCK,因此在此并不执行这条语句。*/#ifdef CFG_INIT_RAM_LOCKbllock_ram_in_cache#endif/* 下面几条指令主要用于在cache中建立一个小的堆栈,以便执行C语言代码,r1就是堆栈指针寄存器。同时,为了防止堆栈在异常的时候能够回收并且打印异常信息,需要把栈顶8个字节清0。lisr1, (CFG_INIT_RAM_ADDR + CFG_GBL_DATA_OFFSET)horir1, r1, (CFG_INIT_RAM_ADDR + CFG_GBL_DATA_OFFSET)llir0, 0stwur0, -4(r1)stwur0, -4(r1)/* 下面开始执行C语言函数,该函数在cpu/74xx_7xx/cpu_init.c中,主要实现了获取CPU类型,并且使能HID0的timebase位。由于篇幅关系,本文没有列出cpu_init_f的函数,具体可以参见cpu/74xx_7xx/cpu_init.c */blcpu_init_f/* 该函数在lib_ppc/board.c中,主要执行单板的一些初始化工作,比如初始化内存,串口。经过初始化后就可以把代码放到内存中运行了。该函数在最后回调start.S中的标号为relocate_code:中的指令。这个函数将在4.4.2节中具体说明。 */blboard_init_frelocate_code: /* 注意,这里并没有列出relocate_code的所有代码 */* 获得内存中的放代码地址 - flash的放代码的基地址 */subr15, r10, r4/* 把原来在cache中的r14(GOT入口)加上一个offset,使它变为RAM中的地址 */addr14, r14, r15/* 这段代码就是把flash的指令一条一条的考到RAM中,一直循环,直到代码读完*/lar8,-4(r4)/load address , r8 = r4 - 1lar7,-4(r3)1:lwzur0,4(r8)/r0 = (r8 + 4)地址中的值, r8 = r8 + 4stwur0,4(r7)/r0的值存放到(r7 + 4)地址, r7 = r7 + 4bdnz1b/减CRT, 如果非0,则跳转回1.b4f/* 开始清除cache中的内容。*/4:5:dcbst0,r4addr4,r4,r6cmplwr4,r5blt5b/* 不断循环,直到dcbst完成 */6:icbi0,r4addr4,r4,r6cmplwr4,r5blt6b/* 不断循环,直到icbi完成 */* 下面开始跳转到in_ram标号处。由于r10是RAM上的放代码的地址,所以也就跳转到RAM中进行指令读取了。可以说从这几行代码后,CPU已经在RAM中读取指令了。*/addir0, r10, in_ram - _start + EXC_OFF_SYS_RESETmtlrr0blr/* 具体的跳转指令 */in_ram:/* 这里主要把在flash中的各种跳转地址,return地址进行修复,因为这些地址原来是在flash上的地址,现在需要把它们改为RAM上的地址,(当然,如果原来这些地址是相对地址,则就没有必要修改了.)。同时还需要把全局数据考到RAM中。 在flash中,有三个段数据(data(已经定义具体值的全局变量),bss(没有定义具体值的全局变量), text(code 代码段)。在复制数据前,需要把bss段清零,这样可以保证全局变量都有值. 然后把所以全局变量都复制到RAM上即可。因此在这段代码中可以分为三个步骤:1. 调整got2指针2. 调整fixup和指针3. 清除bss段 */* 调用board/typhoon/typhoon.c 中的after_reloc()。而实际上,after_reloc()只做了一件事,就是调用board_init_r ()函数,该函数也在board/typhoon/typhoon.c中,主要实现板的第二次初始化。该函数的详细说明见4.4.3节 */blafter_reloc4.2.2 board_init_f函数board_init_f( )是在lib_ppc/board.c中定义的。它是在C语言环境下运行,但是仍然是在flash中运行指令,而不是把指令全部读取到RAM中来运行。这个函数的主要目的是尽早的提供串口来获得一些错误信息以及初始内存,以便在内存中运行所有的代码。要注意的是,这时全局变量是只读的,BSS段也没有初始化,堆栈也只有几kB,因此使用时要格外小心。下面就来分析一下这个函数的具体实现:首先执行一系统的初始化,init_sequence是一个函数指针。for (init_fnc_ptr = init_sequence; *init_fnc_ptr; +init_fnc_ptr)init_sequence也是在lib_ppc/board.c,具体实现为:init_fnc_t *init_sequence = /* 得到一些总线时钟等信息,在board/typhoon/tsi108_init.c */board_early_init_f,/* 初始化时间,在lib_ppc/time.c。这里没作处理。*/init_timebase,env_init,/* 环境变量初始化 */init_baudrate,/* 初始化波特率,在lib_ppc/board.c */serial_init,/* 初始化串口,在board/typhoon/serial.c */console_init_f,/* 初始化控制台,在common/console.c */* 打印版本信息,在lib_generic/display_option.c */display_options,/* 检查并打印CPU类型,在cpu/74xx_7xx/cpu.c */checkcpu,/* 打印板的名字,在board/typhoon/typhoon.c */checkboard,init_func_ram,/* 打印RAM大小,在lib_ppc/board.c */* 测试RAM信息,在board/typhoon/typhoon.c */testdram,/* 堆栈地址应该在256MB以下 */addr = CFG_SDRAM_BASE + (gd-ram_size 256 20) ? 256 ram_size;addr &= (4096 - 1);/* 给u-boot保留了4kB */addr &= (4096 - 1);/* 给data,bss保留了4kB */* 保留malloc的内存空间 */addr_sp = addr - TOTAL_MALLOC_LEN;/* 保留全局数据的内存空间 */addr_sp -= sizeof (bd_t);addr_sp -= sizeof (gd_t);/* 获得堆栈地址,同时为了防止堆栈异常时能打印错误信息,需要把栈顶8byte清0 */addr_sp -= 16;addr_sp &= 0xF;s = (ulong *)addr_sp;*s- = 0;*s- = 0;addr_sp = (ulong)s;/* 看门狗重新赋值,由于我们没有使用看门狗,所以这个函数中没作处理 */WATCHDOG_RESET ();/* 回调到start.S中的relocate_code:标号,执行汇编代码 */relocate_code (addr_sp, id, addr);4.2.3 board_init_r函数board_init_r()是初始化的第二部分,在lib_ppc/board.c。此时,由于内存已经初始化,我们可以在内存上运行标准C语言,同时,全局变量可以被读写,BSS段也被清0,堆栈大小也大大增加了。下面就来分析一下它的具体实现:/* 配置TSI108的寄存器,如PCI,GPIO,中断等,实现TSI108的一些初始化工作。在board/typhoon/tsi108_init.c */board_early_init_r ();/* 这个for循环主要把命令表的处理函数的地址放到一个结构体的指针变量中,如果下次要调用这些函数,只需要访问这个指针即可 */for (cmdtp = &_u_boot_cmd_start; cmdtp != &_u_boot_cmd_end; cmdtp+)/* 主要是把一些向量复制到低位内存中,在start.S中 */trap_init (dest_addr);/* 初始化flash,包括读取BOOTROM,FLASH的容量,并且写保护它们。在board/typhoon/flash.c */flash_init ()/* CPU的一些初始化,这里没作什么具体处理,在cpu/74xx_7xx/cpu_init.c */cpu_init_r ();/* 初始化malloc区,在lib_ppc/board.c */mem_malloc_init ();env_relocate ();/* 环境变量指针重定位,在common/env_common.c */env_relocate ();/* 配置以太网地址 */for (i = 0; i bi_enetaddri = s ? simple_strtoul (s, &e, 16) : 0;if (s)s = (*e) ? e + 1 : e;/* 配置PCI的一些特性,在drives/pci.c 而在这个函数中又调用了pci_init_board(),主要在配置任务都在pci_init_board()上实现,它在board/typhoon/pci.c */pci_init ();/* 初始化设置,如IIC,keyboard等,具体还需要结合typhoon.h中的宏定义,在common/drives.cdevices_init ();/* 初始化应用程序的跳转地址,包括IIC,free, udelay等函数,在common/exports.c */jumptable_init ();/* 设置控制台的输入输出功能, 在common/console.c */console_init_r ();/* 配置一些TSI108寄存器,打印MEM,BUS,CACHE的一些信息,在board/typhoon/tsi108_init.c */misc_init_r ();/* 初始化中断的一些寄存器。在lib_ppc/interrupts.c */interrupt_init ();/* 进入main_loop()循环,该循环主要检测是否有新的命令从控制台进入,在common/main.c, 详见4.2.4节 */for (;) main_loop ();4.2.4 main_loop函数main_loop主要是从控制台(串口)中读取命令,然后执行,整个函数一直在进行for循环,直到出现异常情况。在common/main.c for( ; ; )/* 读取命令 */len = readline (CFG_PROMPT);/* 处理命令 */rc = run_command (lastcommand, flag);4.2.5 u-boot启动流程小结到main_loop这个函数为止,u-boot的堆栈初始化,代码relocate,设置初始化,控制台操作等基本基本信息已经配置结束。如果选为autoboot,则uboot便跳转到相对应的IMG文件并引导内核启动,如果是手动启动,便可以实现在控制台输入一系列的命令,如环境变量读写,tftp下载,flash读写,内核手动引导等。4.3 u-boot的移植过程在4.2节中已经阐述了u-boot的启动过程,因此移植u-boot已经是一件比较简单的事,只需要根据启动过程所需要调用的接口,提供相对应的函数即可,所以在本节中只是简单的讲述一下需要增加的文件和这些文件对外提供的函数。以下就是这些需要的文件:typhoon.h:typhoon.h在include/configs/下,主要是申明u-boot需要使用的全局宏定义,比如IP地址,FLASH地址,RAM大小等。它是u-boot中最重要的一个.h文件,所有的操作都和它密切相关。具体可以参见附件一。typhoon.c:typhoon.c在board/typhoon/下,主要给系统提供了after_reloc()函数,以及内存测试的函数testdram()。cpu_ini

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论