TQ2440移植u-boot2016.11全过程记录-【1】单板建立并启动

TQ2440移植u-boot2016.11-单板建立并启动


移植说明

u-boot2016.11是S3C2440最后一版的uboot支持,所以选择了此版本进行移植,交叉编译器使用的是天嵌官方的交叉编译器,版本为4.4.3,使用的ubuntu1404系统。


(一)新建TQ2440单板

编辑u-boot顶层Makefile文件

gedit Makefile

定位到:

# set default to nothing for native builds
ifeq ($(HOSTARCH),$(ARCH))
CROSS_COMPILE ?=
endif

在下方插入:

ARCH ?= arm
CROSS_COMPILE ?= arm-linux-

这两句的作用为指定编译熟悉和交叉编译工具链。
在这里插入图片描述

将以下两句屏蔽掉,如果不屏蔽掉,后续会修改配置头文件中的默认宏定义而导致配置检查无法通过。
在这里插入图片描述

新建tq2440单板:

  • 创建tq2440单板:
    • cp -a board/samsung/smdk2410 board/samsung/tq2440
    • mv board/samsung/tq2440/smdk2410.c board/samsung/tq2440/tq2440.c
  • 拷贝头文件:cp include/configs/smdk2410.h include/configs/tq2440.h
  • 拷贝配置文件:cp configs/smdk2410_defconfig configs/tq2440_defconfig

修改board/samsung/tq2440/目录下的文件:

  • 修改Kconfig文件:
    gedit board/samsung/tq2440/Kconfig
    在这里插入图片描述
  • 修改板卡支持维护信息文件MAINTAINERS:
    gedit board/samsung/tq2440/MAINTAINERS
    在这里插入图片描述
  • 修改Makefile:
    gedit board/samsung/tq2440/Makefile
    在这里插入图片描述
  • 修改configs/tq2440_defconfig文件:
    gedit configs/tq2440_defconfig
    在这里插入图片描述
  • 修改arch/arm/Kconfig文件:
    • 定位到:

      config TARGET_SMDK2410
      	bool "Support smdk2410"
      	select CPU_ARM920T
      

      下方添加:

      config TARGET_TQ2440
      	bool "Support tq2440"
      	select CPU_ARM920T
      
    • 定位到:

      source "board/samsung/smdk2410/Kconfig
      

      在下一行添加:

      source "board/samsung/tq2440/Kconfig
      

 ~
修改内核引导机器码信息:
arch/arm/include/asm/mach-types.h

        ~~~~~~~~TQ2440官方linux系统内核的机器码为168,所以我们需要修改u-boot的机器识别码,否则在启动引导内核时无法识别。

定位到:

#define MACH_TYPE_SMDK2410             193

在下方插入一行:

#define MACH_TYPE_TQ2440               168

定位到:

#ifdef CONFIG_ARCH_SMDK2410
# ifdef machine_arch_type
#  undef machine_arch_type
#  define machine_arch_type	__machine_arch_type
# else
#  define machine_arch_type	MACH_TYPE_SMDK2410
# endif
# define machine_is_smdk2410()	(machine_arch_type == MACH_TYPE_SMDK2410)
#else
# define machine_is_smdk2410()	(0)
#endif

在下方添加:

#ifdef CONFIG_ARCH_TQ2440
# ifdef machine_arch_type
#  undef machine_arch_type
#  define machine_arch_type	__machine_arch_type
# else
#  define machine_arch_type	MACH_TYPE_TQ2440
# endif
# define machine_is_tq2440()	(machine_arch_type == MACH_TYPE_TQ2440)
#else
# define machine_is_tq2440()	(0)
#endif

到此单板建立完成,编译一下看看是否成功:

  • make distclean
  • make tq2440_defconfig
  • make
    在这里插入图片描述
    OK,没问题,到此第一阶段的单板建立完成,后续开始移植修改代码。

(二)初始化代码修改

修改汇编启动文件arch/arm/cpu/arm920t/start.S,将其中的代码替换为以下:

