移植u-boot-2014.10-rc3到TQ2440开发板过程记录

备注:参考了《u-boot-2014.04移植手册(TQ2440)》,将具体移植过程记录下来。目前仅能够从Nor Flash启动u-boot,无法从Nand Flash启动,以后再解决。

一、建立自己的开发板

1.1获取并解压u-boot源代码

从官网http://ftp.denx.de/pub/u-boot/下载u-boot-2014.10-rc3.tar.bz2,保存到/opt/u-boot/目录下。

(1)解压源代码:

$ tar xvf u-boot-2014.10-rc3.tar.bz2

$ cd u-boot-2014.10-rc3/

(2)使用S3C2410_defconfig配置文件验证编译环境是否配置正确:

make clean 

make smdk2410_defconfig 

make CROSS_COMPILE=arm-linux-

移植u-boot-2014.10-rc3到TQ2440开发板过程记录_第1张图片

(3)解决” include/linux/compiler-gcc.h:114:30: fatal error: linux/compiler-gcc6.h: No such file or directory”错误

       拷贝该目录下的compiler-gcc4.h,重命名为compiler-gcc6.h

$ cp include/linux/compiler-gcc4.h include/linux/compiler-gcc6.h

(4)解决” arch/arm/lib/board.c:67:6: error: 'coloured_LED_init' aliased to external symbol '__coloured_LED_init'”错误

       编辑该文件

$ gedit arch/arm/lib/board.c

LED的开关控制函数定义为了虚函数,需要用户自己实现。这里我们先注释掉所有虚函数的声明,往后再来添加。

移植u-boot-2014.10-rc3到TQ2440开发板过程记录_第2张图片

同时注释掉相应的函数调用语句:

$ gedit arch/arm/lib/crt0.S

(5)解决“arm-linux-ld.bfd: u-boot: Not enough room for program headers, try linking with -N”错误

修改顶层Makefile文件,在LDFLAGS_u-boot += $(LDFLAGS_FINAL)下一行插入:LDFLAGS_u-boot += $(call ld-option, --no-dynamic-linker),保存修改之后重新编译。

       (6)至此,编译环境配置完成

移植u-boot-2014.10-rc3到TQ2440开发板过程记录_第3张图片

1.2建立自己的开发板

(1)建立板卡支持文件夹

  1. 建立板卡支持文件夹tq2440:

$ cp -a board/samsung/smdk2410/ board/samsung/tq2440

  1. 修改该目录下的Makefile文件,指定编译目标为smdk2440.o:

$ gedit board/samsung/tq2440/Makefile

  1. 修改该目录下的Kconfig文件,指定配置选项:

$ gedit board/samsung/tq2440/Kconfig

移植u-boot-2014.10-rc3到TQ2440开发板过程记录_第4张图片

  1. 修改arch/arm/Kconfig文件,手动添加TQ2440的配置项并指定配置文件所在路径:

$ gedit arch/arm/Kconfig

添加:

config TARGET_SMDK2440

       bool "Support smdk2440"

添加:

source "board/samsung/tq2440/Kconfig"

  1. 修改该目录下的MAINTAINERS文件,指定工程结构:

$ gedit board/samsung/tq2440/MAINTAINERS

移植u-boot-2014.10-rc3到TQ2440开发板过程记录_第5张图片

  1. 修改该目录下的lowlevel_init.S文件,将其中所有2410替换为2440。

$ gedit board/samsung/tq2440/lowlevel_init.S

  1. 重命名板卡配置文件为smdk2440.c文件:

$ mv board/samsung/tq2440/smdk2410.c board/samsung/tq2440/smdk2440.c

       修改该目录下的smdk2440.c文件:

$ gedit board/samsung/tq2440/smdk2440.c

修改int board_init(void)函数,将机器识别码修改为MACH_TYPE_SMDK2440。

使用grep "MACH_TYPE_SMDK2410" * -nR查找机器识别码定义:

       可以看到该识别码在arch/arm/include/asm/mach-types.h中定义。

  1. 修改机器识别码头文件:

$ gedit arch/arm/include/asm/mach-types.h

       参考2410开发板添加:

#ifdef CONFIG_ARCH_SMDK2440

# ifdef machine_arch_type

#  undef machine_arch_type

#  define machine_arch_type      __machine_arch_type

# else

