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*/
成功:
--------------------------完成-------------------------------