好文档 - 专业文书写作范文服务资料分享网站

我的arm - linux移植笔记

天下 分享 时间: 加入收藏 我要投稿 点赞

一、 uboot 1.2.0移植

移植环境:VMware5.5.2+redhat9 开发板:SKY_2440B_V5.0或者V3.0

编译器:cross3.2(下载地址ftp://ftp.arm.linux.org.uk/pub/armlinux/toolchain/cross3.2.tar.gz) Uboot:u-boot-1.2.0(下载地址:ftp://ftp.denx.de/pub/u-boot/) 先说明一下,移植过程按照tekkaman的blog移植的。 博客地址http://blog.chinaunix.net/u1/34474/index.html。

其中uboot的移植参照http://blog.chinaunix.net/u1/34474/showart.php?id=397315做的。 所下面写的移植过程,很多都是从blog上copy过来的,有不同的地方,我会另外指出。

1.用dk登录linux主机,在dk下创建一个myboard文件夹 2.解压cross3.2:解压到/usr/local/arm/文件夹下

最好在/usr/local/arm/下创建一个3.2文件夹,把解压在arm文件夹下的文件(夹)全部移到3.2下,因为后面可能还会用到3.4.1的交叉编译器。 3.解压uboot:将uboot解压到myboard文件夹下

tar xzvf u-boot-1.2.0.tar.bz2 –C /home/dk/myboard/ 4.进入uboot目录,修改Makefile

cd u-boot-1.2.0 vi Makefile

(1) 新建我的编译项

在1923行,即smdk2410_config编译项之后增加我的编译项 tekkaman2440_config : unconfig

@$(MKCONFIG) $(@:_config=) arm arm920t tekkaman2440 tekkaman s3c24x0 各项的意思如下: arm: CPU的架构(ARCH)

arm920t: CPU的类型(CPU),其对应于cpu/arm920t子目录。

tekkaman2440: 开发板的型号(BOARD),对应于board/tekkaman/tekkaman2440目录。 tekkaman: 开发者/或经销商(vender)。 s3c24x0: 片上系统(SOC)。

(2) 修改交叉编译器路径,我用的cross3.2是在/usr/local/arm/ 修改128行

CROSS_COMPILE=/usr/local/arm/3.2/bin/arm-linux- 5.在/board子目录中建立自己的开发板tekkaman2440目录

由于我在上一步板子的开发者/或经销商(vender)中填了 tekkaman ,所以开发板tekkaman2440目录一定要建在/board子目录中的tekkaman目录下 ,否则编译会出错。

$cd board

$mkdir tekkaman tekkaman/tekkaman2440 $cp -arf sbc2410x/* tekkaman/tekkaman2440/ $cd tekkaman/tekkaman2440 $mv sbc2410x.c tekkaman2440.c

还要记得修改自己的开发板tekkaman2440目录下的Makefile文件,不然编译时会出错: $vi Makefile

1

COBJS := tekkaman2440.o flash.o 6.在include/configs/中建立配置头文件

$cp include/configs/sbc2410x.h include/configs/tekkaman2440.h 7.测试编译能否成功

$make tekkaman2440_config

Configuring for tekkaman2440 board... (如果出现:

$ make tekkaman2440_config

Makefile:1927: *** 遗漏分隔符 。 停止。 请在U-boot的根目录下的Makefile的

@$(MKCONFIG) $(@:_config=) arm arm920t tekkaman2440 tekkaman) 前加上“Tab”键) $make

到这一步应该能编译成功,但是我的并没有编译成功,提示/common/cmd_bootm.c文件的464行的U_BOOT_CMD有错误,我是把其中的从#ifdef CONFIG_OF_FLAT_TREE到#endif都屏蔽掉,这样就可以编译过去了。可能还会出现类似的问题,用同样的方法可以解决。

下面修改Uboot中的文件,以匹配开发板 8.修改/cpu/arm920t/start.S

这个函数是arm920t系列的共有启动的汇编代码,UBOOT执行的第一个程序 (0)修改寄存器地址定义

/* turn off the watchdog */ #if defined(CONFIG_S3C2400) # define pWTCON 0x15300000

# define INTMSK 0x14400008 /* Interupt-Controller base addresses */

# define CLKDIVN 0x14800014 /* clock divisor register */ #elif defined(CONFIG_S3C2410)|| defined(CONFIG_S3C2440) # define pWTCON 0x53000000这个定义了看门狗的寄存器地址

# define INTMSK 0x4A000008 /* Interupt-Controller base addresses */中断掩码的寄存器地址

# define INTSUBMSK 0x4A00001C中断掩码的寄存器地址

# define CLKDIVN 0x4C000014 /* clock divisor register */完成时钟分份的寄存器 #endif

(1)修改中断禁止部分 #if

defined(CONFIG_S3C2400)

||

defined(CONFIG_S3C2410)

||

defined(CONFIG_S3C2440)

ldr r0, =pWTCON把看门狗寄存器地址给了r0 mov r1, #0x0 r1等于0

str r1, [r0] 看门狗寄存器等于0 因为在启动时要关闭看门狗,不能让他产生中断影响启动,此时也根本不需要任何中断 /*

* mask all IRQs by setting all bits in the INTMR - default */

2

mov r1, #0xffffffff 关闭所有中断 ldr r0, =INTMSK str r1, [r0]

# if defined(CONFIG_S3C2410)

ldr r1, =0x7ff //根据2410芯片手册,INTSUBMSK有11位可用, //vivi也是0x7ff,不知为什么U-Boot一直没改过来。 ldr r0, =INTSUBMSK str r1, [r0] # endif

# if defined(CONFIG_S3C2440)

ldr r1, =0x7fff //根据2440芯片手册,INTSUBMSK有15位可用 ldr r0, =INTSUBMSK str r1, [r0] # endif

(2)修改时钟设置(2440的主频可达533MHz,但是我设到533MHz时系统很不稳定,不知是不是SDRAM和总线配置的影响,所以现在先设到405MHz,以后在改进。) ldr r0, =CLKDIVN

这个值决定了FCLK HCLK PCLK的频率 FCLK是供给CPU的 是主频

HCLK是供给AHB总线(主要用于高性能模块(如CPU、DMA和DSP等)之间的连接,作为SoC的片上系统总线)上的外围设备

PCLK是供给APB总线(APB主要用于低带宽的周边外设之间的连接,例如UART、1284等)上的外围设备

UCLK是两路PLL中一路供给USB的频率

ARM总线技术在这里我不多介绍了, 对硬件感兴趣的同学建议多多了解,我有一回面试人家就问我这个了,405MHZ已经很高了,基本都够了,2410的200MHZ就能播放Mplayer视频,据说很流畅。

mov r1, #5 /* FCLK:HCLK:PCLK = 1:4:8 */

str r1, [r0]

mrc p15, 0, r1, c1, c0, 0 /*read ctrl register tekkaman*/ orr r1, r1, #0xc0000000 /*Asynchronous tekkaman*/ mcr p15, 0, r1, c1, c0, 0 /*write ctrl register tekkaman*/

他是用到了协处理器P15,此处理器主要设置mmu,时钟模式,caches,保护模式的。先把C0 C1的值读出到r1,设置后再写回。 FCLK:HCLK:PCLK的比例由CLKDIVN决定的,CLKDIVN寄存器的HDIVN和PDIVN决定比例的大小。因为此时的HDIVH不为0,将快速总线模式改为异步总线模式,操作协处理器P15改变模式即可,如果HDIVH不为0,而且是快速总线模式的话,那么CPU的主频由hclk控制,这样可以实现不改变HCLK和PCLCK的同时就能使CPU的主频减半或更多。网上的大虾说没有以上几句主频会是12MHZ,我的观点不同。这是数据手册原文

If HDIVN is not 0 and the CPU bus mode is the fast bus mode, the CPU will operate by the HCLK.This feature can be used to change the CPU frequency as a half or more without affecting the HCLKand PCLK #if defined(CONFIG_S3C2440)

3

/*now, CPU clock is 405.00 Mhz tekkaman*/

mov r1, #CLK_CTL_BASE /* tekkaman*/这是时钟寄存器的基地址 mov r2, #MDIV_405 /* mpll_405mhz tekkaman*/ add r2, r2, #PSDIV_405 /* mpll_405mhz tekkaman*/ str r2, [r1, #0x04] /* MPLLCON tekkaman */设置 MPLLCON #endif

#if defined(CONFIG_S3C2410)

/*now, CPU clock is 202.8 Mhz tekkaman*/ mov r1, #CLK_CTL_BASE /* tekkaman*/

mov r2, #MDIV_200 /* mpll_200mhz tekkaman*/ add r2, r2, #PSDIV_200 /* mpll_200mhz tekkaman*/ str r2, [r1, #0x04] /* MPLLCON tekkaman */ #endif

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

红色部分是我添加的,利用vivi的代码,将其设为405.00MHz 并在前面加上: #elif defined(CONFIG_S3C2410) # define pWTCON 0x53000000

# define INTMSK 0x4A000008 /* Interupt-Controller base addresses */ # define INTSUBMSK 0x4A00001C

# define CLKDIVN 0x4C000014 /* clock divisor register */ #define CLK_CTL_BASE 0x4C000000 /* tekkaman */ #if defined(CONFIG_S3C2440)

#define MDIV_405 0x7f << 12 /* tekkaman */ #define PSDIV_405 0x21 /* tekkaman */ #endif

#if defined(CONFIG_S3C2410)

#define MDIV_200 0xa1 << 12 /* tekkaman */ #define PSDIV_200 0x31 /* tekkaman */ #endif #endif〕

(3)将从Flash启动改成从NAND Flash启动。(特别注意:这和2410的程序有不同,不可混用!!!是拷贝vivi的代码。)

将以下U-Boot的重定向语句段:

这段代码将uboot搬运到ram中,这个是没有存放在nand的情况,下面咱们来看一下不在nand启动和在nand启动时此处的区别。

#ifndef CONFIG_SKIP_RELOCATE_UBOOT relocate: /* relocate U-Boot to RAM */

adr r0, _start /* r0 <- current position of code */nor中的起始地址给了r0

ldr r1, _TEXT_BASE /* test if we run from flash or RAM */ram中的uboot代码的起始地址(这里关于uboot搬运这块在内存地址的部分,分了很多段,每一段空间具有不同功能,这是你理解uboot必须掌握的,非常关键,解释后续会提到些)

cmp r0, r1 /* don't reloc during debug */比较两个地址是否相同,不同则进行下面的搬运工作

4

beq stack_setup

在这里你会发现搬运了全部uboot,有的uboot把uboot的c部分搬运到内存_TEXT_BASE里面所放的地址处。

ldr r2, _armboot_start ldr r3, _bss_start

sub r2, r3, r2 /* r2 <- size of armboot */ _bss_start-_armboot_start= armboot 因为_armboot_end的结束位置就是bss区的开始位置所以能计算出uboot代码的大小 add r2, r0, r2 /* r2 <- source end address */

以下就是把整个代码搬运到_TEXT_BASE里面所放的地址处,记住是内存地址,哈哈!! copy_loop:

ldmia r0!, {r3-r10} /* copy from source address [r0] */ stmia r1!, {r3-r10} /* copy to target address [r1] */ cmp r0, r2 /* until source end addreee [r2] */ ble copy_loop

#endif /* CONFIG_SKIP_RELOCATE_UBOOT */

替换成:因为nand和nor的启动是有区别的,NOR Flash储存器较贵,而NAND Flash则相对便宜,所以很多用户选择在NAND Flash中执行启动代码,在SDRAM中执行主程序。为支持NAND Flash的BootLader,S3C2440有一个内部SRAM缓冲,称为‘Steppingstone’,启动时,NAND Flash的最先4K字节将被装载到Steppingstone中,装载到Steppingstone中的启动代码将执行。这都是硬件自动完成的不需要咱们软件参与。一般来说,启动代码将把NAND Flash的内容拷贝到SDRAM中,ECC将检测NAND的合法性,当拷贝完成时,主程序将在SDRAM中执行电源开启后,或系统重启后,NAND Flash控制器将自动装载4KB的BootLoader代码,载入代码后将执行。注意在自启动时,ECC不检测,因此,NAND Flash的头4KB要保证无错,下面我来带你分析它的源代码喽,嘿嘿!!!!忽然想家了,对了nand的硬件连接简单有兴趣的看一下了(NCON-Adv Flash,GPG13-Page size,GPG14-Address cycle,GPG15-总线宽度)

#ifdef CONFIG_S3C2440_NAND_BOOT @tekkaman@ 在以后会定义它的,不要忘了 @ reset NAND

mov r1, #NAND_CTL_BASE nand的寄存器基地址

ldr r2, =( (7<<12)|(7<<8)|(7<<4)|(0<<0) ) CLE & ALE期间设置值|TWRPH0 期间设置值|TWRPH0 期间设置值|8位总线

str r2, [r1, #oNFCONF] 设置NFCONF寄存器,初始化作用 ldr r2, [r1, #oNFCONF]

ldr r2, =( (1<<4)|(0<<1)|(1<<0) ) @ Active low CE Control初始化ECC解码/编码器(只写)

|强制拉低nFCE(允许片选)|允许NAND控制器

str r2, [r1, #oNFCONT] 设置 NFCONT ldr r2, [r1, #oNFCONT]

ldr r2, =(0x6) @ RnB Clear和nand is busy str r2, [r1, #oNFSTAT] ldr r2, [r1, #oNFSTAT]

mov r2, #0xff @ RESET command

5

我的arm - linux移植笔记

一、uboot1.2.0移植移植环境:VMware5.5.2+redhat9开发板:SKY_2440B_V5.0或者V3.0编译器:cross3.2(下载地址ftp://ftp.arm.linux.org.uk/pub/armlinux/toolchain/cross3.2.tar.gz)Uboot:u-boot-1.2.0(下载地址:ftp://ft
推荐度:
点击下载文档文档为doc格式
3q3ea97wu606i7k4fy2m
领取福利

微信扫码领取福利

微信扫码分享