#  define machine_arch_type      MACH_TYPE_SMDK2440

# endif

# define machine_is_smdk2440() (machine_arch_type == MACH_TYPE_SMDK2440)

#else

# define machine_is_smdk2440() (0)

#endif

       移植u-boot-2014.10-rc3到TQ2440开发板过程记录_第6张图片

参考MACH_TYPE_SMDK2410,添加SMDK2440开发板的识别码为168。添加:

#define MACH_TYPE_SMDK2440             168

(2)建立板卡配置头文件

$ cp include/configs/smdk2410.h include/configs/smdk2440.h

修改该smdk2440.h配置头文件,将其中的2410替换为2440:

$ gedit include/configs/smdk2440.h

       指定命令行提示符为TQ2440

(3)建立默认配置文件

$ cp configs/smdk2410_defconfig configs/smdk2440_defconfig

编辑该文件,将其中的SMDK2410替换为SMDK2440

$ gedit configs/smdk2440_defconfig

(4)拷贝nand flash操作源文件,将其中所有2410替换为2440:

$ cp drivers/mtd/nand/s3c2410_nand.c drivers/mtd/nand/s3c2440_nand.c

$ gedit drivers/mtd/nand/s3c2440_nand.c

(5)修改同级Makefile,将该文件添加到编译选项中

$ gedit drivers/mtd/nand/Makefile

添加一行:

obj-$(CONFIG_NAND_S3C2440) += s3c2440_nand.o

1.3建立自动编译脚本

在u-boot根目录下创建一个auto-run.sh脚本文件,用于自动执行编译过程

$ gedit auto_run.sh

脚本内容如下:

#!/bin/bash  

 

echo "Clean Configuration File..."  

make distclean  

 

echo "Clean Obj..."  

make clean  

 

echo "Load Configuration File..."  

make smdk2440_defconfig  

 

echo "make..."  

make CROSS_COMPILE=arm-linux-

 

echo "Copy to TFTP Folder...."

cp /opt/u-boot/u-boot-2014.10-rc3/u-boot.bin /opt/TFTP/u-boot.bin

为该文件添加执行权限:

$ sudo chmod +x auto_run.sh

       修改目录所有者:

$ sudo chown -R tq2440:root /opt/

执行编译

$./auto_run.sh

1.7使用JLink烧写生成的u-boot.bin文件

u-boot默认支持Nor Flash启动,编译生成的u-boot.bin文件位于u-boot根目录下,使用JLink烧写到Nor Flash的0地址中,打开串口终端发现没有任何输出信息,说明u-boot未启动。

二、配置时钟和SDRAM寄存器

2.1开启u-boot指令自动补齐

$ gedit include/configs/smdk2440.h

在开头添加:

#define CONFIG_AUTO_COMPLETE      /* 开启命令自动补全 */

2.2暂时裁剪用不到的u-boot指令

用#if 0和#endif对暂时屏蔽一些不需要的命令行支持,后面再加上:

移植u-boot-2014.10-rc3到TQ2440开发板过程记录_第7张图片

移植u-boot-2014.10-rc3到TQ2440开发板过程记录_第8张图片

移植u-boot-2014.10-rc3到TQ2440开发板过程记录_第9张图片

移植u-boot-2014.10-rc3到TQ2440开发板过程记录_第10张图片

2.3修改底层时钟初始化代码

根据根目录下生成的链接脚本arch/arm/cpu/u-boot.lds可知,u-boot 执行的第一个文件是arch/arm/cpu/arm920t/start.S,底层时钟初始化代码就在这个文件中。

$ gedit arch/arm/cpu/arm920t/start.S

在/* FCLK:HCLK:PCLK = 1:2:4 */上一行插入S3C2440时钟初始化代码:

# if defined(CONFIG_S3C2440)

       ldr r1, =0x7fff

       ldr r0, =INTSUBMSK /*  屏蔽子中断 */

       str r1, [r0]

# endif /* CONFIG_S3C2440 */

