分类: LINUX
2013-08-21 09:13:17
原文地址:一步一步将uboot移植到mini2440(-) 作者:snowboy9859
二、移植步骤
1.选择移植参考开发板
1.1 首先选择MCU相同的开发板,在uboot-2008.10中不支持MCU为s3c2440芯片的开发板
1.2没有找到MCU相同的参考开发板,选择CPU相同的参考开发板,s3c2440的cpu为arm920T,smdk2410的cpu也是arm920T,选择smdk2410作为参考开发板。
2.在顶层makefile中为开发板添加新的配置选项(红色部分为添加代码,下同)
smdk2410_config : unconfig
@$(MKCONFIG) $(@:_config=) arm arm920t smdk2410 NULL s3c24x0
mini2440_config : unconfig
@$(MKCONFIG) $(@:_config=) arm arm920t mini2440 NULL s3c24x0
注释:增加配置选项,使make mini2440_config得以进行,为make提供编译环境和设置编译选择路径;
unconfig执行 @rm -f $(obj)include/config.h $(obj)include/config.mk \
$(obj)board/*/config.tmp $(obj)board/*/*/config.tmp \
$(obj)include/autoconf.mk $(obj)include/autoconf.mk.dep操作,该操作删除原有的配置;
@$(MKCONFIG) $(@:_config=) arm arm920t mini2440 NULL s3c24x0执行根目录下的mkconfig脚本,后面几个为传入该脚本的参数,其中$(@:_config=) 的值为mini2440,mkconfig脚本根据传入的参数对mini2440编译环境进行配置.
3.修改cpu/arm920t/start.s
3.1修改编译条件使其支持s3c2440
136 /*added by snowboy yzx mini2440*/
137 #if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)
138 /* turn off the watchdog */
3.2添加寄存器的定义
151 /*added by yzx for mini2440,register define base on the table of s3c2440 datesheet*/
152 #define CLK_CTL_BASE 0x4c000000 //基地址
153 #define MDIV_405 0x7f << 12
154 #define PSDIV_405 0x21
155 #define UPLL_MDIV_48 0x38 << 12
156 #define UPLL_PSDIV_48 0x22
157 #define MDIV_200 0xa1 << 12
158 #define PSDIV_200 0x31
根据2440芯片手册,其INTSUBMSK有15位可用。
3.4 修改时钟设置(将s3c2440主频设置为405Mhz)
#if defined(CONFIG_S3C2440)
185 /* FCLK:HCLK:PCLK = 1:4:8 */
186 ldr r0, =CLKDIVN
187 mov r1, #5
188 str r1, [r0]
189
190 mrc p15, 0, r1, c1, c0, 0 /*read ctrl regester*/
191 orr r1, r1, #0xc0000000 /*asynchronous*/
192 mcr p15, 0, r1, c1, c0, 0 /*write ctrl register*/
193
194 /*now,cpu clock is 405.00Mhz base on p255 of datasheet table*/
195 mov r1, #CLK_CTL_BASE
196
197 mov r2, #UPLL_MDIV_48
198 add r2, r2, #UPLL_PSDIV_48
199 str r2, [r1, #0x08] /*write UPLL first,48Mhz*/
200
201 mov r2, #MDIV_405
202 add r2, r2, #PSDIV_405
203 str r2, [r1, #0x04] /*MPLLCON MPLLCON 405Mhz*/
204
205 #else
206 /* FCLK:HCLK:PCLK = 1:2:4 */
207 /* default FCLK is 120 MHz ! */
208 ldr r0, =CLKDIVN
209 mov r1, #3
210 str r1, [r0]
211 #endif
分频FCLK:HCLK:PCLK = 1:4:8 是根据下表来设置的,而寄存器的设置是根据上面添加的寄存器定义来赋值的。通过芯片手册可以查到MPLLCON和UPLLCON的地址分别为0x4C000004和0x4C000008
4 修改cpu/arm920t/s3c24x0/interrupts.c
4.1 在有s3c2410宏定义开关里加入对s3c2440的支持
32 #include
33 /*modified by yzx for 2440*/
34 #if defined(CONFIG_S3C2400) || defined (CONFIG_S3C2410) || defined(CONFIG_S3C2440) || defined (CONFIG_TRAB)
35
36 #include
37 #if defined(CONFIG_S3C2400)
38 #include
39 /*modified by yzx for 2440*/
40 #elif defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)
41 #include
42 #endif
4.2在函数get_tbclk中,添加对s3c2440的支持
179 /*modified by yzx for 2440*/
180 #if defined(CONFIG_SMDK2400) || defined(CONFIG_TRAB)
181 tbclk = timer_load_val * 100;
182 #elif defined(CONFIG_SBC2410X) || \
183 defined(CONFIG_SMDK2410) || \
184 defined(CONFIG_MINI2440) || \
185 defined(CONFIG_VCMA9)
186 tbclk = CFG_HZ;
187 #else
188 # error "tbclk not configured"
189 #endif
5. 修改cpu/arm920t/s3c24x0/speed.c
5.1在宏定义中添加对s3c2440的支持
32 #include
33 /*modified by yzx for 2440*/
34 #if defined(CONFIG_S3C2400) || defined (CONFIG_S3C2410) || defined(CONFIG_S3C2440) || defined (CONFIG_TRAB)
35
36 #if defined(CONFIG_S3C2400)
37 #include
38 /*modified by yzx for 2440*/
39 #elif defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)
40 #include
41 #endif
5.2修改函数get_PLLCLK
s3c2410与s3c2440的MPLL、UPLL计算公式不同,需要修改相关代码。
72 /*modified by yzx*/
73 #if defined(CONFIG_S3C2440)
74 if (pllreg == MPLL)
75 return((CONFIG_SYS_CLK_FREQ * m * 2) / (p << s));
76 else if (pllreg == UPLL)
77 #endif
78
79 return((CONFIG_SYS_CLK_FREQ * m) / (p << s));
根据芯片手册中的公式修改
5.3 修改函数get_HCLK
同样s3c2410与s3c2440对分频的设置也不相同,需添加相关修改
93 /*modified by yzx for 2440*/
94 #if defined(CONFIG_S3C2440)
95 if (clk_power->CLKDIVN & 0x6)
96 {
97 if((clk_power->CLKDIVN & 0x6) == 2)
98 return(get_FCLK()/2);
99 if((clk_power->CLKDIVN & 0x6) == 6)
100 return((clk_power->CAMDIVN & 0x100) ? get_FCLK()/6 : get_FCLK()/3);
101 if((clk_power->CLKDIVN & 0x6) == 4)
102 return((clk_power->CAMDIVN & 0x200) ? get_FCLK()/8 : get_FCLK()/4);
103 return(get_FCLK());
104 }
105 else
106 return(get_FCLK());
107 #else
108 return((clk_power->CLKDIVN & 0x2) ? get_FCLK()/2 : get_FCLK());
109 #endif
根据芯片手册CLKDIVN寄存器的描述,如图:
可以看出代码中clk_power->CLKDIVN & 0x6确定其HDIVN的值,clk_power->CAMDIVN & 0x100)和
clk_power->CAMDIVN & 0x200分别确定CAMDIVN 第八位和第九位中的值,从而确定其分频系数。
(下面的一段代码为自己粗心所移植的,最后导致串口数据显示乱码,最后定位了半天才找到这里出了问题,通过问题了定位,也进一步了解了时钟对串口显示的重要性。
ulong get_HCLK(void)
90 {
91 S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
92
93 #if defined(CONFIG_S3C2440)
94 if (clk_power->CLKDIVN & 0x6)
95 {
96 if((clk_power->CLKDIVN) == 2)
97 return(get_FCLK()/2);
98 if((clk_power->CLKDIVN) == 6)
99 return((clk_power->CAMDIVN & 0x100)?get_FCLK()/6:get_FCLK()/3);
100 if((clk_power->CLKDIVN) == 4)
101 return((clk_power->CAMDIVN & 0x200)?get_FCLK()/8:get_FCLK()/4);
102 return(get_FCLK());
103 }
104 else
105 return(get_FCLK());
106 #else
107 return((clk_power->CLKDIVN & 0x2) ? get_FCLK()/2 : get_FCLK());
108 #endif
109 }
6. 修改include/asm-arm/mach-types.h
添加mini2440机器ID,要求添加的ID与内核提供的ID保持一致
1860 /*modified by yzx for 2440*/
1861 #define MACH_TYPE_MINI2440 1999
7.修改cpu/arm920t/s3c24x0/serial.c
在有s3c2410宏定义开关里加入对s3c2440的支持
22 /*modified by yzx*/
23 #if defined(CONFIG_S3C2400) || defined (CONFIG_S3C2410) || defined(CONFIG_S3C2440) || defined (CONFIG_TRAB)
24
25 #if defined(CONFIG_S3C2400) || defined(CONFIG_TRAB)
26 #include
27 /*modified by yzx for 2440*/
28 #elif defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)
29 #include
30 #endif
8.修改drivers/rtc/s3c24x0_rtc.c
在有s3c2410宏定义开关里加入对s3c2440的支持
33 #if defined(CONFIG_S3C2400)
34 #include
35 #elif defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)
36 #include
37 #endif
9.修改include/s3c24x0.h
9.1 在有s3c2410宏定义开关里加入对s3c2440的支持,和上面的改法一致
9.2添加寄存器CAMDIVN的定义,该寄存器在speed.c中确定分频系数时会用到。
133 /*modified by yzx for 2440*/
134 #if defined(CONFIG_S3C2440)
135 S3C24X0_REG32 CAMDIVN;
136 #endif
cp -a board/smdk2410 board/mini2440
对smdk2410.c和Makefile做修改
将smdk2410.c改为mini2440.c
修改Makefile
将代码
COBJS := smdk2410.o flash.o
改为
COBJS := mini2440.o flash.o
11.修改board/mini2440/mini2440.c
11.1 修改PLL的配置
根据上面提供的频率对照表来设置相关值
40 /*modified by yzx for mini2440*/
41 #if defined(CONFIG_S3C2410)
42 /*Fout = 202.8Mhz*/
43 #define M_MDIV 0xA1
44 #define M_PDIV 0x3
45 #define M_SDIV 0x1
46 #endif
47 #if defined(CONFIG_S3C2440)
48 /*Fout = 405Mhz*/
49 #define M_MDIV 0x7f
50 #define M_PDIV 0x2
51 #define M_SDIV 0x1
52 #endif
11.2 修改UPLL的配置
68 /*modified by yzx for 2440*/
69 #if defined(CONFIG_S3C2410)
70 #define U_M_MDIV 0x48
71 #define U_M_PDIV 0x3
72 #endif
73
74
75 #if defined(CONFIG_S3C2440)
76 #define U_M_MDIV 0x38
77 #define U_M_PDIV 0x2
78 #endif
79
80 #define U_M_SDIV 0x2
81 #endif
11.3为了引导内核,修改函数board_init中开发板类型代码部分。
132 /*modified by yzx,arcm number of MINI2440-board*/
133 gd->bd->bi_arch_number = MACH_TYPE_MINI2440;
12.修改board/mini2440/lowlevel_init.S
修改REFRESH的刷新周期
120 /* REFRESH parameter */
121 #define REFEN 0x1 /* Refresh enable */
122 #define TREFMD 0x0 /* CBR(CAS before RAS)/Auto refresh */
123 #define Trp 0x2 /* 4clk *//*modified by yzx*/
124 #define Trc 0x3 /* 7clk */
125 #define Tchr 0x2 /* 3clk */
126 #define REFCNT 1012 /* period=7.8us, HCLK=133Mhz, (2048+1-7.8*133) modified by yzx*/
127 /**************************************/
关于这一部分的修改,在我的博客日志《修改REFRESH的刷新周期》有详细介绍。
13.修改软硬件配置文件mini2440.h
先复制参考开发板的配置文件smdk2410.h,然后再修改
cp include/configs/smdk2410.h include/configs/mini2440.h
13.1添加对s3c2440宏定义
36 #define CONFIG_ARM920T 1 /* This is an ARM920T Core */
37 #define CONFIG_S3C2440 1 /* modified by yzx for 2440 */
38 #define CONFIG_MINI2440 1 /* modified by yzx for 2440 */
13.2修改命令提示符
114 #define CFG_PROMPT "yzx2440 # " /* Monitor Command Prompt */
至此初步修改完毕
make mini2440_config
make CROSS_COMPILE=arm-linux-
在顶层目录下生成u-boot.bin文件。
将该文件烧写到开发板上能够正常运行,如图:
注意:上图中打印出的警告是因为没有设置环境变量,设置环境变量后保存再复位之后该警告消除,如下图所示:
该部分移植的u-boot能够在mini2440上运行,但有一些功能还不完善,比如网络不通、flash不能正常使用,后面会对它进行完善。
有一些说明可能自己分析不是很透彻,可以关注下面的这篇文章,里面有一些东西还写得不错