详细解析mini2440uboot移植.docx

上传人:b****3 文档编号:5440036 上传时间:2022-12-16 格式:DOCX 页数:17 大小:23.48KB
下载 相关 举报
详细解析mini2440uboot移植.docx_第1页
第1页 / 共17页
详细解析mini2440uboot移植.docx_第2页
第2页 / 共17页
详细解析mini2440uboot移植.docx_第3页
第3页 / 共17页
详细解析mini2440uboot移植.docx_第4页
第4页 / 共17页
详细解析mini2440uboot移植.docx_第5页
第5页 / 共17页
点击查看更多>>
下载资源
资源描述

详细解析mini2440uboot移植.docx

《详细解析mini2440uboot移植.docx》由会员分享,可在线阅读,更多相关《详细解析mini2440uboot移植.docx(17页珍藏版)》请在冰豆网上搜索。

详细解析mini2440uboot移植.docx

详细解析mini2440uboot移植

下面会对每一个步骤详细解答,包括为什么这样做?

版本用的是u-boot-2008.10。

我们选择一般都是寻找最相近的进行移植,首先应该考虑选择MCU(微型控制芯片)一样的开发板,如果没有这类存在,就退而求其次,选择MPU(微型处理芯片,即IP核)一样的开发板。

在uboot中没有支持S3C2440(MCU)的开发板,就考虑MPU,S3C2440是arm920t的IP核,所以选择相近的,锁定目标smdk2410开发板,它是以arm920t为核心,三星公司开发的一块开发板。

选定目标之后就可以开始移植了。

第一步:

移植一般从最顶层文件开始,最顶层当然是Makefile了,从它开始编译的。

打开Makefile后找到下面这行字:

(最左边的是行数,这个在同类版本中有一些出入,大家找到关键词就行了)

2625smdk2400_config:

unconfig:

2626@$(MKCONFIG)$(@:

_config=)armarm920tsmdk2400NULLs3c24x0

2627

2628smdk2410_config:

unconfig

2629@$(MKCONFIG)$(@:

_config=)armarm920tsmdk2410NULLs3c24x0

2630

2631SX1_config:

unconfig

2632@$(MKCONFIG)$(@:

_config=)armarm925tsx1

这几行有什么用呢?

定义开发板的名字和其他相关信息,以smdk2410为例,即:

arm:

cpu架构;

arm920t:

cpu的核;

smdk2410:

开发板的名字;

NULL:

开发者,这里没有,也可写上你想取的名字;

S3C24X0:

片上系统(Soc);

现在我们就可以知道哪些可以修改,哪些不用修改了。

这里没有对我们想要移植的开发板的支持,所以应该加上,改成如下:

(红色字为修改的):

2625smdk2400_config:

unconfig:

2626@$(MKCONFIG)$(@:

_config=)armarm920tsmdk2400NULLs3c24x0

2627

2628smdk2410_config:

unconfig

2629@$(MKCONFIG)$(@:

_config=)armarm920tsmdk2410NULLs3c24x0

2630/*modifiedbymike,weletitsupportthedevelopedboardofMINI2440*/

2631MINI2440_config:

unconfig

2632@$(MKCONFIG)$(@:

_config=)armarm920tMINI2410NULLs3c24x0

2633

2634SX1_config:

unconfig

2635@$(MKCONFIG)$(@:

_config=)armarm925tsx1

这里注意一点,如果你取名为MINI2440,那么以后涉及开发板的名字时(接下去的会讲到)就必须以这个名字,而且是必须是大写的,否则编译时会找不到相应的文件。

修改完顶层文件后就开始修改其他与顶层文件不在同一层的文件了,我们知道uboot中很多都不需要修改,不同的大部分在于cpu以及board这两个目录中,为什么呢?

因为一个关于cpu架构,一个关于开发板类型的。

比如smdk2410在board中就有自己的目录,所以新建的这个开发板就得在board中也有自己的目录,这个待会再讲。

那么cpu呢?

这里面有自己的各种核,比如arm920t,powerPC,x86等,接下去修改的便是arm920t这个目录,让这个IP核也支持它的产品S3C2440。

第二步:

进入/cpu/arm920t/start.S,这是一个很重要的文件,我们根据链接脚本可以看出,程序执行都是从这个文件开始执行的。

我们讲一下,当在编译前,我们不是一般都会执行这个命令:

makesmdk2410_config,这意味着待会编译时就只会讲与smdk2410有关的文件链接一起,所以其他不相关的不会参与编译。

