首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

Uboot在S3C2440上的移植(2)

Uboot在S3C2440上的移植(2)

2.4 添加平台相关代码
            从汇编跳转到C程序的入口点start_armboot时,即位于./Lib_arm/Board.c中的start_armboot函数,通过函数初始化数组来依次完成CPU(cpu_init)、板级(board_init)、中断(interrupt_init)、环境变量(env_init)、串口(serial_init)、波特率(init_buardrate)、显示(disp_banner)、Flash初始化(nand_init),每个初始化后返回不为0的值,否则永远在死循环中挂起,需要重新启动开发板。
        2.4.1 锁相环时钟的配置
            在smdk2410开发板的基础上修改。在./board/qq2440v3下新建qq2440v3.c,并且将Uboot中的./board/smdk2410/smdk2410.c内容全部复制给qq2440v3.c。在include/configs下新建qq2440v3.h配置文件,同时将include/configs/smdk2410.h全部复制给qq2440v3.h。因为S3C2440与S3C2410的最高运行速率不一样,系统时钟设置也不一样,即锁相环配置有差异,因此内部总线的分频比系数是不同的。S3C2440可运行于400 MHz,而S3C2410则是200 MHz,需要更改系统时钟部分,使其增加对S3C2440的支持。
            锁相环输出的MPLL(fclk时钟频率寄存器)与UPLL(USB控制时钟频率寄存器)计算式如下:
            MPLL=(2*m*Fin)/(p*2^s)         /*锁相环输出fclk频率
            UPLL=(m*Fin)/(p*2^s)      /*锁相环输出USB控制频率
            m=M(the value for divider M)+8,p=P(the value for divider P)+2,s=S
            其中m、p、s为锁相环的预置值,控制输出频率, Fin为晶振频率12 MHz。通过下面的宏定义分别给M、P、S赋值0x5c、0x01、0x01就能轻松完成时钟配置。
            #define S3C2440_MPLL_400 MHz ((0x5c<<12)|(0x01<<4)|(0x01))
            #define S3C2440_UPLL_48 MHz ((0x38<<12)|(0x02<<4)|(0x02))
            #define S3C2440_CLKDIV 0x05 /* FCLK:HCLKCLK= 1:4:8, UCLK = UPLL
        2.4.2 串口的配置
            S3C2440带有3个UART,用异步通用串口uart0与上位机通信。串口时钟用pclk时钟,即1/2 hclk时钟,1/8 fclk时钟(mpll时钟),get_PCLK()函数返回pclk时钟频率。串口0工作于中断模式,通过FIFO缓存收发,没有校验位,1位停止位,通过设置ULCON0寄存器与UFCON0来配置。为了提高数据传送的可靠性,使用了错误接收中断机制,能够检测溢出错误、奇偶校验错误和帧错误,相关错误状态保存在错误状态寄存器UTRSTAT0的对应位中。
            串口的波特率用115 200 b/s,通过给波特率除数寄存器UBRDIV0赋值,能够确定串行发送接收波特率。计算公式如下:
            UBRDIVn=(int) (UART clock/(buad rate*16))-1;
            其中UART clock为pclk时钟,buard rate为115 200。
        2.5 编译并调试
            为了在内存中运行,先要把链接脚本文件./Board/qq2440v3/U-boot.lds中的程序初始化运行地址.=0x0000,0000改为.=0x3300,0000,以方便直接在RAM中运行。在终端控制台中先进入Uboot的根目录,然后执行命令make qq2440v3_config,通过make all来编译和连接程序。编译没有错误的情况下,会在Uboot的根目录下生成u-boot、u-boot.srec和u-boot.bin三个文件,分别对应于ELF格式、S-Record格式和二进制格式。
            直接使用JTAG烧写二进制u-boot.bin到SDRAM的0x3300,0000处,烧写完成之后,将pc的指针指向该处运行,会在串口终端上显示板子的自检信息,并给出提示符等待用户输入命令,如图5所示。

       


        3 Uboot从Flash中启动
          S3C2440既支持从Nor Flash中启动,也支持从Nand Flash中启动。Nor Flash的地址线与数据线分开,方便代码存取且速度很快,上电复位时直接把Nor Flash映射到了0x0000,0000地址处。但是Nand Flash数据线与地址线复用,运行速度慢,为了提高Nand Flash启动效率,S3C2440芯片加入了一个特殊机制,会在上电复位时,把Nand Flash前4 KB代码硬拷贝到内部SRAM的4 KB空间,然后将SRAM的4 KB空间映射到0x0000,0000处,这样直接在SRAM中启动Uboot,节省了启动时间。
        3.1 从Nor Flash中运行
        3.1.1添加Nor Flash驱动

         board/qq2440v3/Flash.c中的驱动只支持Nor Flash的AMDLV400和AMDLV800两种芯片,不支持本文板子上的AM29LV160,更不支持Nand Flash,只能用CFI标准接口连接,在/drivers/cfiflash.c中定义了该接口标准下的读写函数的具体实现。要调用该驱动,应在配置头文件/include/configs/qq2440v3.h中添加CFI的宏定义:
            #define CFG_FLASH_CFI_DRIVER 1
            并在board/qq2440v3/Makefile中去掉原来的Nor flash驱动的编译,即:
            COBJS:= qq2440v3.o flash.o 变量中去掉flash.o的连接。
        3.1.2 SDRam初始化并实现代码从定位
            Uboot在Nor Flash中启动后,在start.s阶段除了要完成必要的寄存器设置外,还要完成SDRAM的初始化以及代码从定位,即把Flash空间的Uboot映像搬运到SDRAM高地址空间中,然后在SDRAM中运行Uboot。可以直接从Nor Flash启动Uboot,但从Nand Flash启动要实现重定位,在这里就一起实现了。
            首先在.\include\configs\qq2430.h中去掉刚才添加宏定义define CONFIG_SKIP_LOWLEVEL_INIT,则会在start.s阶段进入cpu_init_crit函数以完成I/D caches设置以及禁止MMU,随后进入lowlevel_init完成内存寄存器组的设置,如SDRAM位宽、刷新率等的初始化工作。
            在.\include\configs\qq2430.h中去掉CONFIG_SKIP_
        RELOCATE_UBOOT的宏定义,来完成整个代码的重定位[5]。
             Uboot代码区的长度为_bss_start-_armboot_start,其中_bss_start与_armboot_start变量保存的都是代码段的起始地址与终止地址。_start+_bss_start-_armboot_start为代码区结束的绝对地址,通过地址绝对寻址来复制代码区的数据到内存中TEXT_BASE地址区域,其中TEXT_BASE在.\Board\QQ2440v3\Config.mk中被赋值,即TEXT_BASE=0x33000000,表示代码重定位在SDRAM中的运行起始地址。
        3.1.3 编译并调试
            Uboot已经能够成功在SDRAM中启动运行了,为了能够从Nor Flash中启动,需要做如下工作。
            先要把链接脚本文件./Board/qq2440v3/U-boot.lds中的程序初始化运行地址.=0x3300,0000改为.=0x0000,0000,通过硬件开关选择开机启动方式为Nor Flash,完成Nor Flash映射到0地址处。然后在终端控制台编译连接,直到没有错误。通过HJTAG烧录进Nor Flash里面,开机运行后串口终端输出界面如图6所示。

       

继承事业,薪火相传
返回列表