# if defined(CONFIG_S3C2440)

       # define MPLLCON 0x4C000004 /* 系统主频配置寄存器 */

       # define UPLLCON 0x4C000008 /* USB 频率配置寄存器 */

       # define CAMDIVN 0x4C000018 /* 照相机时钟分频寄存器 */

       ldr r0, =CAMDIVN

       mov r1, #0

       str r1, [r0]

       ldr r0, =CLKDIVN

       mov r1, #0x05

       str r1, [r0]

       /*如果HDIVN 不等于0CPU 必须设置为异步总线模式*/

       mrc p15,0,r0,c1,c0,0

       orr r0,r0,#0xc0000000

       mcr p15,0,r0,c1,c0,0

       ldr r0, =UPLLCON

       ldr r1, =0x38022 /*  USB 时钟48MHZ */

       str r1, [r0]

       /*

       **When you set MPLL&UPLL values, you have to set the UPLL

       **value first and then the MPLL value. (Needs intervals

       **approximately 7 NOP)

       */

       nop

       nop

       nop

       nop

       nop

       nop

       nop

       ldr r0, =MPLLCON

       ldr r1, =0x5c011 /* CPU 时钟400MHZ */

       str r1, [r0]

# else

在#endif /* CONFIG_S3C24X0 */上一行插入#endif /* CONFIG_S3C2440 */,和前面插入的#if CONFIG_S3C2440配对。

移植u-boot-2014.10-rc3到TQ2440开发板过程记录_第11张图片

2.4屏蔽高层时钟初始化代码

在board/samsung/tq2440/smdk2440.c中board_early_init_f()函数也初始化了时钟,在start.S 中已完成了时钟初始化操作,所以屏蔽掉board_early_init_f()中对时钟的初始化代码

$ gedit board/samsung/tq2440/smdk2440.c

屏蔽相关代码,注意保留gpio初始化代码。

移植u-boot-2014.10-rc3到TQ2440开发板过程记录_第12张图片

2.5跳过底层初始化函数以便烧录到SDRAM运行

(1)烧录到SDRAM为什么需要屏蔽底层初始化函数

由于u-boot的底层初始化代码还未移植,所以我们将u-boot直接烧写到内存中运行,则需要在第一阶段启动过程中跳过底层初始化代码。在arch/arm/cpu/arm920t/start.S文件中发现如下代码:

#ifndef CONFIG_SKIP_LOWLEVEL_INIT

bl cpu_init_crit

#endif

也就是说如果没有定义CONFIG_SKIP_LOWLEVEL_INIT,底层函数会跳转cpu_init_crit 函数执行,该函数进行了一些底层初始化操作(比如内存)。而调试阶段目标代码在内存中运行,如果再初始化一次内存,可能导致内存中的数据被破坏。所以需要跳过底层初始化操作。

(2)修改u-boot.bin的链接地址

$ gedit include/configs/smdk2440.h

将#define CONFIG_SYS_TEXT_BASE 0修改为#define CONFIG_SYS_TEXT_BASE 0x32000000,则利用官方u-boot自带的TFTP功能将新编译生成的u-boot.bin下载至0x3200000进行调试。

(3)跳过底层初始化代码

在上面文件中定义CONFIG_SKIP_LOWLEVEL_INIT宏

#define CONFIG_SKIP_LOWLEVEL_INIT     /* 跳过底层初始化 */

2.6使用TFTP功能下载和烧录镜像

从Nor Flash启动开发板,并打开串口调试终端:

移植u-boot-2014.10-rc3到TQ2440开发板过程记录_第13张图片

(1)进行网络连接设置

  1. 用网线连接开发板与宿主机物理网卡;
  2. 设置宿主机物理网卡:IP为192.168.1.1,子网掩码为255.255.255.0,网关为192.168.1.1;
  3. 设置虚拟机(TFTP服务器) 连接方式为桥接模式(指定网卡为物理机网卡),IP为192.168.1.10,子网掩码为255.255.255.0,网关为192.168.1.1;
  4. 按5配置开发板TFTP下载相关信息:TFTP服务器IP为192.168.1.10,IP为192.168.1.11,子网掩码为255.255.255.0,网关为192.168.1.1;

移植u-boot-2014.10-rc3到TQ2440开发板过程记录_第14张图片

(2)测试网络连通性

