u-boot移植之三 uboot-2015.04的移植过程

1. 生成mini2440的文件,并修改对应的Kconfig
(1)将smdk2410特有的文件拷贝到一个以mini2440命令的副本。(注:使用find查看smdk2410相关文件并修改为mini2440)
(1.1)cp configs/smdk2410_defconfig configs/mini2440_defconfig
并修改CONFIG_TARGET_SMDK2410为CONFIG_TARGET_MINI2440
(1.2)cp include/configs/smdk2410.h include/configs/mini2440.h
暂时只修改部分内容,剩余的在其他功能中说明修改。
(1.2.1)修改配制宏
//#define CONFIG_S3C2410 /* specifically a SAMSUNG S3C2410 SoC */
//#define CONFIG_SMDK2410 /* on a SAMSUNG SMDK2410 Board */
#define CONFIG_S3C2440 /* specifically a SAMSUNG S3C2440 SoC */
#define CONFIG_MINI2440 /* on a FriendlyArm mini2440 Board */
(1.2.2)CONFIG_SYS_PROMPT修改为"mini2440 # ",实质是uboot命令行。
(1.2.3)删除CONFIG_ENV_IS_IN_FLASH的宏定义,并添加语句define CONFIG_ENV_IS_IN_NAND
(1.2.3)CONFIG_SYS_TEXT_BASE修改为0x33f00000(有问题稍后说明),是uboot链接的时候的基地址。
(1.3)cp board/samsung/smdk2410/ board/samsung/mini2440 -rf
(1.3.1)board/samsung/mini2440/Kconfig
把smdk2410相关内容都改成mini2440
(1.3.2)board/samsung/mini2440/lowlevel_init.S稍后修改
(1.3.3)board/samsung/mini2440/MAINTAINERS
暂时不清楚其作用,照样子把smdk2410相关内容都改成mini2440
(1.3.4)board/samsung/mini2440/Makefile
修改obj-y为mini2440.o
(1.4)mv board/samsung/mini2440/smdk2410.c board/samsung/mini2440/mini2440.c
修改MACH_TYPE_SMDK2410为MACH_TYPE_MINI2440
最新的u-boot-2015.04有关于MACH_TYPE_MINI2440的定义,这里不用重复定义了。
(2)"grep smdk2410 * -r"搜索smdk2410相关内容,并根据其更改mini2440相关。
(2.1)machine_is_smdk2410未使用,忽略处理。
(2.2)arch/arm/Kconfig
首先,在TARGET_SMDK2410配置项后增加MINI2440的配置项
config TARGET_MINI2440
bool "Support mini2440"
select CPU_ARM920T
然后source "board/samsung/smdk2410/Kconfig"这句话后面加上如下语句:
source "board/samsung/mini240/Kconfig"


2. 修改源文件
按照启动的顺序进行修改,一般代码添加在原有S3C2410代码的后面,后面不再说明功能位置。
(1)arch/arm/cpu/arm920t/start.S
(1.1)在原来配置看门狗,时钟分频寄存器的位置添加S3C2440的代码
#elif defined(CONFIG_S3C2440)
# define pWTCON 0x53000000
# define INTMSK 0x4A000008
# define INTSUBMSK 0x4A00001C
# define CLKDIVN 0x4C000014
# define MPLLCON 0x4C000004
# define UPLLCON 0x4C000008

(1.2)添加S3C2440关中断代码
# if defined(CONFIG_S3C2440)
ldr r1, =0x7fff
ldr r0, =INTSUBMSK
str r1, [r0]
# endif

(1.3)修改lowlevel_init代码
指定位置修改为如下信息
#define B1_BWSCON   (DW16)
#define B3_BWSCON   (DW16 + UBLB)
#define B4_BWSCON   (DW16 + WAIT + UBLB)
#define B5_BWSCON   (DW8)
#define B4_Tcos 0x3 /*  4clk */
#define B4_Tcoh 0x1 /*  1clk */
#define B4_Tah 0x3 /*  4clk */
#define B4_Tacp 0x6 /*  6clk */
#define REFCNT 0x4f4 /* period=7.8125, HCLK=100Mhz, (2048+1-7.8125*100) */
倒数第三行修改为.word 0xb1