那么这个start.S里面有哪些内容需要修改呢?

我们查看文件不难发现,里面有对S3C2410的支持,那么S3C2410与S3C2440很类似,所以修改的地方就不多了,只是添加上一些宏定义而已,源代码如下:

136#ifdefined(CONFIG_S3C2400)||defined(CONFIG_S3C2410)

137/*turnoffthewatchdog*/

138

138#ifdefined(CONFIG_S3C2400)

140#definepWTCON0x15300000

141#defineINTMSK0x14400008/*Interupt-Controllerbaseaddresses*/

142#defineCLKDIVN0x14800014/*clockdivisorregister*/

143#else

144#definepWTCON0x53000000

145#defineINTMSK0x4A000008/*Interupt-Controllerbaseaddresses*/

146#defineINTSUBMSK0x4A00001C

147#defineCLKDIVN0x4C000014/*clockdivisorregister*/

148#endif

149

150ldrr0,=pWTCON

151movr1,#0x0

152strr1,[r0]

153

154/*

155*maskallIRQsbysettingallbitsintheINTMR-default

156*/

157movr1,#0xffffffff

158ldrr0,=INTMSK

159strr1,[r0]

160#ifdefined(CONFIG_S3C2410)

161ldrr1,=0x3ff

162ldrr0,=INTSUBMSK

163strr1,[r0]

164#endif

165

166/*FCLK:

HCLK:

PCLK=1:

2:

4*/

167/*defaultFCLKis120MHz!

*/

168ldrr0,=CLKDIVN

169movr1,#3

170strr1,[r0]

171#endif/*CONFIG_S3C2400||CONFIG_S3C2410*/

现在修改这些代码如下:

135/*modifiedbyMike,addthe2440,closethewatchdog*/

136#ifdefined(CONFIG_S3C2400)||defined(CONFIG_S3C2410)||defined(CONFIG_S3C2440)

137/*turnoffthewatchdog*/

138

139#ifdefined(CONFIG_S3C2400)

140#definepWTCON0x15300000

141#defineINTMSK0x14400008/*Interupt-Controllerbaseaddresses*/

142#defineCLKDIVN0x14800014/*clockdivisorregister*/

143#else

144#definepWTCON0x53000000

145#defineINTMSK0x4A000008/*Interupt-Controllerbaseaddresses*/

146#defineINTSUBMSK0x4A00001C

147#defineCLKDIVN0x4C000014/*clockdivisorregister*/

148#endif

149

150#defineCLK_CTL_BASE0x4C000000

151#defineMDIV_4050x7f<<12

152#definePSDIV_4050x21

153#defineUPLL_MDIV_480x38<<12

154#defineUPLL_PSDIV_480x22

155#defineMDIV_2000xa1<<12

156#definePSDIV_2000x31

157#endif

158

159ldrr0,=pWTCON

160movr1,#0x0

161strr1,[r0]

162

163/*

164*maskallIRQsbysettingallbitsintheINTMR-default

165*/

166movr1,#0xffffffff

167ldrr0,=INTMSK

168strr1,[r0]

169#ifdefined(CONFIG_S3C2410)

170ldrr1,=0x3ff

171ldrr0,=INTSUBMSK

172strr1,[r0]

173#endif

174

175#ifdefined(CONFIG_S3C2440)

176ldrr1,=0x7fff

177ldrr0,=INTSUBMSK

178strr1,[r0]

179#endif

180/*modifytheclock*/

181#ifdefined(CONFIG_S3C2440)

182/*FCLK:

HCLK:

PCLK=1:

4:

8*/

183

184ldrr0,=CLKDIVN

185movr1,#5

186strr1,[r0]

187mrcp15,0,r1,c1,c0,0/*readctrlregister*/

188orrr1,r1,#0xc0000000/*Asynchronous*/

189mcrp15,0,r1,c1,c0,0/*writectrlregister*/

190

191/*now,thecpuclockis405MHz*/

192movr1,#CLK_CTL_BASE

193

194movr2,#UPLL_MDIV_48/*UPLL*/

195addr2,r2,#UPLL_PSDIV_48