保存环境变量后,多出一个[p] Test network (TQ2440 Ping PC's IP)  选项,根据提示按’p’,连接TFTP服务器成功。

移植u-boot-2014.10-rc3到TQ2440开发板过程记录_第15张图片

(3)从TFTP服务器下载镜像并烧录到SDRAM中

连按两次’q’进入命令行模式,输入tftp 0x32000000 u-boot.bin下载该镜像到SDRAM中。

移植u-boot-2014.10-rc3到TQ2440开发板过程记录_第16张图片

输入go 0x32000000启动SDRAM中的u-boot:

移植u-boot-2014.10-rc3到TQ2440开发板过程记录_第17张图片

2.7修改SDRAM寄存器定义

$ gedit board/samsung/tq2440/lowlevel_init.S

根据S3C2440芯片手册,修改最后一段中13个SDRAM寄存器定义代码为:

SMRDATA:

    .long 0x22011110 @ BWSCON

    .long 0x00000700 @ BANKCON0

    .long 0x00000700 @ BANKCON1

    .long 0x00000700 @ BANKCON2

    .long 0x00000700 @ BANKCON3

    .long 0x00000700 @ BANKCON4

    .long 0x00000700 @ BANKCON5

    .long 0x00018005 @ BANKCON6

    .long 0x00018005 @ BANKCON7

    .long 0x008C07A3 @ REFRESH

    .long 0x000000B1 @ BANKSIZE

    .long 0x00000030 @ MRSRB6

    .long 0x00000030 @ MRSRB7

 

2.8解决SDRAM拷贝代码卡死问题

发现u-boot启动卡死了,打开DEBUG查看详细启动信息:

$ gedit include/configs/smdk2440.h

(1)在开头插入DEBUG宏查看详细调试信息:

#define DEBUG /* 查看详细的调试信息 */

(2)重新编译生成u-boot.bin文件后,重启u-boot,连按两次’q’键进入命令行模式,执行tftp 0x32000000 u-boot.bin;go 0x32000000查看详细的启动信息

移植u-boot-2014.10-rc3到TQ2440开发板过程记录_第18张图片

使用$ grep "Now running in RAM - U-Boot at" * -nR指令发现,问题定位在board.c 中的board_init_r 在调用mem_malloc_init 函数时出现问题。mem_malloc_init完成对操作是将malloc_start 标识的malloc 区域清零,这里malloc 区域的大小是4MB+160KB,发现在清除到2MB 多的时候程序就挂了,故将malloc 区域的大小减小为2MB+160KB。

$ gedit include/configs/smdk2440.h

修改#define CONFIG_SYS_MALLOC_LEN (4 * 1024 * 1024)为#define CONFIG_SYS_MALLOC_LEN (2 * 1024 * 1024)

(3)重新编译生成u-boot.bin文件后,重启u-boot,连按两次’q’键进入命令行模式,执行tftp 0x32000000 u-boot.bin;go 0x32000000查看详细的启动信息

移植u-boot-2014.10-rc3到TQ2440开发板过程记录_第19张图片

从输出信息来看,u-boot已经探测到开发板的flash 的厂家ID 为0x1c,设备ID 为0x2249。但执行到flash:…后就出现了### ERROR ### Please RESET the board ###,说明Nor Flash不被u-boot支持。

三、添加Nor Flah支持

3.1查找u-boot不支持Nor Flash的原因

$ grep "Flash:" * -nR

移植u-boot-2014.10-rc3到TQ2440开发板过程记录_第20张图片

问题出在arch/arm/lib/board.c中,打看该文件查看:

$ gedit arch/arm/lib/board.c

failed字符串为一个宏定义

从宏开关来看是没找到FLASH(CONFIG_SYS_NO_FLASH),之后便进入到hang()函数中挂起了。

移植u-boot-2014.10-rc3到TQ2440开发板过程记录_第21张图片

由此可知问题出在前面的flash_init()函数执行失败,查找可知该函数在drivers/mtd/cfi_flash.c文件中。打开文件并分析该函数,发现jedec_flash_match()函数执行失败导致的错误。该函数将flash_detect_legacy函数读取到的flash 信息与jedec_table 进行匹配,如果匹配成功则填充flash_info,否则返回1。说明jedec_table中没有TQ2440开发板所用Nor Flash芯片(EN29LV160AB)相关信息。

3.2在jedec_table 表中增加开发板的NOR FLASH信息

$ gedit drivers/mtd/jedec_flash.c

在jedec_table[]末尾};前插入:

#ifdef CONFIG_SYS_FLASH_LEGACY_1024Kx16

       {

              /* TQ2440 EN29LV160AB */

              .mfr_id = 0x1c, /* manufacturer_id */

              .dev_id = 0x2249, /* device_id */

              .name = "EON EN29LV160AB",

              .uaddr = {/* 因为NOR FLASH ADDR0 接到了S3C2440 ADDR1 */

                     [1] = MTD_UADDR_0x0555_0x02AA /* x16 */

              },

                     .DevSize = SIZE_2MiB,

                     .CmdSet = P_ID_AMD_STD,

                     .NumEraseRegions= 4,

                     .regions = {

                     ERASEINFO(0x04000, 1),

                     ERASEINFO(0x02000, 2),

                     ERASEINFO(0x08000, 1),

                     ERASEINFO(0x10000, 31),

              }

       },

#endif

移植u-boot-2014.10-rc3到TQ2440开发板过程记录_第22张图片

(3)定义CONFIG_SYS_FLASH_LEGACY_1024Kx16宏使添加的代码生效

$ gedit include/configs/smdk2440.h

修改其中的#define CONFIG_SYS_FLASH_LEGACY_512Kx16为#define CONFIG_SYS_FLASH_LEGACY_1024Kx16

3.3关闭调试信息

删除include/configs/smdk2440.h中的#define DEBUG宏。

3.4测试

重新编译生成u-boot.bin文件后,重启u-boot,连按两次’q’键进入命令行模式,执行tftp 0x32000000 u-boot.bin;go 0x32000000查看详细的启动信息

移植u-boot-2014.10-rc3到TQ2440开发板过程记录_第23张图片

3.5修正“too many flash sectors”错误

查找发现该信息在./drivers/mtd/jedec_flash.c文件中,判断条件为sect_cnt >= CONFIG_SYS_MAX_FLASH_SECT,也就是说CONFIG_SYS_MAX_FLASH_SECT值过小。根据EN29LV160AB芯片手册可知,该Nor Flash芯片的扇区数为35。

$ gedit include/configs/smdk2440.h

修改#define CONFIG_SYS_MAX_FLASH_SECT (19)为#define CONFIG_SYS_MAX_FLASH_SECT (35),重新编译并使用tftp 0x32000000 u-boot.bin;go 0x32000000烧录后观察启动信息:

移植u-boot-2014.10-rc3到TQ2440开发板过程记录_第24张图片

3.6修正” Warning: Your board does not use generic board.”警告

该警告在common/main.c  里面main_loop里面,原因是没有定义CONFIG_SYS_GENERIC_BOARD宏

$ gedit include/configs/smdk2440.h

在开头添加:

#define CONFIG_SYS_GENERIC_BOARD      /* 屏蔽非常规开发版警告 */

3.7再次测试

重新编译生成u-boot.bin文件后,重启u-boot,连按两次’q’键进入命令行模式,执行tftp 0x32000000 u-boot.bin;go 0x32000000查看详细的启动信息

移植u-boot-2014.10-rc3到TQ2440开发板过程记录_第25张图片

(1)使用flinfo进行Nor Flash读写测试并查看分区信息

移植u-boot-2014.10-rc3到TQ2440开发板过程记录_第26张图片

可以看到0地址所在扇区为只读状态(RO)。

(2)使用protect off all命令去掉写保护。

(3)使用cp.b 32000000 0 10指令,从0x32000000复制16字节(0x10)到0x0地址

(4)使用cmp.b 0 32000000 10指令,比较拷贝数据是否正确

(5)使用md.b 32000000 10指令读取原始内容

(6)使用md.b 0 10指令读取拷贝过来的内容,发现两份数据移植,Nor Flash移植成功。

注意:该操作破坏了位于Nor Flash0地址的原厂u-boot,需要用JLink重新烧录原厂u-boot到Nor Flash中,才便于后续继续使用TFTP烧录和调试。

3.8解决拷贝数据到Nor Flash时可能出现的“Flash not Erased”错误

提示Copy to Flash... Flash not Erased,发现无法写入Flash。按照网上的说法是在开发板配置头文件中添加ONFI_VCT_NOR宏定义,但修改后问题没解决,后尝试执行了一次erase all指令后问题解决,故网上说法是否正确有待下次验证。

$ gedit include/configs/smdk2440.h

添加:

#define ONFIG_VCT_NOR /* 编译flash_read16函数,解决Nor Flash无法写入问题 */

