U-boot学习与移植 linux
任务表格 ubuntu |
||||
时间 网络 |
3.31 异步 |
4.1 工具 |
4.2 oop |
4.3 学习 |
任务、阶段 优化 |
学习了解 this |
开始移植 spa |
优化总结 |
修补返工 |
备注 |
|
|
|
|
今天是四月三号,周四,农历三月初三。大风。
早晨,完成了u-boot 的移植。分外欣喜,这是我第一次移植u-boot,尽管有书参考,网络可用,可是仍是遇到了不少问题,毕竟仍是个嵌入式底层驱动菜鸟。遂赶忙记录总结,虽然遇到的问题或许都是小儿科,可是,不去认真对待小儿科,就没法健康长大,就没法成为大人。
另:重振一下学习态度,严谨认真。
一
1、解压u-boot-1.1.6 创建si文件夹,创建sourceinsigh工程
2、
3、
4、
2、根据《嵌入式linux应用开发彻底手册》
1、在board里创建jd24x0目录,另将smdk2410目录复制粘贴到jd24x0里,smdk24x0.c更名为jd24x0.c。
2、在include/configs目录里,将ssmdk2410.h复制为jd24x0.h。
3、修改Makefile
1、顶层Makefile,添加两行
jd24x0_config : unconfig
@$(MKCONFIG) $(@:_config=) arm arm920t jd24x0 NULL s3c24x0
2、board/jd24x0/Makefile:修改以下
COBJS := smdk2410.o flash.o 改成
COBJS := jd24x0.o flash.o
3、修改SDRAM(注意若先建好了工程须要,从新添加一下)
SDRAM的初始化在u-boot的第一阶段完成,就是在board/jd24x0/lowlevel_init.s文件里,设置存储控制器。
只需修改SDRAM的刷新参数,即REFCNT寄存器。
#define REFCNT 1113 /* period=15.6us, HCLK=60Mhz, (2048+1-15.6*60) */
改成
#define REFCNT 0x4f4
4、读取GSTAUS1寄存器的值可分辨2410,2440
S3c2410与s3c2440MPLL,UPLL计算公式不同,
S3c2410:FCLK,200MHZ,FCLK:HCLK:PCLK=1:2:4
S3c2440:FCLK,400MHZ,FCLK:HCLK:PCLK=1:4:8
需将UCLK设为48MHZ,以在内核中支持USB控制器。
在board/jd24x0/jd24x0.c里修改后以下
#include <common.h>
#include <s3c2410.h>
DECLARE_GLOBAL_DATA_PTR;
//----------------------
#define S3C2440_MPLL_400MHZ ((0x5c<<12)|(0x01<<4)|(0x01))
#define S3C2440_UPLL_48MHZ ((0x38<<12)|(0x02<<4)|(0x02))
#define S3C2440_CLKDIV 0x05
#define S3C2410_MPLL_200MHZ ((0x5c<<12)|(0x04<<4)|(0x00))
#define S3C2410_UPLL_48MHZ ((0x28<<12)|(0x01<<4)|(0x02))
#define S3C2410_CLKDIV 0x03
//----------------------
static inline void delay (unsigned long loops)
{
__asm__ volatile ("1:\n"
"subs %0, %1, #1\n"
"bne 1b":"=r" (loops):"0" (loops));
}
/*
* Miscellaneous platform dependent initialisations
*/
int board_init (void)
{
S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
//---------------------------------
gpio->GPACON = 0x007FFFFF;
gpio->GPBCON = 0x00044555;
gpio->GPBUP = 0x000007FF;
gpio->GPCCON = 0xAAAAAAAA;
gpio->GPCUP = 0x0000FFFF;
gpio->GPDCON = 0xAAAAAAAA;
gpio->GPDUP = 0x0000FFFF;
gpio->GPECON = 0xAAAAAAAA;
gpio->GPEUP = 0x0000FFFF;
gpio->GPFCON = 0x000055AA;
gpio->GPFUP = 0x000000FF;
gpio->GPGCON = 0xFF95FFBA;
gpio->GPGUP = 0x0000FFFF;
gpio->GPHCON = 0x002AFAAA;
gpio->GPHUP = 0x000007FF;
/*t同时支持2410 2440*/
if ((gpio->GSTATUS1 == 0x32410000) || (gpio->GSTATUS1 == 0x32410002))
{
clk_power->CLKDIVN = S3C2410_CLKDIV;
/*异步总线模式*/
__asm__( "mrc p15, 0, r1, c1, c0, 0\n"
"orr r1, r1, #0xc0000000\n"
"mcr p15, 0, r1, c1, c0, 0\n"
:::"r1"
);
//设置pll锁定时间
clk_power->LOCKTIME = 0xFFFFFF;
//配置mll
clk_power->MPLLCON = S3C2410_MPLL_200MHZ;
delay (4000);
//配置upll
clk_power->UPLLCON = S3C2410_UPLL_48MHZ;
delay (8000);
//机器类型邋ID,调用linux内核时用到
gd->bd->bi_arch_number = MACH_TYPE_SMDK2410;
}
else
{//global_data
//fclk:hclk:pclk=1:4:8
clk_power->CLKDIVN = S3C2440_CLKDIV;
/*异步总线模式*/
__asm__( "mrc p15, 0, r1, c1, c0, 0\n"
"orr r1, r1, #0xc0000000\n"
"mcr p15, 0, r1, c1, c0, 0\n"
:::"r1"
);
//设置pll锁定时间
clk_power->LOCKTIME = 0xFFFFFF;
//设置mpll
clk_power->MPLLCON = S3C2440_MPLL_400MHZ;
delay (4000);
//设置upll
clk_power->UPLLCON = S3C2440_UPLL_48MHZ;
delay (8000);
//机器类型邋ID,调用linux内核时用到
gd->bd->bi_arch_number = MACH_TYPE_S3C2440;
}
//启动内核时参数存放位置,在构造标记列表时用到
gd->bd->bi_boot_params = 0x30000100;
icache_enable();
dcache_enable();
return 0;
}
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;
}
5、设置机器类型ID:gd->bd->bi_arch_number,分辨s3c2440与2410
须要用DECLARE_GLOBAL_DATA_PTR宏定义
6、在cpu/arm920t/s3c24x0/speed.c里修改以下
//+++++++++++++++++++++++++++++++
#define S3C2440_CLKDIVN_PDIVN (1<<0)
#define S3C2440_CLKDIVN_HDIVN_MASK (3<<1)
#define S3C2440_CLKDIVN_HDIVN_1 (0<<1)
#define S3C2440_CLKDIVN_HDIVN_2 (1<<1)
#define S3C2440_CLKDIVN_HDIVN_4_8 (2<<1)
#define S3C2440_CLKDIVN_HDIVN_3_6 (3<<1)
#define S3C2440_CLKDIVN_UCLK (1<<3)
#define S3C2440_CAMDIVN_CAMCLK_MASK (0xf<<0)
#define S3C2440_CAMDIVN_CAMCLK_SEL (1<<4)
#define S3C2440_CAMDIVN_HCLK3_HALF (1<<8)
#define S3C2440_CAMDIVN_HCLK4_HALF (1<<9)
#define S3C2440_CAMDIVN_DVSEN (1<<12)
//REFCNT
//-----------------------------------------
/* ------------------------------------------------------------------------- */
/* NOTE: This describes the proper use of this file.
*
* CONFIG_SYS_CLK_FREQ should be defined as the input frequency of the PLL.
*
* get_FCLK(), get_HCLK(), get_PCLK() and get_UCLK() return the clock of
* the specified bus in HZ.
*/
/* ------------------------------------------------------------------------- */
DECLARE_GLOBAL_DATA_PTR;
static ulong get_PLLCLK(int pllreg)
{
S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
ulong r, m, p, s;
if (pllreg == MPLL)
r = clk_power->MPLLCON;
else if (pllreg == UPLL)
r = clk_power->UPLLCON;
else
hang();
m = ((r & 0xFF000) >> 12) + 8;
p = ((r & 0x003F0) >> 4) + 2;
s = r & 0x3;
//同时支持2410 2440
if(gd->bd->bi_arch_number == MACH_TYPE_SMDK2410)
return ((CONFIG_SYS_CLK_FREQ * m) / (p << s));
else
return ((CONFIG_SYS_CLK_FREQ * m * 2) /(p << s));
}
/* return FCLK frequency */
ulong get_FCLK(void)
{
return(get_PLLCLK(MPLL));
}
/* return HCLK frequency */
ulong get_HCLK(void)
{
S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
unsigned long clkdiv;
unsigned long camdiv;
int hdiv = 1;
//同时支持2410 2440//
if (gd->bd->bi_arch_number == MACH_TYPE_SMDK2410)
return((clk_power->CLKDIVN & 0x2) ? get_FCLK()/2 : get_FCLK());
else
{
clkdiv = clk_power->CLKDIVN;
camdiv = clk_power->CAMDIVN;
switch (clkdiv & S3C2440_CLKDIVN_HDIVN_MASK) {
case S3C2440_CLKDIVN_HDIVN_1:
hdiv = 1;
break;
case S3C2440_CLKDIVN_HDIVN_2:
hdiv = 2;
break;
case S3C2440_CLKDIVN_HDIVN_4_8:
hdiv = (camdiv & S3C2440_CAMDIVN_HCLK4_HALF) ? 8 : 4;
break;
case S3C2440_CLKDIVN_HDIVN_3_6:
hdiv = (camdiv & S3C2440_CAMDIVN_HCLK3_HALF) ? 6 : 3;
break;
}
return get_FCLK() / hdiv;
}
//return((clk_power->CLKDIVN & 0x2) ? get_FCLK()/2 : get_FCLK());
}
/* return PCLK frequency */
ulong get_PCLK(void)
{
S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
unsigned long clkdiv;
unsigned long camdiv;
int hdiv = 1;
//DECLARE_GLOBAL_DATA_PTR
if (gd->bd->bi_arch_number == MACH_TYPE_SMDK2410)
return((clk_power->CLKDIVN & 0x1) ? get_HCLK()/2 : get_HCLK());
else
{
clkdiv = clk_power->CLKDIVN;
camdiv = clk_power->CAMDIVN;
//计算分频比
switch (clkdiv & S3C2440_CLKDIVN_HDIVN_MASK) {
case S3C2440_CLKDIVN_HDIVN_1:
hdiv = 1;
break;
case S3C2440_CLKDIVN_HDIVN_2:
hdiv = 2;
break;
case S3C2440_CLKDIVN_HDIVN_4_8:
hdiv = (camdiv & S3C2440_CAMDIVN_HCLK4_HALF) ? 8 : 4;
break;
case S3C2440_CLKDIVN_HDIVN_3_6:
hdiv = (camdiv & S3C2440_CAMDIVN_HCLK3_HALF) ? 6 : 3;
break;
}
return get_FCLK() / hdiv / ((clkdiv & S3C2440_CLKDIVN_PDIVN)? 2:1);
}
}
/* return UCLK frequency */
ulong get_UCLK(void)
{
return(get_PLLCLK(UPLL));
}
#endif
3、到此处生成u-boot.bin文件就便可用2410又能用2440了,在串口工具上就能看到信息了。能够操做u-boot了。不过,问题仍是会有,一切不会顺利。
1、source insight里save all一下
2、将u-boot传到ubuntu上编译,
3问题
permission :容许批准承认denied:拒绝
解决:sudo chmod 777 /路径/Mkconfig
如:
4、make all后出现问题
在make all时会出现错误:没有CAMDIVN
这个要在include/s3c24x0.h中定义, 在129行S3C24X0_CLOCK_POWER结构体中增长:
S3C24X0_REG32 CAMDIVN; /* for s3c2440*/
成功:
--------------------------完成-------------------------------