/*
 *  armboot - Startup Code for ARM920 CPU-core
 *
 *  Copyright (c) 2001	Marius Gröger <[email protected]>
 *  Copyright (c) 2002	Alex Züpke <[email protected]>
 *  Copyright (c) 2002	Gary Jennejohn <[email protected]>
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#include <asm-offsets.h>
#include <common.h>
#include <config.h>

/*
 *************************************************************************
 *
 * Startup Code (called from the ARM reset exception vector)
 *
 * do important init only if we don't start from memory!
 * relocate armboot to ram
 * setup stack
 * jump to second stage
 *
 *************************************************************************
 */

	.globl	reset

reset:
	/*
	 * set the cpu to SVC32 mode
	 */
	mrs	r0, cpsr
	bic	r0, r0, #0x1f
	orr	r0, r0, #0xd3
	msr	cpsr, r0

#define pWTCON	      0x53000000
#define INTMSK	      0x4A000008	/* Interrupt-Controller base addresses */
#define INTSUBMSK	  0x4A00001C
#define CLKDIVN	      0x4C000014	/* clock divisor register */
#define MPLLCON       0x4C000004
#define UPLLCON       0x4C000008

	/* turn off the watchdog */
	ldr	r0, =pWTCON
	mov	r1, #0x0
	str	r1, [r0]

	/* mask all IRQs by setting all bits in the INTMR - default */
	mov	r1, #0xffffffff
	ldr	r0, =INTMSK
	str	r1, [r0]
	ldr r1, =0x7ff
	ldr r0, =INTSUBMSK
	str r1, [r0]
	
	/* FCLK:HCLK:PCLK = 1:4:8 */
	/* default FCLK is 405 MHz ! */
	ldr r0, =CLKDIVN
	mov r1, #5
	str r1, [r0]
	
	/* set asynchronous bus mod */
	mrc p15, 0, r1, c1, c0, 0
	orr r1, r1, #0xc0000000  
	mcr p15, 0, r1, c1, c0, 0

	/* When you set MPLL&UPLL values, you have 
	 * to set the UPLL value first and then the MPLL value. 
	 * (Needs intervals approximately 7 NOP) 
	 */

	/* set upllcon is 48MHz */
	ldr r0, =UPLLCON
	ldr r1, =((0x38 << 12) | (0x2 << 4) | (0x2 << 0))
	str r1, [r0]

	/* delay 7 nop */
	nop
	nop
	nop
	nop
	nop
	nop
	nop

	/* set mpllcon is 405MHz */
    ldr r0, =MPLLCON
	ldr r1, =((0x7F << 12) | (0x2 << 4) | (0x1 << 0))
	str r1, [r0]
	
	/*
	 * we do sys-critical inits only at reboot,
	 * not when booting from ram!
	 */
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
	bl	cpu_init_crit
#endif

	bl	_main

/*------------------------------------------------------------------------------*/

	.globl	c_runtime_cpu_setup
c_runtime_cpu_setup:

	mov	pc, lr

/*
 *************************************************************************
 *
 * CPU_init_critical registers
 *
 * setup important registers
 * setup memory timing
 *
 *************************************************************************
 */


#ifndef CONFIG_SKIP_LOWLEVEL_INIT
cpu_init_crit:
	/*
	 * flush v4 I/D caches
	 */
	mov	r0, #0
	mcr	p15, 0, r0, c7, c7, 0	/* flush v3/v4 cache */
	mcr	p15, 0, r0, c8, c7, 0	/* flush v4 TLB */

	/*
	 * disable MMU stuff and caches
	 */
	mrc	p15, 0, r0, c1, c0, 0
	bic	r0, r0, #0x00002300	@ clear bits 13, 9:8 (--V- --RS)
	bic	r0, r0, #0x00000087	@ clear bits 7, 2:0 (B--- -CAM)
	orr	r0, r0, #0x00000002	@ set bit 1 (A) Align
	orr	r0, r0, #0x00001000	@ set bit 12 (I) I-Cache
	mcr	p15, 0, r0, c1, c0, 0

