• 首页
  • 中国
  • u-boot-2009.08在mini2440上的移植(一)---建立mini2440工程环境(3)

u-boot-2009.08在mini2440上的移植(一)---建立mini2440工程环境(3)

2023-11-01 77浏览
百检网是一家专业的第三方检测平台,汇聚众多拥有权威资质的第三方检测机构为你提供一站式的检测服务,做检测就上百检网。百检网让检测从此检测,一份报告全国通用,专业值得信赖。

根据启动流程修改或添加基本的u-boot源码,使其能够在内存中启动

【1】增加对S3C2440一些寄存器的支持,添加中断禁止部分和时钟设置部分

用gedit打开cpu/arm920t/start.S,定位到134行附近,如下代码

#if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410)/* turn off the watchdog */

由于2410和2440的寄存器及地址大部分是一致的,所以这里就直接在2410的基础上再加上对2440的支持即可,修改后代码如下:

#if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410)|| defined(CONFIG_S3C2440)/* turn off the watchdog */

... ...

# if defined(CONFIG_S3C2410) ldr r1, =0x3ff ldr r0, =INTSUBMSK str r1, [r0]# endif

# if defined(CONFIG_S3C2440)//添加s3c2440的中断禁止部分 ldr r1, =0x7fff //根据2440芯片手册,INTSUBMSK寄存器有15位可用 ldr r0, =INTSUBMSK str r1, [r0]# endif

# if defined(CONFIG_S3C2440) //添加s3c2440的时钟部分#define MPLLCON 0x4C000004 //系统主频配置寄存器基地址#define UPLLCON 0x4C000008 //USB时钟频率配置寄存器基地址 ldr r0, =CLKDIVN //设置分频系数FCLK:HCLK:PCLK = 1:4:8 mov r1, #5 str r1, [r0] ldr r0, =MPLLCON //设置系统主频为405MHz ldr r1, =0x7F021 //这个值参考芯片手册“PLL VALUE SELECTION TABLE”部分 str r1, [r0] ldr r0, =UPLLCON //设置USB时钟频率为48MHz ldr r1, =0x38022 //这个值参考芯片手册“PLL VALUE SELECTION TABLE”部分 str r1, [r0]# else //其他开发板的时钟部分 /* FCLK:HCLK:PCLK = 1:2:4 *//* default FCLK is 202.8 MHz ! */ ldr r0, =CLKDIVN mov r1, #3 str r1, [r0]

ldr r0, =MPLLCON //设置系统主频为202.8MHz(可以先不添加,对我们的移植没有影响) ldr r1, =0xa1031 //这个值参考芯片手册“PLL VALUE SELECTION TABLE”部分(可以先不添加,对我们的移植没有影响) str r1, [r0](可以先不添加,对我们的移植没有影响)

# endif

#endif /* CONFIG_S3C2400 || CONFIG_S3C2410|| CONFIG_S3C2440*/

**,上面INTSUBMSK寄存器有15位可用与2410是不同的,在之前的文章中已经做出说明了,这里不在说了,说一下时钟部分:看一下这两个寄存器

下面的说明也许需要注意一下,手册中说在设置MPLLCON和UPLLCON时要先设置UPLLCON,之后再设置MPLLCON,上面作者是没有按照这个要求来做的,没有去验证是否对系统有影响,在我的移植过程中我是按照手册中的要求,按顺序设置的,然后怎么通过设置MPLLCON和UPLLCON获得我们想要的系统主频时钟和USB时钟呢,手册上面给了我们一个计算方法,当然我们一般直接按照手册中给出的表获得我们想要的配置

看看这个配置表吧,我们用这个配置表来配置:

我们把主频时钟配置为405MHz,那么按照上面的说明,MDIV=127,PDIV=2,SDIV=1,所以MPLLCON =0x7F021,同理,把USB时钟配置为48MHz,按照上面的说明,MDIV=56,PDIV=2,SDIV=2,所以,UPLLCON=0x38022,设置分频系数FCLK:HCLK:PCLK = 1:4:8,下面

【2】S3C2440的时钟部分除了在start.S中添加外,还要分别在board/samsung/mini2440/mini2440.c和cpu/arm920t/s3c24x0/speed.c中修改或添加部分代码。

(1)用gedit打开board/samsung/mini2440/mini2440.c,定位到33行,修改或添加如下内容:

//设置主频和USB时钟频率参数与start.S中的一致

#define FCLK_SPEED2 //设置默认等于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 //这三个值根据S3C2440芯片手册“PLL VALUE SELECTION TABLE”部分进行设置#define M_PDIV 0x2#define M_SDIV 0x1#endif

#define USB_CLOCK2 //设置默认等于2

#if USB_CLOCK==0#define U_M_MDIV 0xA1#define U_M_PDIV 0x3#define U_M_SDIV 0x1#elif USB_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 //这三个值根据S3C2440芯片手册“PLL VALUE SELECTION TABLE”部分进行设置#define U_M_PDIV 0x2#define U_M_SDIV 0x2#endif

(2)用gedit打开cpu/arm920t/s3c24x0/speed.c,定位到69行加入如下代码

m = ((r & 0xFF000) >> 12) + 8; p = ((r & 0x003F0) >> 4) + 2; s = r & 0x3;

//根据设置的分频系数FCLK:HCLK:PCLK = 1:4:8修改获取时钟频率的函数#if defined(CONFIG_S3C2440) if(pllreg == MPLL)//参考S3C2440芯片手册上的公式:PLL=(2 * m * Fin)/(p * 2s) return((CONFIG_SYS_CLK_FREQ * m * 2) / (p << s)); //else if (pllreg == UPLL) //warning: control reaches end of non-void function#endif

return((CONFIG_SYS_CLK_FREQ * m) / (p << s));

为什么要再返回时加一个判断呢?因为在2440中MPLL的时钟为UPLL时钟的2倍,这个地方也是我有疑问的地方,虽然是2倍的关系不错,我这里在移植过程中还是加入了UPLL分支的计算方法,在s3c2440的数据手册里的227页这样写到MPLL和UPLL的计算方法

MPLL Control RegisterMpll = (2 * m * Fin) / (p * 2s)m = (MDIV + 8), p = (PDIV + 2), s = SDIVUPLL Control RegisterUpll = (m * Fin) / (p * 2s)m = (MDIV + 8), p = (PDIV + 2), s = SDIV程序先获得m,p,s,然后根据这三个变量求出响应的值,这个就是修改此函数的缘由。

由于S3C2410和S3C2440的设置方法也不一样,所以get_HCLK函数也需要修改:

/* return HCLK frequency */ulong get_HCLK(void){ S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();#if defined(CONFIG_S3C2440)if (clk_power->CLKDIVN & 0x6){if ((clk_power->CLKDIVN & 0x6)==2) return(get_FCLK()/2);if ((clk_power->CLKDIVN & 0x6)==6) return((clk_power->CAMDIVN & 0x100) ? get_FCLK()/6 : get_FCLK()/3);if ((clk_power->CLKDIVN & 0x6)==4) return((clk_power->CAMDIVN & 0x200) ? get_FCLK()/8 : get_FCLK()/4);return(get_FCLK());(似乎有点多余)}elsereturn(get_FCLK());#else return((clk_power->CLKDIVN & 0x2) ? get_FCLK()/2 : get_FCLK());#endif

}

这里用到了将在include/s3c24x0.h文件里所添加的CAMDIVN 项,因为这一项的值决定了我们的时钟配置。这样修改的原因是在s3c2440的数据手册的231页有这样一段话:我们到底应该返回FCLK的几分之一在这里就有秒数,其中必须根据HDIVN 的值与CAMDIVN的值来判断。

【3】加入LED进度指示,增加控制台显示信息

作用是显示代码进度,对 Debug 有帮助。这里先看一下led的硬件连接

(1)代码在跳转到第二阶段代码start_armboot 函数前会亮起一个LED 灯,打开cpu/arm920t/start.S,定位到240行附近,修改如下:

clbss_l: str r2, [r0] /* clear loop... */ add r0, r0, #4 cmp r0, r1 ble clbss_l

#if defined(CONFIG_MINI2440_LED)//根据mini2440原理图可知LED分别由S3C2440的PB5、6、7、8口来控制,

//以下是PB端口寄存器基地址(查2440的DataSheet得知)#define GPBCON 0x56000010#define GPBDAT 0x56000014#define GPBUP 0x56000018 //以下对寄存器的操作参照S3C2440的DataSheet进行操作 ldr r0, =GPBUP ldr r1, =0x7FF //即:二进制11111111111,关闭PB口上拉 str r1, [r0]