(1.4)修改board_early_init_f函数
board_early_init_f在board/samsung/mini2440/board_f.c中。
首先增加转为异步模式的代码
__asm__( "mrc p15, 0, r1, c1, c0, 0\n" /* read ctrl register */
"orr r1, r1, #0xc0000000\n" /* Asynchronous */
"mcr p15, 0, r1, c1, c0, 0\n" /* write ctrl register */
:::"r1"
);
然后修改时钟相关寄存器的值
#define S3C2440_MPLL_200MHZ     ((0x5c<<12)|(0x04<<4)|(0x01))
#define S3C2440_UPLL_48MHZ      ((0x28<<12)|(0x01<<4)|(0x03))
#define S3C2440_CLKDIV          0x03    /* FCLK:HCLK:PCLK = 1:2:4 */

(1.5)修改include/configs/mini2440.h网卡信息
#define CONFIG_DRIVER_DM9000 1
#define CONFIG_DM9000_USE_16BIT 1
#define CONFIG_DM9000_BASE 0x20000000 //网卡在BANK4上,地址是0x20000000
#define DM9000_IO 0x20000000  
#define DM9000_DATA 0x20000004

3. 配置
make smdk2410_defconfig

4. 编译生成uboot
4.1编译
修改主Makefile,增加如下语句
CROSS_COMPILE:= arm-linux- 
ARCH := arm
然后执行make all
4.1 u-boot环境变量的设置
提示需要定义CONFIG_ENV_OFFSET
这里增加两个宏如下:
#define CONFIG_ENV_SIZE 0x50000
#define CONFIG_ENV_OFFSET 0x100000
并修改CONFIG_ENV_ADDR如下:
#define CONFIG_ENV_ADDR (CONFIG_SYS_FLASH_BASE + CONFIG_ENV_OFFSET)
环境变量的配置参数设置于nand的0x100000地址,长度为0x20000。
这里规定:
uboot存放在0x0-0x100000地址处。
环境变量放在0x100000-0x150000地址处。
0x150000-0x550000放置linux内核,即0x150000开始的4M空间。
同时加入如下环境变量,作为启动参数和mtd文件系统挂载的参数等
#define CONFIG_BOOTCOMMAND "nand read.jffs2 0x30007FC0 0x140000 0x400000; bootm 0x30007FC0"
#define CONFIG_BOOTARGS "mtdparts=nandflash0:1M(uboot)ro,256K(env),5M(kernel)ro,-(rootfs) root=/dev/mtdblock3 rw rootfstype=jffs2"

4.2 u-boot.lds语法错误
编译出现了u-boot.lds语法错误,根据前面分析主目录的arch/arm/cpu/u-boot.lds拷贝过来,开头包含了config.h,其中在config.h中包含的内容中有一个mini2440.h,而主目录的的错误信息恰巧就是mini2440.h中以//开头注释的行(笔者之前修改的源代码都用//注释并未删除),这里删除后重新编译。
这时候编译已经成功了,可以得到u-boot.bin
4.3 nandflash移植
回头看一下mini2440.h,还有nandflash部分没有修改,仍然是2410的代码。
搜索CONFIG_NAND_S3C2410,发现在drivers/mtd/nand/s3c2410_nand.c有关于2410的
(1)cp drivers/mtd/nand/s3c2410_nand.c drivers/mtd/nand/s3c2440_nand.c
(2)并在drivers/mtd/nand/Makefle中增加如下语句:
obj-$(CONFIG_NAND_S3C2440) += s3c2440_nand.o
(3)修改s3c2440_nand.c
(3.1)board_nand_init函数
将2410部分代码删掉,并将修改寄存器的代码和nand_chip代码改为如下内容:
#if defined(CONFIG_S3C2440)
#define TACLS 2
#define TWRPH0 1
#define TWRPH1 0
#define BusWidth 0
nand_reg->nfconf =  (BusWidth<<0) | (TWRPH1<<4) | (TWRPH0<<8) | (TACLS<<12);
nand_reg->nfcont &= ~((1<<4) | (1<<1) | (1<<0)) ;
nand_reg->nfcont |= ((1<<4) | (0<<1) | (1<<0));
nand->IO_ADDR_R = (void *)&nand_reg->nfdata;
nand->IO_ADDR_W = (void *)&nand_reg->nfdata;
nand->select_chip = NULL;
nand->cmd_ctrl = s3c24x0_hwcontrol;
nand->dev_ready = s3c24x0_dev_ready;
nand->options   = 0; //8-bit 
nand->ecc.mode = NAND_ECC_SOFT;
#endif
(3.2)s3c24x0_hwcontrol
这里简单分析下该函数,由于2410的函数是已经有的,按照这个分析,2440照着改便可以。值得注意的是该函数中IO_ADDR_W是是一个指针,对它进行或运算,实质就是加法,更换寄存器。这里只要把ctrl变量用NAND_CLE或NAND_ALE代替,IO_ADDR_W就自然定位到指定的寄存器。
处理ctrl那些if语句删掉,修改为如下格式
if(ctrl & NAND_CLE)
{
IO_ADDR_W = 0x4E000008;
}
else if(ctrl & NAND_ALE)
{
IO_ADDR_W = 0x4E00000C;
}
else
{
IO_ADDR_W = 0x4E000010;
}
由于2410与2440的片选信号的寄存器位置不同,修改代码如下:
#define S3C2440_NFCONF_nFCE (1<<1)
if (ctrl & NAND_NCE)
writel(readl(&nand->nfcont) & ~S3C2440_NFCONF_nFCE,
  &nand->nfconf);