196strr2,[r1,#0x08]/*writeUPLLfirst,48MHz*/

197

198movr2,#MDIV_405/*MPLL405MHz*/

199addr2,r2,#PSDIV_405/*MPLL405MHz*/

200strr2,[r1,#0x04]/*MPLLCON*/

201#else

202

203/*FCLK:

HCLK:

PCLK=1:

2:

4*/

204ldrr0,=CLKDIVN

205movr1,#3

206strr1,[r0]

207

208mrcp15,0,r1,c1,c0,0/*readctrlregister*/

209orrr1,r1,#0xc0000000/*Asynchronous*/

210mcrp15,0,r1,c1,c0,0/*writectrlregister*/

211

212/*now,cpuclockis202.8MHz*/

213movr1,#CLK_CTL_BASE

214

215movr2,#MDIV_200/*MPLL200MHz*/

216addr2,r2,#PSDIV_200/*MPLL405MHz*/

217strr2,[r1,#0X04]/*MPLLCON*/

218

219#endif/*CONFIG_S3C2400||CONFIG_S3C2410||CONFIG_S3C2440*/

现在我们详细讲解为什么这么改?

以便以后自己移植新的系统会修改!

修改136行是因为让编译时支持S3C2440,这跟#ifdefined有关,关于这个关键词不会的话自行查找C语言的书。

我们可以略掉S3C2400的语句,144行定义watchdog的寄存器地址,由于S3C2440与S3C2410这一寄存器地址一样,所以无需修改的。

关于这个寄存器见S3C2440手册462页。

除了这个一样之外还有相同的是INTMSK、INTSUBMSK、CLKDIVN,分别在S3C2440手册的388、395、58页。

从150行定义的都是根据实际需要修改的。

因为我们要求将S3C2440设置为主频405MHz。

150行是定义寄存器基址,即从0x4c000000开始,MPLL寄存器是0x4c000004,UPLL寄存器是0x4c000008,所以有后面的“196strr2,[r1,#0x08]”与“200strr2,[r1,#0x04]”,即将r2寄存器的值传给r1偏移8(或者4)后的地址的存储器。

这是定义CLK_CTL_BASE的用意。

那么r2里面存的是什么值呢?

首先194行与195行的“movr2,#UPLL_MDIV_48“”addr2,r2,#UPLL_PSDIV_48“,根据上面对UPLL_MDIV_48与

UPLL_PSDIV_48的定义,可以看出MDIV=64,为什么要那样定义呢?

我们知道64是0x38,将其左移12位便是和UPLL寄存器定义的一样,那么UPLL_PSDIV_48则是PDIV和SDIV的组合,这样就构成了UPLL寄存器的值,然后我们计算一下,这里注意一点,UPLL与MPLL的计算公式不一样的(前提是2440,如果是2410那么两者是一样的)。

UPLL=((MIDV+8)*Fin)/((PDIV+2)*2SDIV)=48MHz。

所以要这样写。

同理MPLL与此类似,只是公式有点不一样,MPLL=(2*(MIDV+8)*Fin)/((PDIV+2)*2SDIV)=405MHz。

详细见S3C2440手册的235页第7部分“clock&powermanagement“。

注意这里并没有出现这两个公式,具体是在/cpu/arm920t/s3c24x0/speed.c函数中出现,这会在后面修改。

对于201行~217行的设置是对于没有定义S3C2440的例外情况,其方法与前面讲的类似,本可以不要的,这里加上方便以后移植。

再回过头来看175行,这里是为了设置INTSUBMSK寄存器,查看S3C2440手册395页可知,该寄存器15位可用且初始值都为1,所以赋值0x7fff。

接下去设置分频比,同样查看S3C2440手册246页的分频比设置,由表可知,1:

4:

8对应的HDIVN是2(占用CLKDIVN的[2:

1]),PDIVN是1(占用CLKDIVN的[0]),所以是0x5。

这就是对于这段修改的全部解析!

!

!

!

!

!

至于187行~189行的则是些约定俗成的语句,不解析了。

第三步:

现在跳出start.S函数,进入/cpu/arm920t/s3c24x0/interrupts.c函数。

这个函数是实现中断相关信息的。

改动之处1:

源代码如下:

33#ifdefined(CONFIG_S3C2400)||defined(CONFIG_S3C2410)||defined(CONFIG_TRAB)

34

35#include

36#ifdefined(CONFIG_S3C2400)

37#include

38#elifdefined(CONFIG_S3C2410)

39#include

40#endif

修改后的:

33#ifdefined(CONFIG_S3C2400)||defined(CONFIG_S3C2410)||defined(CONFIG_TRAB)||defined(CONFIG_S3C2440)

34

35#include

36#ifdefined(CONFIG_S3C2400)

37#include

38#elifdefined(CONFIG_S3C2410)||defined(CONFIG_S3C2440)

39#include

40#endif

这些就不细说了,两个改动是为了包含arm920t.h和s3c2410.h这两个头文件。

改动之处2:

源代码:

177#ifdefined(CONFIG_SMDK2400)||defined(CONFIG_TRAB)

178tbclk=timer_load_val*100;

179#elifdefined(CONFIG_SBC2410X)||\

180defined(CONFIG_SMDK2410)||\

181defined(CONFIG_VCMA9)

182tbclk=CFG_HZ;

183#else

改动之后:

177#ifdefined(CONFIG_SMDK2400)||defined(CONFIG_TRAB)

178tbclk=timer_load_val*100;

179#elifdefined(CONFIG_SBC2410X)||\

180defined(CONFIG_SMDK2410)||\

181defined(CONFIG_MINI2440)||\

182defined(CONFIG_VCMA9)

183tbclk=CFG_HZ;

184#else

第四步:

修改/cpu/arm920t/s3c24x0/speed.c函数,改动之处1:

源代码如下:

33#ifdefined(CONFIG_S3C2400)||defined(CONFIG_S3C2410)||defined(CONFIG_TRAB)

34

35#ifdefined(CONFIG_S3C2400)

36#include

37#elifdefined(CONFIG_S3C2410)

38#include

39#endif

修改之后如下:

f

33#ifdefined(CONFIG_S3C2400)||defined(CONFIG_S3C2410)||defined(CONFIG_S3C2440)||defined(CONFIG_TRAB)

34

35#ifdefined(CONFIG_S3C2400)

36#include

37#elifdefined(CONFIG_S3C2410)||defined(CONFIG_S3C2440)

38#include

39#endif

同样是添加定义支持2440,不解析了。

改动之处2:

便是我们上次提到修改MPLL与UPLL公式的地方。

源代码:

66m=((r&0xFF000)>>12)+8;

67p=((r&0x003F0)>>4)+2;

68s=r&0x3;

69

70return((CONFIG_SYS_CLK_FREQ*m)/(p<

上面代码仅仅支持2410的,所以我们要添加上2440的计算方法,改动如下:

66m=((r&0xFF000)>>12)+8;

67p=((r&0x003F0)>>4)+2;

68s=r&0x3;

69#ifdefined(CONFIG_S3C2440)

70if(pllreg==MPLL)

71return((CONFIG_SYS_CLK_FREQ*m*2)/(p<

72elseif(pllreg==UPLL)

73#endif

74return((CONFIG_SYS_CLK_FREQ*m)/(p<

上面66行、67行、68行的r是指MPLLCON(UPLLCON),m、p、s是根据我们S3C2440手册的238页的计算公式得来的,接下去的71行便是MPLL的频率计算公式。

你可能会问,那UPLL怎么没有公式呢?

那是有的,在74行便定义了。

因为它的计算与2410一样,就无需画蛇添足了!

由此可见,linux内核是相当简练的!

改动之处3:

在get_HCLK(void)函数内修改HCLK的计算,源代码:

82S3C24X0_CLOCK_POWER*constclk_power=S3C24X0_GetBase_CLOCK_POWER();

83

84return((clk_power->CLKDIVN&0x2)?

get_FCLK()/2:

get_FCLK());

这是仅仅针对2410的,所以我们要添加定义2440的,改动如下:

82S3C24X0_CLOCK_POWER*constclk_power=S3C24X0_GetBase_CLOCK_POWER();

83

84#ifdefined(CONFIG_S3C2440)

85if(clk_power->CLKDIVN&0x6)

86{

87if((clk_power->CLKDIVN&0x6)==2)

88return(get_FCLK()/2);

89if((clk_power->CLKDIVN&0x6)==6)

90return((clk_power->CAMDIVN&0x100)?

get_FCLK()/6:

get_FCLK()/3);

91if((clk_power->CLKDIVN&0x6)==4)

92return((clk_power->CAMDIVN&0x200)?

get_FCLK()/8:

get_FCLK()/4);

93return(get_FCLK());

94}

95elsereturn((clk_power->CLKDIVN&0x2)?

get_FCLK()/2:

get_FCLK());

96#endif

什么意思呢?

就是如果定义了S3C2440的话,如果CLKDIVN的[2:

1]不为0的话,那么进入判断语句中。

首先如果CLKDIVN与0x6位与等于2的话,就可以知道HCLK=FCLK/2,接下去的分析都是遵循S3C2440手册242页的一个表,这里转换成编程语言,你会发现这转换的技巧很经典!

最后是如果CLKDIVN的[2:

1]为0的话就执行另外

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 医药卫生 > 基础医学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1