ldr r0, =GPBCON //配置PB5、6、7、8为输出口,对应PBCON寄存器的第10-17位 ldr r1, =0x154FD //即:二进制010101010011111101 str r1, [r0]

ldr r0, =GPBDAT ldr r1, =0x1C0 //即:二进制111000000,PB5设为低电平,6、7、8为高电平 str r1, [r0]

#endif//此段代码使u-boot启动后,开发板上的LED1被点亮,而LED2、LED3、LED4不亮

ldr pc, _start_armboot

_start_armboot: .word start_armboot#define STACK_BASE 0x33f00000#define STACK_SIZE 0x10000.align 2DW_STACK_START: .word STACK_BASE+STACK_SIZE-4

1.**通过GPBUP关闭GPB口上拉

所以设置GPBUP=0x7FF

2.设置GPB5,6,7,8为输入

(2)在完成board_init函数初始化时的点亮第二个LED,修改如下:

打开board/samsung/mini2440/mini2440.c,定位到100行附近,修改如下:

/* set up the I/O ports */gpio->GPACON = 0x007FFFFF;#if defined(CONFIG_MINI2440)gpio->GPBCON = 0x00295551;#elsegpio->GPBCON = 0x00044556;#endifgpio->GPBUP = 0x000007FF;gpio->GPCCON = 0xAAAAAAAA;gpio->GPCUP = 0xFFFFFFFF;gpio->GPDCON = 0xAAAAAAAA;gpio->GPDUP = 0xFFFFFFFF;gpio->GPECON = 0xAAAAAAAA;gpio->GPEUP = 0x0000FFFF;gpio->GPFCON = 0x00005**A;gpio->GPFUP = 0x000000FF;gpio->GPGCON = 0xFF95FFBA;gpio->GPGUP = 0x0000FFFF;gpio->GPHCON = 0x0016FAAA;gpio->GPHUP = 0x000007FF;

gpio->EXTINT0=0x22222222;gpio->EXTINT1=0x22222222;gpio->EXTINT2=0x22222222;

/* arch number of SMDK2410-Board */gd->bd->bi_arch_number = MACH_TYPE_SMDK2410;

/* adress of boot parameters */gd->bd->bi_boot_params = 0x30000100;

icache_enable();dcache_enable();#ifdefined(CONFIG_MINI2440_LED)gpio->GPBDAT = 0x00000181;//GPB0=buzzer#endif

int dram_init (void){gd->bd->bi_dram[0].start = PHYS_SDRAM_1;gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;

return 0;}

(3)在初始化console后点亮一个LED3,进入命令行之前点亮LED4

打开/lib_arm/board.c,定位到52行,修改如下:

#include #include #include #include //modify

#ifdef CONFIG_DRIVER_SMC91111

定位到121行,注释掉下面代码:

#if 0/************************************************************************* Coloured LED functionality************************************************************************* May be supplied by boards if desired*/void inline __coloured_LED_init (void) {}//void inline coloured_LED_init (void) __attribute__((weak, alias("__coloured_LED_init")));void inline __red_LED_on (void) {}//void inline red_LED_on (void) __attribute__((weak, alias("__red_LED_on")));void inline __red_LED_off(void) {}//void inline red_LED_off(void) __attribute__((weak, alias("__red_LED_off")));void inline __green_LED_on(void) {}//void inline green_LED_on(void) __attribute__((weak, alias("__green_LED_on")));void inline __green_LED_off(void) {}//void inline green_LED_off(void)__attribute__((weak, alias("__green_LED_off")));void inline __yellow_LED_on(void) {}//void inline yellow_LED_on(void)__attribute__((weak, alias("__yellow_LED_on")));void inline __yellow_LED_off(void) {}//void inline yellow_LED_off(void)__attribute__((weak, alias("__yellow_LED_off")));void inline __blue_LED_on(void) {}//void inline blue_LED_on(void)__attribute__((weak, alias("__blue_LED_on")));void inline __blue_LED_off(void) {}//void inline blue_LED_off(void)__attribute__((weak, alias("__blue_LED_off")));#endif

百检网秉承“客户至上,服务为先,精诚合作,以人为本”的经营理念,始终站在用户的角度解决问题,为客户提供“一站购物式”的新奇检测体验,打开网站,像挑选商品一样简单,方便。打破行业信息壁垒,建构消费和检测机构之间高效的沟通平台