else
writel(readl(&nand->nfcont) | S3C2440_NFCONF_nFCE,
  &nand->nfconf);


4.4 增加启动参数
#define CONFIG_BOOTCOMMAND "nand read.jffs2 0x30007FC0 0x150000 0x400000; bootm 0x30007FC0"

4.5 uboot命令的配置
u-boot-1.1.6版本命令是在CONFIG_COMMANDS宏定义的,但是在u-boot-2015.04模范的linux的Kconfig,是在Kconfig中配置的。

5. openjtag调试
下载到nandflash中,无反应,因此需要使用openjtag调试,查看问题,同时需要得到反汇编文件u-boot.dis作为调试使用。
需要在主Makefile的All-y的定义处增加u-boot.dis
5.1 问题之nandfalsh程序未拷贝到SDRAM中
经过jlink调试发现lowlevel_init处异常,用jlink命令mem 0 1010查看发现原因是超过4K内存了,超过4K内存的部分不能再steppingstone中使用。
所以需要把lowlevel_init的链接地址放在4K地址空间内,然后添加或修改把nandflash的数据拷贝到sdram的代码。
5.1.1将lowlevel_init移到4K地址空间内。
arch/arm/cpu/u-boot.lds中在start.o后增加如下内容:
board/samsung/mini2440/lowlevel_init.o (.text*)
并在board/samsung/mini2440/Makefile中lowlevel_init.o前面的内容修改为extra-y,防止编译入built-in.o使lowlevel_init.o多次链接。
5.1.2增加拷贝NANDFLASH程序到SDRAM的代码
新增加的代码放在board\samsung\mini2440\mni2440_init.c中,因为与之前的裸机操作时钟和NANDFLASH代码基本一致,这里不再粘贴。
同时在board\samsung\mini2440\Makefile增加如下代码:
extra-y += mini2440_init.o
注:这里使用extra-y,而不是使用obj-y。因为obj-y会编译到built-in.o,而后面u-boot.lds有会加入mini2440_init.o,所以会提示多次定义错误。
为了保证mini2440_init.o在4K之前内,需要在arch/arm/cpu/u-boot.lds中"CPUDIR/start.o (.text*)"下一行增加如下代码:
board\samsung\mini2440\mni2440_init.o (.text*)
为了把NANDFLASH代码移植到SDRAM中,需要保证时钟和存储控制器正确初始化,并增加适当的nandflash处理函数。
其中,控制器初始化在cpu_init_crit完成。因此需要增加一个时钟的初始化。
另外需要考虑的是堆栈空间,这里设置4K内存处为堆栈栈顶,因此实际能用的内存是不到4K的。
    然后通过ldr pc, =afterCopyCode2Ram字节跳到SDRAM中执行。
