1、smdk2440开发板u-boot的入口点分析: 在嵌入式系统软件开发中,在所有源码文件编译完成之后,链接器要读取一个链接分配文件,在该文件中定义了程序的入口点,代码段、数据段等分配情况等。那么我们的smdk2440开发板中,u-boot的这个链接文件就是cpu/arm920t/u-boot.lds,打开该文件部分代码如下: OUTPUT_FORMAT("elf32-littlearm","elf32-littlearm","elf32-littlearm") OUTPUT_ARCH(arm)????//定义生成文件的目标平台是arm ENTRY(_start)??????????????//定义程序的入口点是_start SECTIONS { ??? //其他一些代码段、数据段等分配 ??? . = 0x00000000; ??? . = ALIGN(4); ??? .text : ??? { ??????? cpu/arm920t/start.o??? (.text) ??????? *(.text) ??? } ??? .................. } 知道了程序的入口点是_start,那么我们就打开smdk2440开发板u-boot第一个要运行的程序 cpu/arm920t/start.S(即u-boot的stage1部分),查找到_start的位置如下: globl _start _start: b?????? start_code????//将程序的执行跳转到start_code处 从这段汇编代码可以看到程序又跳转到start_code处开始执行,那么再查找到start_code处的代码如下: /* the actual start code */ start_code: ??? /* ???? * set the cpu to SVC32 mode ???? */ ??? mrs??? r0,cpsr ??? bic??? r0,r0,#0x1f ??? orr??? r0,#0xd3 ??? msr??? cpsr,r0 ??? //以下两行是对AT91RM9200DK开发板上的LED进行初始化的,可以将它们删除 ??? bl coloured_LED_init?? ??? bl red_LED_on ??? ... ... 由此可以看到,start_code处是u-boot启动代码的真正开始处。以上就是u-boot的stage1入口的过程。
2、smdk2440开发板u-boot的硬件设备初始化。 2.1、在u-boot启动代码处有两行是AT91RM9200DK的LED初始代码,但tx2440上的LED资源与该开发板的不一致,所以我们要删除或屏蔽该处代码,可以再加上tx2440的LED驱动代码(注:添加tx2440 LED功能只是用于表示u-boot运行的状态,给调试带来方便,可将该段代码放到任何你想调试的地方),代码如下: ????//bl coloured_LED_init? //接上一步 ??? //bl red_LED_on ? #if defined(CONFIG_S3C2440)??//区别与其他开发板 //根据tx2440原理图可知LED分别由S3C2440的PB5、6、7、8口来控制,以下是PB端口寄存器基地址(查2440的DataSheet得知) #define GPFCON 0x56000050 #define GPFDAT 0x56000054 #define GPFUP? 0x56000058 ????//以下对寄存器的操作参照S3C2440的DataSheet进行操作 ??? ldr r0,=GPFUP ??? ldr r1,=0x7FF????????//即:二进制22222222221,关闭GPF口上拉 ??? str r1,[r0] ??? ldr r0,=GPFCON???//配置PF1、2、3、4为输出口 ??? ldr r1,=0x0055??????//即:二进制01010101 ??? str r1,[r0] ??? ldr r0,=GPFDAT ??? ldr r1,=0x0F?????????//即:二进制11110000,PF0、1、2、3设为低电平 ??? str r1,[r0] #endif //此段代码使u-boot启动后,点亮开发板上的LED1、LED2、LED3、LED4 2.2、在u-boot中添加对S3C2440一些寄存器的支持、添加中断禁止部分和时钟设置部分。 由于2410和2440的寄存器及地址大部分是一致的,所以这里就直接在2410的基础上加上对2440的支持即可: ... ... #if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410)?|| defined(CONFIG_S3C2440) ?/* turn off the watchdog */ # if defined(CONFIG_S3C2400) #? define pWTCON? 0x15300000 #? define INTMSK? 0x14400008 /* Interupt-Controller base addresses */ #? define CLKDIVN 0x14800014 /* clock divisor register */ #else????????????????????????//下面的相关寄存器在2410和2440中的地址是一致的 #? define pWTCON? 0x53000000 #? define INTMSK? 0x4A000008 /* Interupt-Controller base addresses */ #? define INTSUBMSK 0x4A00001C #? define CLKDIVN? 0x4C000014 /* clock divisor register */ # endif ?ldr???? r0,=pWTCON????????//关闭看门狗定时器 ?mov???? r1,#0x0 ?str???? r1,[r0] ?/* ? * mask all IRQs by setting all bits in the INTMR - default ? */ ?mov r1,#0xffffffff ?ldr r0,=INTMSK ?str r1,[r0] # if defined(CONFIG_S3C2410)?|| defined(CONFIG_S3C2440) # if defined(CONFIG_S3C2410) ? ldr r1,=0x3ff # else ? ldr r1,=0x7fff??????????//添加s3c2440的中断禁止部分 # endif ?ldr r0,=INTSUBMSK ?str r1,[r0] # endif # if defined(CONFIG_S3C2440) ? ldr r0,=CLKDIVN?????????//设置分频系数FCLK ? mov r1,#0x5?? /* 0=1:1:1,1=1:1:2,2=1:2:2,3=1:2:4,4=1:4:4,5=1:4:8,6=1:3:3,7=1:3:6 */ ? str r1,[r0]? # else ? ldr r0,=CLKDIVN?? /* default FCLK is 120 MHz !? FCLK:HCLK:PCLK = 1:2:4? */ ? mov r1,#3 ? str r1,[r0] # endif ? mrc p15,c1,c0,0????//根据2440的Datasheet,设置异步总线模式 ? orr r0,#0xc0000000? /*R1_nF:OR:R1_iA*/ ? mcr p15,0 #endif /* CONFIG_S3C2400 || CONFIG_S3C2410? || defined(CONFIG_S3C2440)*/ 2.3、时钟部分除了在start.S中添加外,还要分别在board/smdk2440/smdk2440.c和cpu/arm920t/s3c24x0/speed.c中修改或添加部分代码。 修改board/samsung/my2440/smdk2440.c,设置主频和USB时钟频率参数: #define FCLK_SPEED?2???????//设置默认等于2,即下面红色代码部分有效 #if FCLK_SPEED==0????????? /* Fout = 203MHz,Fin = 12MHz for Audio */ #define M_MDIV??? 0xC3 #define M_PDIV??? 0x4 #define M_SDIV??? 0x1 #elif FCLK_SPEED==1??????? /* Fout = 202.8MHz */ #define M_MDIV??? 0xA1 #define M_PDIV??? 0x3 #define M_SDIV??? 0x1 #elif FCLK_SPEED==2????????/* Fout = 405MHz */ #define M_MDIV??? 0x7F??????//这三个值根据芯片手册"PLL VALUE SELECTION TABLE”部分进行设置 #define M_PDIV??? 0x2 #define M_SDIV??? 0x1 #endif #define USB_CLOCK?2????????//设置默认等于2,即下面红色代码部分有效 #if USB_CLOCK==0 #define U_M_MDIV??? 0xA1 #define U_M_PDIV??? 0x3 #define U_M_SDIV??? 0x1 #elifUSB_CLOCK==1 #define U_M_MDIV??? 0x48 #define U_M_PDIV??? 0x3 #define U_M_SDIV??? 0x2 #elif USB_CLOCK==2????????? /* Fout = 48MHz */ #define U_M_MDIV??? 0x38???//这三个值根据芯片手册"PLL VALUE SELECTION TABLE”部分进行设置 #define U_M_PDIV??? 0x2 #define U_M_SDIV??? 0x2 #endif ... ... 找到board_init函数,将gd->bd->bi_arch_number = MACH_TYPE_SMDK2410修改为 gd->bd->bi_arch_number = MACH_TYPE_SMDK2440; 修改cpu/arm920t/s3c24x0/speed.c,根据设置的分频系数FCLK:HCLK:PCLK 修改获取时钟频率的函数: static ulong get_PLLCLK(int pllreg) { ??? S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER(); ??? ulong r,m,p,s;
|