#ifndef CONFIG_SKIP_LOWLEVEL_INIT_ONLY
	/*
	 * before relocating, we have to setup RAM timing
	 * because memory timing is board-dependend, you will
	 * find a lowlevel_init.S in your board directory.
	 */
	mov	ip, lr

	bl	lowlevel_init
	mov	lr, ip
#endif
	mov	pc, lr
#endif /* CONFIG_SKIP_LOWLEVEL_INIT */

注意:这里我在这个汇编文件中设置了UPLLCON寄存器,目的是因为后续移植linux内核后,当使用USB鼠标或者U盘时,由于未先设置UPLLCON寄存器导致在linux内核启动配置USB时钟时会设置失败,错误信息大概为usb 1-1: device descriptor read/64, error -110的字样,这个错误是USB鼠标或U盘插入后能显示有设备插入但是无法枚举,也就是USB时钟没有配置为48M导致的,所以在此将USB的时钟设置为了48M,UPLLCON和MPLLCON寄存器是有设置顺序的,要先设置UPLLCON然后延时7个时钟在设置MPLLCON,这在S3C2440芯片数据手册中有说明:
在这里插入图片描述
修改SDRAM初始化代码文件board/samsung/tq2440/lowlevel_init.S

定位到:

SMRDATA:
    .word (0+(B1_BWSCON<<4)+(B2_BWSCON<<8)+(B3_BWSCON<<12)+(B4_BWSCON<<16)+(B5_BWSCON<<20)+(B6_BWSCON<<24)+(B7_BWSCON<<28))
    .word ((B0_Tacs<<13)+(B0_Tcos<<11)+(B0_Tacc<<8)+(B0_Tcoh<<6)+(B0_Tah<<4)+(B0_Tacp<<2)+(B0_PMC))
    .word ((B1_Tacs<<13)+(B1_Tcos<<11)+(B1_Tacc<<8)+(B1_Tcoh<<6)+(B1_Tah<<4)+(B1_Tacp<<2)+(B1_PMC))
    .word ((B2_Tacs<<13)+(B2_Tcos<<11)+(B2_Tacc<<8)+(B2_Tcoh<<6)+(B2_Tah<<4)+(B2_Tacp<<2)+(B2_PMC))
    .word ((B3_Tacs<<13)+(B3_Tcos<<11)+(B3_Tacc<<8)+(B3_Tcoh<<6)+(B3_Tah<<4)+(B3_Tacp<<2)+(B3_PMC))
    .word ((B4_Tacs<<13)+(B4_Tcos<<11)+(B4_Tacc<<8)+(B4_Tcoh<<6)+(B4_Tah<<4)+(B4_Tacp<<2)+(B4_PMC))
    .word ((B5_Tacs<<13)+(B5_Tcos<<11)+(B5_Tacc<<8)+(B5_Tcoh<<6)+(B5_Tah<<4)+(B5_Tacp<<2)+(B5_PMC))
    .word ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN))
    .word ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN))
    .word ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT)
    .word 0x32
    .word 0x30
    .word 0x30

替换为:

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,1的二进制为001,表示内存为64M,具体请看BANKSIZE寄存器
	.long 0x00000030 @ MRSRB6
	.long 0x00000030 @ MRSRB7

修改板卡初始化代码文件board/samsung/tq2440/tq2440.c

定位到:

#define FCLK_SPEED 1

#if (FCLK_SPEED == 0)		/* Fout = 203MHz, Fin = 12MHz for Audio */
#define M_MDIV	0xC3
#define M_PDIV	0x4
#define M_SDIV	0x1
#elif (FCLK_SPEED == 1)		/* Fout = 202.8MHz */
#define M_MDIV	0xA1
#define M_PDIV	0x3
#define M_SDIV	0x1
#endif

#define USB_CLOCK 1

#if (USB_CLOCK == 0)
#define U_M_MDIV	0xA1
#define U_M_PDIV	0x3
#define U_M_SDIV	0x1
#elif (USB_CLOCK == 1)
#define U_M_MDIV	0x48
#define U_M_PDIV	0x3
#define U_M_SDIV	0x2
#endif

替换为:

#define FCLK_SPEED 2

