mini2440移植uboot-2008.10 (一)

时间:2022-10-14 17:12:33

今天是我申请此博客的第一天,从现在开始养成每次学完新东西,都要写博客进行总结的习惯!!!Come on!

首先就从这两天学的uboot开始吧,这两天学这个东西郁闷死了,不知道该怎么去学,尤其是到nand那部分,根据mini2440之uboot移植详细手册进行改写uboot,越到后面越头疼,怎么办??今天下载了aiku的驱动视频感觉不错,等这两天把之前学的uboot总结一下,还是回归学习驱动吧。总之学这个东西,我现在觉得就是颠来倒去一点点深入地学习。不说废话了,开始吧:

一、简介

根据国嵌实验手册4.2.4,基于uboot-2008.10,移植出可以在mini2440 norflash上运行的uboot

二、uboot启动简述

uboot与其他bootloader类似,有两个阶段

stage1:

1、初始化硬件

2、为stage2运行代码准备RAM空间

3、将stage2代码复制到RAM空间

4、设置堆栈

5、跳转到stage2的C入口点

stage2:

1、初始化本阶段要使用的硬件

2、检测系统内存映射

3、将内核映像和根文件系统,从Flash读到RAM空间

4、为内核设置启动参数

5、调用内核

1、系统上电 2、_start标号(cpu/arm920t/start.s)3、reset标号(start.s)4、cpu_init_crit标号(start.s)5、low_level_init.s(board/smdk2410/low_level_init.s)5、relocate标号(start.s)6、_start_arm_boot标号(start.s)7、start_armboot()函数(lib_arm/board.c)8、main_loop()函数(common/main.c)9、进入uboot命令行

三、开始移植

1、修改顶层Makefile

根据

smdk2410_config : unconfig
@$(MKCONFIG) $(@:_config=) arm arm920t smdk2410 NULL s3c24x0

添加

mini2440_config : unconfig
@$(MKCONFIG) $(@:_config=) arm arm920t mini2440 NULL s3c24x0

2、修改cpu/arm920t/start.S   (加黑的为添加部分)

2.1、添加对S3C2440的支持 代码136行

#if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)

2.2、添加寄存器的定义与修改时钟频率的参数

#  define CLK_CTL_BASE  0x4c000000
#  define MDIV_405      0x7f<<12
#  define PSDIV_405     0x21
#  define UPLL_MDIV_48  0x38<<12
#  define UPLL_PSDIV_48 0x22
#  define MDIV_200      0xa1<<12
#  define PS_DIV_200    0x31

2.3、修改中断禁止部分,添加s3口440中断禁止代码 代码164行 后面添加

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

2.4、修改时钟设置(将s3c2440主频设置为405MHz)

/*FCLK:HCLK:PCLK=1:2:4*/    166行左右
/*defauk FCLK is 120Mhz!*/
ldr r0,=CLKDlVN
mov r1,#3
str r1,[r0]
改为