四、添加DM9000网卡支持

网卡DM9000 的驱动为drivers/net/dm9000x.c,我们需要将它编译进u-boot,查看drivers/net/Makefile发现需要定义CONFIG_DRIVER_DM9000宏才能将其编译到u-boot.bin中。

4.1修改开发板配置头文件

$ gedit include/configs/smdk2440.h

在第二步中已经将CS8900网卡相关定义注释掉了,替换相关内容为DM9000网卡相关宏。

(1)定义DM9000网卡相关寄存器

#if 0

#define CONFIG_CS8900           /* we have a CS8900 on-board */

#define CONFIG_CS8900_BASE       0x19000300

#define CONFIG_CS8900_BUS16      /* the Linux driver does accesses as shorts */

#endif

替换为:

#define CONFIG_DRIVER_DM9000

#define CONFIG_DM9000_NO_SROM                   /* TQ2440 开发板没有网卡的SDROM芯片 */

#define CONFIG_DM9000_BASE 0x20000000       /* TQ2440 开发板的网卡dm9000 接在S3C2440 bank4 */

#define DM9000_IO     CONFIG_DM9000_BASE

#define DM9000_DATA       (CONFIG_DM9000_BASE + 4) /* TQ2440 开发板的网卡dm9000 cmd引脚接在S3C2440 ADDR2 */

移植u-boot-2014.10-rc3到TQ2440开发板过程记录_第27张图片

(2)打开相关命令支持

取消第二步中注释掉的CONFIG_CMD_DHCP和CONFIG_CMD_PING宏

移植u-boot-2014.10-rc3到TQ2440开发板过程记录_第28张图片

4.1初步测试

使用命令tftp 0x32000000 u-boot.bin;go 0x32000000烧录u-boot到SDRAM中,观察启动输出信息

移植u-boot-2014.10-rc3到TQ2440开发板过程记录_第29张图片

提示没有找到网络,查看代码发现为在board/samsung/tq2440/smdk2440.c文件的board_eth_init函数中调用dm9000_initialize()函数。

4.2添加DM9000网卡初始化函数

$ gedit board/samsung/tq2440/smdk2440.c

参照cs8900网卡添加:

#ifdef CONFIG_DRIVER_DM9000

       rc = dm9000_initialize(bis);

#endif

移植u-boot-2014.10-rc3到TQ2440开发板过程记录_第30张图片

4.3再次测试

使用命令tftp 0x32000000 u-boot.bin;go 0x32000000烧录u-boot到SDRAM中,观察启动输出信息

移植u-boot-2014.10-rc3到TQ2440开发板过程记录_第31张图片

4.4设置并保存网络配置相关的环境变量

使用下列指令依次设置mac 地址、开发板IP 地址和tftp 服务器IP 地址,并保存环境变量的修改:

set ethaddr 00:12:34:56:ab:cd

set ipaddr 192.168.1.11

set serverip 192.168.1.10

saveenv

4.5网络功能测试

(1)Ping测试TFTP服务器(注意大小写)

ping 192.168.1.10

(2)尝试TFTP下载文件

tftpboot 31000000 u-boot.bin

移植u-boot-2014.10-rc3到TQ2440开发板过程记录_第32张图片

4.6解决新版uboot中“could not establish link “提示

$ gedit drivers/net/dm9000x.c

注释掉相关代码:

移植u-boot-2014.10-rc3到TQ2440开发板过程记录_第33张图片

五、添加Nand Flash支持

5.1修改开发板配置头文件

打开配置头文件中NAND操作命令宏

$ gedit include/configs/smdk2440.h

重新编译并使用tftp 0x32000000 u-boot.bin;go 0x32000000烧录到SDRAM运行

移植u-boot-2014.10-rc3到TQ2440开发板过程记录_第34张图片

发现无法识别Nand Flash,如果打开调试模式则发现nand_get_flash_type函数执行失败。

5.2修改Nand Flash操作底层函数

$ gedit drivers/mtd/nand/s3c2440_nand.c

对照S3C2440手册修改参数:

 

移植u-boot-2014.10-rc3到TQ2440开发板过程记录_第35张图片