在之前加上另外一段代码,判断当前是否已经在SDRAM中。
注:adr r0, my_copy与ldr r2,my_copy区别在于adr寻址范围小,如果在SDRAM中,r0会得到链接地址,在stepping stone则为0。使用ldr则r2一定为链接地址。
注意:在u-boot-1.6中使用了_start编号判断是否在SDRAM中,这里使用该标号的时候编译不通过,可能是因为超越了adr的寻址范围,这里选择就近的编号my_copy来判断是否已经运行在SDRAM中。
在cpu_init_crit前增加代码如下:
ldr sp,=0x1000
bl clock_init
因此, 在arch/arm/cpu/arm920t/start.S的"bl _main"前增加这样一段代码:
my_copy:
adr r0, my_copy
ldr r1,=my_copy
cmp r0,r1
beq afterCopyCode2Ram
mov r0,#0
ldr r1,=CONFIG_SYS_TEXT_BASE
ldr r2,=_start
ldr r3,=_end
sub r2, r3, r2
bl copyCode2Ram
afterCopyCode2Ram:
ldr pc, =afterCopyCode2Ram
注:尽管relocate.S里面已经有了重定位代码,但是这里还是有一步重定位判断,是因为该u-boot重定位代码之前调用了board_init_f,已经超出了4K地址空间,并且该函数用到的空间过大,不便于移到4K地址空间内。

5.2 问题之内存区域重叠
在board_init_f中调用了init_sequence_f函数指针指向的一组函数。其中,最后一个是jump_to_copy,简单观察上下文初步认定该版本的u-boot会把自己加载到CONFIG_SYS_TEXT_BASE指向的地址,然后将起移到内存区的地址最高端。这里CONFIG_SYS_TEXT_BASE为0x33f00000,uboot.bin长度达到了549.5K,这里拷贝的内存区的源地址和目的地址有地址重叠区域。这里将CONFIG_SYS_TEXT_BASE修改为0x32000000。

5.3 nand命令失败
uboot启动已经可以正常启动,而使用nand系列的命令的时候会出现“no devices available”的提示。
经过调试定位,发现是nand_scan=> nand_scan_ident =>nand_get_flash_type返回值异常。这个函数大量调用了nand_chip的指针函数,回想之前增加的s3c2440_nand.c代码,应该是这个函数出现了问题。
经过检查是s3c24x0_hwcontrol函数写寄存器的时候writel第三个参数忘记改会来了。

5.4 uboot参数地址的设置
修改过后,nandflash可以正常操作了,但是后来无法启动,是因为之前无法读取nandflash的uboot参数,所以使用自动的参数。
追踪发现uboot是以块为单位处理uboot参数的,一个块大小是0x20000,而之前设置的uboot为0x50000(即CONFIG_ENV_SIZE),这里改为0x40000. 
至此,nandflash空间调整如下:
0 - 0x100000 1M u-boot
0x100000 - 0x140000 256K u-boot环境参数
0x140000 - 0x540000 4M linux内核
0x540000 - 最后 文件系统

5.5 网卡驱动的移植
在include/configs/mini2440.h中删除CS8900网卡的宏定义,然后添加如如下定义
#define CONFIG_DRIVER_DM9000 1
#define CONFIG_DM9000_USE_16BIT 1
#define CONFIG_DM9000_BASE 0x20000000 /*网卡在BANK4上,地址是0x20000000*/
#define DM9000_IO 0x20000000  
#define DM9000_DATA 0x20000004

5.6 网络功能异常
进入uboot命令模式下执行tftp或ping命令,发现没有网卡,有这样的警告信息"No ethernet found"
发现是没有增加CONFIG_CMD_NET,导致board_init_r中部分网络功能的函数没有被加入.把CONFIG_CMD_NET宏定义加入到include/configs/mini2440.h中.尽管新的网络初始化工作已经加入,但是仍然是"No ethernet found". 继续追踪发现是board/samsung/mini2440/mini2440.c中board_eth_init函数的代码还没有写如DM9000的代码,加入一条"rc = dm9000_initialize(NULL);"即可. 这样uboot就可以正常使用网络功能了.

5.7 nand write功能失败
分析了好久原因,原来是未擦出就直接写导致的.首先执行nand erase命令再执行nand write即可.

至此,u-boot-2015.04移植全部完成







  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值