#if (FCLK_SPEED == 0)		/* Fout = 203MHz, Fin = 12MHz for Audio */
#define M_MDIV	0xC3
#define M_PDIV	0x4
#define M_SDIV	0x1
#elif (FCLK_SPEED == 1)		/* Fout = 202.8MHz */
#define M_MDIV	0xA1
#define M_PDIV	0x3
#define M_SDIV	0x1
#elif (FCLK_SPEED == 2)		/* Fout = 405MHz */
#define M_MDIV  0x7f
#define M_PDIV  0x2
#define M_SDIV  0x1
#endif

#define USB_CLOCK 2

#if (USB_CLOCK == 0)
#define U_M_MDIV	0xA1
#define U_M_PDIV	0x3
#define U_M_SDIV	0x1
#elif (USB_CLOCK == 1)
#define U_M_MDIV	0x48
#define U_M_PDIV	0x3
#define U_M_SDIV	0x2
#elif (USB_CLOCK == 2)
#define U_M_MDIV    0x38
#define U_M_PDIV    0x2
#define U_M_SDIV    0x2
#endif

修改IO口,点亮LED灯:

        ~~~~~~~~TQ2440板载4个LED灯接到了GPB8-GPB5,蜂鸣器接到了GPB0,GPB共有11个引脚,由高到低依次为GPB10-GPB0,由GPBCON、GPBUP和GPBDAT三个寄存器控制。

  • GPBCON(0x56000010):每两位控制一个引脚,为00时表示输入引脚,为01时表示输出引脚,
    为10时表示复用功能;
  • GPBDAT(0x56000014):每一位表示一个引脚的输入或输出状态;
  • GPBUP(0x56000018):每一位控制一个引脚,为0时表示使用上拉电阻,为1表示禁用上拉电
    阻。

找到board_early_init_f函数,定位到writel(0x00044555, &gpio->gpbcon),代码将0x00044555写入到了GPBCON寄存器,二进制为1000100010101010101,也就是说将GPB10、GPB8、GPB6配置为了输入,其他配置为了输出;我们需要将GPB8-GPB5和GPB0配置为输出模式,其他引脚配置为复用模式,用计算器计算一下为:
在这里插入图片描述
所以将0x00044555改为0x002956A9即可。
原本的代码将0x000007FF写入到了GPBUP寄存器,0x7FF就是控制了11位,也就是将GPB的11个IO全部禁止使用上拉电阻,此处无需更改。
在这里插入图片描述

找到board_init函数,修改为:
在这里插入图片描述
注意gd->bd->bi_boot_params = 0x30000100这行代码,这里指定了在SDRAM中运行时的环境变量保存位置,暂时不修改,后面移植过程中在研究。
 ~
修改板卡初始化代码头文件:

  • gedit include/configs/tq2440.h
  • S3C2410替换为S3C2440
  • SMDK2410替换为TQ2440

创建NAND Flash 驱动

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

  • gedit drivers/mtd/nand/s3c2440_nand.c将文件中的S3C2410替换为S3C2440

  • gedit drivers/mtd/nand/Makefile
    定位到: obj-$(CONFIG_NAND_S3C2410) += s3c2410_nand.o
    在下一行加入: obj-$(CONFIG_NAND_S3C2440) += s3c2440_nand.o
    在这里插入图片描述

设置从SDRAM启动代码

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

  • 在开头定义一个宏CONFIG_SKIP_LOWLEVEL_INIT,目的是在arch/arm/cpu/arm920t/start.S中跳过SDRAM的初始化,否则我们将程序通过tftp下载到内存处时,就会将SDRAM重新初始化破坏掉代码。
  • 修改宏CONFIG_SYS_TEXT_BASE的值为0x30008000,一会我们使用tftp将u-boot.bin下载到这个地址。
    在这里插入图片描述

编译一下无误后使用天嵌自带的u-boot将刚编译出来u-boot.bin下载到内存0x30008000地址处,然后运行:

  • tftp 0x30008000 uboot.bin
  • go 0x30008000
    在这里插入图片描述
    成功启动!
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章