替换

       cfg = S3C2440_NFCONF_EN;

       cfg |= S3C2440_NFCONF_TACLS(tacls - 1);

       cfg |= S3C2440_NFCONF_TWRPH0(twrph0 - 1);

       cfg |= S3C2440_NFCONF_TWRPH1(twrph1 - 1);

       writel(cfg, &nand_reg->nfconf);

       cfg |= S3C2440_NFCONF_TACLS(tacls);

       cfg |= S3C2440_NFCONF_TWRPH0(twrph0);

       cfg |= S3C2440_NFCONF_TWRPH1(twrph1);

       writel(cfg, &nand_reg->nfconf);

       /*初始化ECC、禁止片选、使能NAND FLASH 控制器*/

       writel((1 << 4)|(1 << 1)|(1 << 0), &nand_reg->nfcont);

修改s3c2440_hwcontrol函数,添加cmd == NAND_CMD_NONE分支

if (cmd == NAND_CMD_NONE)

                     IO_ADDR_W = &nand->nfdata;

移植u-boot-2014.10-rc3到TQ2440开发板过程记录_第36张图片

修改ctrl & NAND_NCE)分支

              if (ctrl & NAND_NCE)      // 使能选中

                     writel(readl(&nand->nfcont) & ~(1 << 1),&nand->nfcont);

              else // 取消选中

                     writel(readl(&nand->nfcont) | (1 << 1),    &nand->nfcont);

移植u-boot-2014.10-rc3到TQ2440开发板过程记录_第37张图片

 

5.3修改drivers/mtd/nand/nand_base文件

$ gedit drivers/mtd/nand/nand_base.c

找到nand_select_chip函数,实现case 0分支:

chip->cmd_ctrl(mtd, NAND_CMD_NONE, NAND_CTRL_CLE | NAND_CTRL_CHANGE);

移植u-boot-2014.10-rc3到TQ2440开发板过程记录_第38张图片

5.4测试

使用tftp 32000000 u-boot.bin;go 32000000指令从TFTP服务器下载u-boot,并烧录到开发板的SDRAM中。

移植u-boot-2014.10-rc3到TQ2440开发板过程记录_第39张图片

说明已经正确识别Nand Flash了。

(1)使用nand write 32000000 0 ff指令,将SDRAM 的0x32000000 地址的0xff 字节数据写到NAND FLASH 的0 地址

(2)使用nand read 31000000 0 ff指令,从NAND FLASH 的0 地址读0xff 字节数据到SDRAM 的0x31000000 地址

移植u-boot-2014.10-rc3到TQ2440开发板过程记录_第40张图片

注意:使用nand erase.chip擦除整片Nand Flash,否则因为写入和读取操作时的ECC校验不同而导致报“NAND read from offset 0 failed -74”错误。

擦除整片Nand Flash后,重新使用上面指令进行写入和读取操作。

移植u-boot-2014.10-rc3到TQ2440开发板过程记录_第41张图片

(3)使用cmp.b 31000000 32000000 ff指令比较读取数据是否正确。

六、从Nor Flash启动u-boot

6.1修改开发板配置头文件

$ gedit include/configs/smdk2440.h

修改链接地址CONFIG_SYS_TEXT_BASE为0x0

使用/**/注释掉#define CONFIG_SKIP_LOWLEVEL_INIT宏定义

6.2修改SDRAM的刷新参数

开发板的HCLK设置为100Mhz,根据SDRAM芯片(K4S561632数据手册上注:64ms refresh period (8K Cycle))的参数计算REFCNT寄存器的值。计算公式如下:R_CNT=2^11+1-SDRAM时钟频率(MHz)*SDRAM刷新周期(us)。

$ gedit board/samsung/tq2440/lowlevel_init.S

修改REFCNT参数为0x4f4

6.3从TFTP服务器下载u-boot.bin并烧录到Nor Flash中

(1)使用tftp 0x32000000 u-boot.bin下载u-boot.bin到SDRAM

(2)使用protect off all去掉Nor Flash的写保护

(3)使用erase 0 +40000擦除Nor Flash的前0x40000空间

(4)使用cp.b 0x32000000 0x0 0x40000指令将u-boot.bin拷贝至Nor Flash的0字节位置,因为Nor Flash写入速度比较慢,此处约需要20秒时间才能完成。

移植u-boot-2014.10-rc3到TQ2440开发板过程记录_第42张图片

(5)使用reset指令复位开发板,发现原厂的u-boot已被自己移植的u-boot替换了。