179 # if defined(CONFIG_S3C2440)
180     /* FCLK:HCLK:PCLK = 1:4:8 */
181     ldr r0, =CLKDIVN
182     mov r1, #5
183     str r1, [r0]
184
185     mrc p15, 0, r1, c1, c0, 0
186     orr r1, r1, #0xc0000000
187     mcr p15, 0, r1, c1, c0, 0
188
189     mov r1, #CLK_CTL_BASE
190
191     mov r2, #UPLL_MDIV_48
192     add r2, r2, #UPLL_PSDIV_48
193     str r2, [r1, #0x08]
194
195     mov r2, #MDIV_405
196     add r2, r2, #PSDIV_405
197     str r2, [r1, #0x04]

199 # else
200     /* FCLK:HCLK:PCLK = 1:2:4 */
201     ldr r0, =CLKDIVN
202     mov r1, #3
203     str r1, [r0]
204
205     mrc p15, 0, r1, c1, c0, 0
206     orr r1, r1, #0xc0000000
207     mcr p15, 0, r1, c1, c0, 0
208
209     mov r1, #CLK_CTL_BASE
210     mov r2, #MDIV_200
211     add r2, r2, #PSDIV_200
212     str r2, [r1, #0x04]
213
214 # endif


3、修改cpu/arm920t/s3c24x0/interrupt.c

3.1、 修改宏定义,增加对S3C2440的支持 (加黑的为添加部分)

32 #include <common.h>
33 #if defined(CONFIG_S3C2400) || defined (CONFIG_S3C2410) || defined(CONFIG_S3C2440) || defined (CONFIG_TRAB)
34
35 #include <arm920t.h>
36 #if defined(CONFIG_S3C2400)
37 #include <s3c2400.h>
38 #elif defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)
39 #include <s3c2410.h>
40 #endif

3.2、 在函数get_tbclk()中添加对mini2440的支持  (加黑的为添加部分)

173 ulong get_tbclk (void)
174 {
175     ulong tbclk;
176
177 #if defined(CONFIG_SMDK2400) || defined(CONFIG_TRAB)
178     tbclk = timer_load_val * 100;
179 #elif defined(CONFIG_SBC2410X) || \
180       defined(CONFIG_SMDK2410) || \
181       defined(CONFIG_MINI2440) || \
182       defined(CONFIG_VCMA9)
183     tbclk = CFG_HZ;
184 #else
185 #   error "tbclk not configured"
186 #endif
187
188     return tbclk;
189 }

4、修改cpu/arm920t/s3c24x0/speed.c

4.1、 修改宏定义,增加对S3C2440的支持 (加黑的为添加部分)

32 #include <common.h>
33 #if defined(CONFIG_S3C2400) || defined (CONFIG_S3C2410) || defined(CONFIG_S3C2440) || defined (CONFIG_TRAB)
34
35 #if defined(CONFIG_S3C2400)
36 #include <s3c2400.h>
37 #elif defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)
38 #include <s3c2410.h>
39 #endif

4.2、修改函数get_PLLCLK()  (加黑的为添加部分)

由于S3C2440的MPLL计算公式与S3C2410不一样,而UPLL的计算公式一样,所以修改如下

54 static ulong get_PLLCLK(int pllreg)
55 {

56     S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
57     ulong r, m, p, s;
58
59     if (pllreg == MPLL)
60     r = clk_power->MPLLCON;
61     else if (pllreg == UPLL)
62     r = clk_power->UPLLCON;
63     else
64     hang();
65
66     m = ((r & 0xFF000) >> 12) + 8;
67     p = ((r & 0x003F0) >> 4) + 2;
68     s = r & 0x3;
69
70 #if defined(CONFIG_S3C2440)
71     if (pllreg == MPLL)
72     return((CONFIG_SYS_CLK_FREQ * m * 2) / (p << s));
73 #endif

74
75     return((CONFIG_SYS_CLK_FREQ * m) / (p << s));
76 }

4.3、修改函数get_HCLK()  (加黑的为添加部分)

具体修改参考S3C2440数据手册

85 ulong get_HCLK(void)
86 {

87     S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
88
89 #if defined(CONFIG_S3C2440)
90     if(clk_power->CLKDIVN & 0x6)
91     {
92         if (2 == (clk_power->CLKDIVN & 0x6))
93             return (get_FCLK()/2);
94         if (6 == (clk_power->CLKDIVN & 0x6))
95             return((clk_power->CAMDIVN & 0x100) ? get_FCLK()/6 : get_FCLK()/3)    ;
96         if (4 == (clk_power->CLKDIVN & 0x6))
97             return((clk_power->CAMDIVN & 0x200) ? get_FCLK()/8 : get_FCLK()/4)    ;
98         else
99             return (get_FCLK());
100     }
101     else
102         return (get_FCLK());

103
104 #else
105     return((clk_power->CLKDIVN & 0x2) ? get_FCLK()/2 : get_FCLK());
106 #endif
107 }

5、修改cpu/arm920t/s3c24x0/serial.c  (加黑的为添加部分)

21 #include <common.h>
22 #if defined(CONFIG_S3C2400) || defined (CONFIG_S3C2410) || defined(CONFIG_S3C2440) || defined (CONFIG_TRAB)
23
24 #if defined(CONFIG_S3C2400) || defined(CONFIG_TRAB)
25 #include <s3c2400.h>
26 #elif defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)
27 #include <s3c2410.h>
28 #endif

6、修改drivers/rtc/s3c24x0_rtc.c (加黑的为添加部分)

28 #include <common.h>
29 #include <command.h>
30
31 #if (defined(CONFIG_CMD_DATE))
32
33 #if defined(CONFIG_S3C2400)
34 #include <s3c2400.h>
35 #elif defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)
36 #include <s3c2410.h>
37 #endif

7、修改include/asm-arm/mach-type.h

第1859行左右添加

#define MACH_TYPE_MINI2440   1999

8、修改include/s3c24x0.h(加黑的为添加部分)

添加寄存器定义

77 /* INTERRUPT (see manual chapter 14) */
78 typedef struct {
………………
83     S3C24X0_REG32   INTPND;
84     S3C24X0_REG32   INTOFFSET;
85 #if defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)
86     S3C24X0_REG32   SUBSRCPND;
87     S3C24X0_REG32   INTSUBMSK;
88 #endif
89 } /*__attribute__((__packed__))*/ S3C24X0_INTERRUPT;

 

92 /* DMAS (see manual chapter 8) */
93 typedef struct {
94     S3C24X0_REG32   DISRC;
95 #if defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)
96     S3C24X0_REG32   DISRCC;
97 #endif
98     S3C24X0_REG32   DIDST;
99 #if defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)
100     S3C24X0_REG32   DIDSTC;
101 #endif
…………
110 #if defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)
111     S3C24X0_REG32   res[7];
112 #endif
113 } /*__attribute__((__packed__))*/ S3C24X0_DMA;

 

120 /* CLOCK & POWER MANAGEMENT (see S3C2400 manual chapter 6) */
121 /*                          (see S3C2410 manual chapter 7) */
122 typedef struct {
………
128     S3C24X0_REG32   CLKDIVN;
129 #if defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)
130     S3C24X0_REG32   CAMDIVN;
131 #endif

132 } /*__attribute__((__packed__))*/ S3C24X0_CLOCK_POWER;

 

135 /* LCD CONTROLLER (see manual chapter 15) */
136 typedef struct {
……
149     S3C24X0_REG32   DITHMODE;
150     S3C24X0_REG32   TPAL;
151 #if defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)
152     S3C24X0_REG32   LCDINTPND;
153     S3C24X0_REG32   LCDSRCPND;
154     S3C24X0_REG32   LCDINTMSK;
155     S3C24X0_REG32   LPCSEL;
156 #endif
157 } /*__attribute__((__packed__))*/ S3C24X0_LCD;

 

372 /* I/O PORT (see manual chapter 9) */
373 typedef struct {
374 #ifdef CONFIG_S3C2400
………
407 #if defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)
408     S3C24X0_REG32   GPACON;
409     S3C24X0_REG32   GPADAT;
……………
457 } /*__attribute__((__packed__))*/ S3C24X0_GPIO;

9、在board目录中添加属于新开发板的目录

(1)在board目录下创建mini2440文件夹,将board/smdk2410下的所有文件拷贝到mini2440文件夹下

(2)将mini2440文件夹下的smdk2410.c改为mini2440.c

(3)修改mini2440文件夹下的Makefile, COBJS := mini2440.o flash.o

10、修改board/mini2440/mini2440.c  (修改如下)

39 #elif FCLK_SPEED==1     /* Fout = 202.8MHz */
40
41 #if defined(CONFIG_S3C2440)
42 #define M_MDIV  0x7f
43 #define M_PDIV  0x2
44 #define M_SDIV  0x1
45 #endif
46
47 #if defined(CONFIG_S3C2410)
48 #define M_MDIV  0xA1
49 #define M_PDIV  0x3
50 #define M_SDIV  0x1
51 #endif

52
53 #endif

61 #elif USB_CLOCK==1
62
63 #if defined(CONFIG_S3C2440)
64 #define U_M_MDIV    0x38
65 #define U_M_PDIV    0x2
66 #define U_M_SDIV    0x2
67 #endif
68
69 #if defined(CONFIG_S3C2410)
70 #define U_M_MDIV    0x48
71 #define U_M_PDIV    0x3
72 #define U_M_SDIV    0x2
73 #endif

74
75 #endif

88 int board_init (void)
89 {

…………
125     /* arch number of SMDK2410-Board */
126     gd->bd->bi_arch_number = MACH_TYPE_MINI2440;

128     /* adress of boot parameters */
129     gd->bd->bi_boot_params = 0x30000100;
130
131     icache_enable();
132     dcache_enable();
133
134     return 0;
135 }

11、修改board/mini2440/lowlevel_init.S (修改如下)

#define REFCNT     1012 改为 #define REFCNT 0x4f4

原因:根据SDRAM芯片手册上说的 8192(8K) refresh cycles / 64ms 得到 SDRAM刷新周期 period=64ms/8192 =7.8125us

REFCNT 是刷新控制寄存器REFRESH的Refresh Counter([10:0])

SDRAM时钟频率就是HCLK的频率

REFCNT = 2^11 + 1 - SDRAM时钟频率(MHz) * SDRAM刷新周期(us) = 2^11 + 1 – 100 * 7.8125 = 1267.75 = 0x4F4

12、修改配置文件 include/configs/mini2440.h

将include/configs下的smdk2410.h 拷贝一份到mini2440.h

36 #define CONFIG_ARM920T      1   /* This is an ARM920T Core  */
37 #define CONFIG_S3C2410      1   /* in a SAMSUNG S3C2410 SoC     */
38 #define CONFIG_SMDK2410     1   /* on a SAMSUNG SMDK2410 Board  */

改为

36 #define CONFIG_ARM920T 1 /* This is an ARM920T Core */
37 #define CONFIG_S3C2440 1 /* in a SAMSUNG S3C2440 SoC */
38 #define CONFIG_MINI2440 1 /* on a SAMSUNG Mini440 Board */

13、编译

#make clean

#make mini2440_config

#make CROSS_COMPILE=arm-linux-