你的位置:首页 > 操作系统

[操作系统]移植u


  首先从u-boot官网下载最新版的u-boot,这里我下的是u-boot-2015.10。下载完成后解压,阅读README,在Building the Software:中得知编译方法:如果使用交叉编译的话要执行以下命令:

 CROSS_COMPILE=arm-linux-
 export CROSS_COMPILE

然后执行make NAME_defconfig,进行默认的配置。NAME为支持的开发板的名称,最后make all 即可。这里默认配置中和JZ2440最接近的是三星的smdk2410开发板。因此,我这里执行make smdk2410_defconfig,然后make all。编译成功,用JLINK烧写到norflash中,上电启动,发现串口无任何输出,看来smdk2410的配置不能直接用到JZ2440开发板,需要修改代码。可以新建一个单板目录,但新版u-boot需要改动的地方很多,较麻烦,因此我就直接在smdk2410的代码上改了。首先分析启动过程,根据编译生成的u-boot.lds发现第一个文件是arch/arm/cpu/arm920t/start.S。于是从这里开始分析。分析到lowlevel_init函数时,发现对SDRAM进行设置时,SMRDATA中的REFCNT依赖于HCLK=60MHz,而在这之前只设置了时钟比例,具体时钟大小还未设置,所以估计这里有问题。如果有openjtag可以用openjtag对SDRAM进行读写,就会发现读写有问题。于是修改代码:在board/samsung/smdk2410/smdk2410.c的board_early_init_f中将时钟的设置函数注释掉,

 

int board_early_init_f(void) {   struct s3c24x0_clock_power * const clk_power =           s3c24x0_get_base_clock_power();   struct s3c24x0_gpio * const gpio = s3c24x0_get_base_gpio();   /* to reduce PLL lock time, adjust the LOCKTIME register */   //writel(0xFFFFFF, &clk_power->locktime);   /* configure MPLL */   //writel((M_MDIV << 12) + (M_PDIV << 4) + M_SDIV, &clk_power->mpllcon);   /* some delay between MPLL and UPLL */   //pll_delay(4000)   /* configure UPLL */   //writel((U_M_MDIV << 12) + (U_M_PDIV << 4) + U_M_SDIV,  &clk_power->upllcon);   /* some delay between MPLL and UPLL */   //pll_delay(8000);  

在前面的start.S中自己设置时钟:

ldr r0, =CLKDIVNmov r1, #3str r1, [r0]/*clk config*/#define S3C2440_MPLL_200MHZ   ((0x5c<<12)|(0x01<<4)|(0x02))ldr r0, =0x4c000004ldr r1, =S3C2440_MPLL_200MHZstr r1, [r0]

将board/samsung/smdk2410/lowlevel_init.S中的SRMDATA改为对应我们设置的时钟的数值

SMRDATA:  .long 0x22011110   //BWSCON  .long 0x00000700   //BANKCON0  .long 0x00000700   //BANKCON1  .long 0x00000700   //BANKCON2  .long 0x00000700   //BANKCON3   .long 0x00000700   //BANKCON4  .long 0x00000700   //BANKCON5  .long 0x00018005   //BANKCON6  .long 0x00018005   //BANKCON7  .long 0x008C04F4   // REFRESH  .long 0x000000B1   //BANKSIZE  .long 0x00000030   //MRSRB6  .long 0x00000030   //MRSRB7

改完后编译,串口有输出了,但是乱码,估计是波特率的问题。分析代码,在board_init_r中,init_sequence_r函数数组中有一个initr_serial函数,一路追踪下去,到serial_register(&s3c24xx_serial0_device),这个函数注册了串口0,s3c24xx_serial0_device定义如下,

DECLARE_S3C_SERIAL_FUNCTIONS(0);struct serial_device s3c24xx_serial0_device =INIT_S3C_SERIAL_STRUCTURE(0, "s3ser0");

INIT_S3C_SERIAL_STRUCTURE定义如下:

#define INIT_S3C_SERIAL_STRUCTURE(port, __name) {  \  .name  = __name,        \  .start  = s3serial##port##_init,    \  .stop  = NULL,          \  .setbrg  = s3serial##port##_setbrg,    \  .getc  = s3serial##port##_getc,    \  .tstc  = s3serial##port##_tstc,    \  .putc  = s3serial##port##_putc,    \  .puts  = s3serial##port##_puts,    \}

我们看看波特率设置函数.setbrg = s3serial##port##_setbrg的定义,

#define DECLARE_S3C_SERIAL_FUNCTIONS(port) \  int s3serial##port##_init(void) \  { \    return serial_init_dev(port); \  } \  void s3serial##port##_setbrg(void) \  { \    serial_setbrg_dev(port); \  } \

一路跟踪进_serial_setbrg函数,get_PCLK,get_HCLK(),发现get_HCLK()中支持2440,但要要定义CONFIG_S3C2440,于是,我们在include/configs/smdk2410.h中定义这个宏,编译出现错误,./arch/arm/include/asm/arch/s3c24x0.h:443: error: duplicate member 'gpacon' ,打开s3c24x0.h:443,发现由于定义了CONFIG_S3C2440,导致寄存器重复定义了,删去2410那一段即可,编译后,烧写程序,串口成功打印。