Chinaunix首页 | 论坛 | 博客
  • 博客访问: 465177
  • 博文数量: 68
  • 博客积分: 2606
  • 博客等级: 上尉
  • 技术积分: 1308
  • 用 户 组: 普通用户
  • 注册时间: 2010-12-13 23:01
文章分类
文章存档

2012年(6)

2011年(62)

分类: LINUX

2011-06-23 16:14:49

一、移植环境

  • 主  机:VMWare--redhat 5
  • 开发板:Mini2440--256MB Nand
  • 编译器:
  • u-boot:

二、移植步骤

  • 移植uboot到mini2440,使其可以在nor flash中运行
  • 支持DM9000网卡
  • 支持nor flash读写

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

上述定义是根据芯片手册来设置的
 
 MDIV相应的数据之所以要左移12位是因为它在对应的寄存器的12-19位,将pdiv和sdiv放在一起用16进制表示,因为pdiv正好从第四位开始取值。
 
 根据下表来设置对应的寄存器的值,38 2 2对应于48Mhz的频率,7f 2 1对应405Mhz的频率,其中200的频率在mini2440的开发板中没有用到,可以提供给其他的开发板使用。
 
      
3.3 修改中断禁止部分,添加s3c2440的中断禁止代码
170 # if defined(CONFIG_S3C2410)
171         ldr     r1, =0x3ff
172         ldr     r0, =INTSUBMSK
173         str     r1, [r0]
174 # endif

175
176 /*added by yzx for mini2440,s3c2440 have 15bit INTSUBMSK can be used*/
177 #if defined(CONFIG_S3C2440)
178         ldr r1, =0x7fff
179         ldr r0, =INTSUBMSK
180         str r1, [r0]
181 #endif
182 /*added by yzx for mini2440,s3c2440 have 15bit INTSUBMSK can be used*/

根据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


10.在board目录中创建一个属于新开发板的目录,向目录中添加文件,再修改

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不能正常使用,后面会对它进行完善。

有一些说明可能自己分析不是很透彻,可以关注下面的这篇文章,里面有一些东西还写得不错

阅读(15057) | 评论(3) | 转发(13) |
给主人留下些什么吧!~~

dan768542015-07-09 16:40:38

LZ,不要嫌我菜哈,那个get_PLLCLK函数为什么是那样改的? C语言函数里面可以用#if什么的吗

sssfff1234567892014-09-27 12:43:33

第9步,具体怎么操作

luyunxm2014-06-19 21:33:22

移植成功 非常感谢