移植u-boot-2014.10-rc3到TQ2440开发板过程记录_第43张图片

七、保存环境变量到Nand Flash分区

u-boot默认是将环境变量保存在Nor Flash中的,但同时也提供了保存到Nand Flash的功能实现文件。源代码根目录common文件夹下的env_flash.c 和env_fnand.c,分别用于将环境变量保存到NOR FLASH 和NAND FLASH,分别由配置头文件中的CONFIG_ENV_IS_IN_FLASH和CONFIG_ENV_IS_IN_NAND宏控制。

7.1修改配置头文件

$ gedit include/configs/smdk2440.h

屏蔽环境变量保存到Nor Flash的宏定义

#if 0

#define CONFIG_ENV_ADDR                 (CONFIG_SYS_FLASH_BASE + 0x070000)

#define CONFIG_ENV_IS_IN_FLASH

#define CONFIG_ENV_SIZE                   0x10000

/* allow to overwrite serial and ethaddr */

#define CONFIG_ENV_OVERWRITE

#endif

添加如下代码:

#define CONFIG_ENV_IS_IN_NAND

#define CONFIG_ENV_OFFSET 0x40000 // 256K for u-boot

#define CONFIG_ENV_SIZE 0x20000 // 128K for environment

/* allow to overwrite serial and ethaddr */

#define CONFIG_ENV_OVERWRITE

移植u-boot-2014.10-rc3到TQ2440开发板过程记录_第44张图片

7.2测试

从TFTP服务器下载u-boot.bin并烧录到Nor Flash中

protect off all;erase 0 +40000;tftp 32000000 u-boot.bin;cp.b 32000000 0 40000

移植u-boot-2014.10-rc3到TQ2440开发板过程记录_第45张图片

先使用reset命令重新加载u-boot,然后使用saveenv指令保存环境变量到Nand Flash中

移植u-boot-2014.10-rc3到TQ2440开发板过程记录_第46张图片

八、为Nand Flash添加MTD分区

8.1打开MTD相关命令宏

$ gedit include/configs/smdk2440.h

打开第二步中屏蔽的CONFIG_CMD_MTDPARTS和CONFIG_MTD_DEVICE宏

移植u-boot-2014.10-rc3到TQ2440开发板过程记录_第47张图片

为何不打开CONFIG_MTD_PARTITIONS宏,此处存疑。

8.2在配置头文件中添加默认分区表

#define MTDIDS_DEFAULT "nand0=tq2440-0"

#define MTDPARTS_DEFAULT "mtdparts=tq2440-0:1m(u-boot)," \

"1m(params)," \

"3m(kernel)," \

"-(rootfs)"

此处换行最好顶格写

移植u-boot-2014.10-rc3到TQ2440开发板过程记录_第48张图片

8.3修改默认网络配置信息

#define CONFIG_NETMASK            255.255.255.0

#define CONFIG_IPADDR         192.168.1.11

#define CONFIG_SERVERIP             192.168.1.10

#define CONFIG_ETHADDR            00:11:22:33:44:aa

 

#define CONFIG_BOOTARGS "root=/dev/mtdblock2 rootfstype=yaffs2 init=/linuxrc console=ttySAC0,115200"

#define CONFIG_BOOTCOMMAND "nand read 32000000 kernel;bootm 32000000"

移植u-boot-2014.10-rc3到TQ2440开发板过程记录_第49张图片

8.4加载默认分区表

(1)从TFTP服务器获取u-boot.bin并烧录到Nor Flash中

protect off all;erase 0 +40000;

tftp 32000000 u-boot.bin;cp.b 32000000 0 40000;

移植u-boot-2014.10-rc3到TQ2440开发板过程记录_第50张图片

(2)使用reset命令重启开发板

移植u-boot-2014.10-rc3到TQ2440开发板过程记录_第51张图片

(3)使用mtdparts指令查看Nand Flash分区信息

移植u-boot-2014.10-rc3到TQ2440开发板过程记录_第52张图片

(4)使用mtdparts default加载默认分区表,并使用saveenv指令保存环境变量。

(5)再次使用mtdparts指令查看分区信息。

移植u-boot-2014.10-rc3到TQ2440开发板过程记录_第53张图片

你可能感兴趣的:(嵌入式linux内核移植)