【Linux 移植 】——4、移植 u-boot-2012.04.01 之 支持NAND启动

本文详细介绍了如何移植u-boot-2012.04.01以支持NAND启动。主要涉及修改和添加的文件包括init.c、board/samsung/smdk2440目录的Makefile,以及start.S、smdk2440.h、common.h、board.c和arch/arm/cpu/u-boot.lds等多个源文件。通过这些修改,移除了-pie选项,实现了NAND Flash的相关配置,并完成了编译和测试过程。
摘要由CSDN通过智能技术生成

三、移植 u-boot-2012.04.01 之 支持NAND启动

需要进行修改和添加的文件:

1、添加的文件:init.c   包含NAND Flash 的相关配置

 board/samsung/smdk2440目录, 修改Makefile

2、需要修改的文件:

a、去掉-pie选项,修改arch/arm/config.mk

b、start.S

c、smdk2440.h

d、common.h

e、board.c

f、arch/arm/cpu/u-boot.lds  


1、添加的文件:init.c 

init.c 代码如下:

/* NAND FLASH控制器 */
#define NFCONF (*((volatile unsigned long *)0x4E000000))
#define NFCONT (*((volatile unsigned long *)0x4E000004))
#define NFCMMD (*((volatile unsigned char *)0x4E000008))
#define NFADDR (*((volatile unsigned char *)0x4E00000C))
#define NFDATA (*((volatile unsigned char *)0x4E000010))
#define NFSTAT (*((volatile unsigned char *)0x4E000020))

/* GPIO */
#define GPHCON              (*(volatile unsigned long *)0x56000070)
#define GPHUP               (*(volatile unsigned long *)0x56000078)

/* UART registers*/
#define ULCON0              (*(volatile unsigned long *)0x50000000)
#define UCON0               (*(volatile unsigned long *)0x50000004)
#define UFCON0              (*(volatile unsigned long *)0x50000008)
#define UMCON0              (*(volatile unsigned long *)0x5000000c)
#define UTRSTAT0            (*(volatile unsigned long *)0x50000010)
#define UTXH0               (*(volatile unsigned char *)0x50000020)
#define URXH0               (*(volatile unsigned char *)0x50000024)
#define UBRDIV0             (*(volatile unsigned long *)0x50000028)

#define TXD0READY   (1<<2)

void nand_read_ll(unsigned int addr, unsigned char *buf, unsigned int len);

static int isBootFromNorFlash(void)
{
	volatile int *p = (volatile int *)0;
	int val;

	val = *p;
	*p = 0x12345678;
	if (*p == 0x12345678)
	{
		/* 写成功, 是nand启动 */
		*p = val;
		return 0;
	}
	else
	{
		/* NOR不能像内存一样写 */
		return 1;
	}
}

void copy_code_to_sdram(unsigned char *src, unsigned char *dest, unsigned int len)
{	
	int i = 0;
	
	/* 如果是NOR启动 */
	if (isBootFromNorFlash())
	{
		while (i < len)
		{
			dest[i] = src[i];
			i++;
		}
	}
	else
	{
		//nand_init();
		nand_read_ll((unsigned int)src, dest, len);
	}
}

void clear_bss(void)
{
	extern int __bss_start, __bss_end__;
	int *p = &__bss_start;
	
	for (; p < &__bss_end__; p++)
		*p = 0;
}

void nand_init_ll(void)
{
#define TACLS   0
#define TWRPH0  1
#define TWRPH1  0
	/* 设置时序 */
	NFCONF = (TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4);
	/* 使能NAND Flash控制器, 初始化ECC, 禁止片选 */
	NFCONT = (1<<4)|(1<<1)|(1<<0);	
}

static void nand_select(void)
{
	NFCONT &= ~(1<<1);	
}

static void nand_deselect(void)
{
	NFCONT |= (1<<1);	
}

static void nand_cmd(unsigned char cmd)
{
	volatile int i;
	NFCMMD = cmd;
	for (i = 0; i < 10; i++);
}

static void nand_addr(unsigned int addr)
{
	unsigned int col  = addr % 2048;
	unsigned int page = addr / 2048;
	volatile int i;

	NFADDR = col & 0xff;
	for (i = 0; i < 10; i++);
	NFADDR = (col >> 8) & 0xff;
	for (i = 0; i < 10; i++);
	
	NFADDR  = page & 0xff;
	for (i = 0; i < 10; i++);
	NFADDR  = (page >> 8) & 0xff;
	for (i = 0; i < 10; i++);
	NFADDR  = (page >> 16) & 0xff;
	for (i = 0; i < 10; i++);	
}

static void nand_wait_ready(void)
{
	while (!(NFSTAT & 1));
}

static unsigned char nand_data(void)
{
	return NFDATA;
}

void nand_read_ll(unsigned int addr, unsigned char *buf, unsigned int len)
{
	int col = addr % 2048;
	int i = 0;
		
	/* 1. 选中 */
	nand_select();

	while (i < len)
	{
		/* 2. 发出读命令00h */
		nand_cmd(0x00);

		/* 3. 发出地址(分5步发出) */
		nand_addr(addr);

		/* 4. 发出读命令30h */
		nand_cmd(0x30);

		/* 5. 判断状态 */
		nand_wait_ready();

		/* 6. 读数据 */
		for (; (col < 2048) && (i < len); col++)
		{
			buf[i] = nand_data();
			i++;
			addr++;
		}
		
		col = 0;
	}

	/* 7. 取消选中 */		
	nand_deselect();
}

同时在 board/samsung/smdk2440目录, 修改Makefile

Makefile:28: COBJS:= smdk2440.o init.o 



2、需要修改的文件:

a、去掉-pie选项,不需要附加“*(.rel*)”、“*(.dynsm)”等信息

命令:grep "\-pie" * -nR
arch/x86/config.mk:43:LDFLAGS_FINAL += --gc-sections -pie
arch/arm/config.mk:75:LDFLAGS_u-boot += -pie
doc/README.arm-relocation:3:At arch level: add linker flag -pie

然后输入命令: vim arch/arm/config.mk

去掉/config.mk去掉75行LDFLAGS_u-boot += -pie


b、修改start.S  参考以前写的start.S 修改代码

前一篇我们对u-boot 进行了时钟、SDRAM 以及串口的相关设定;这一篇的目的是要让u-boot 支持NAND 启动。

在进行是时钟设定之后需要对重定向的代码进行修改:

        ldr	sp, =(CONFIG_SYS_INIT_SP_ADDR)	
	bic	sp, sp, #7 /* 8-byte alignment for ABI compliance */    

	/* 重定位 : 把bootloader本身的代码从flash复制到它的链接地址去 */	
	bl	nand_init_ll	
	mov r0, #0	
	ldr   r1, _TEXT_BASE	
	ldr    r2, _bss_start_ofs		
	bl    copy_code_to_sdram	
	bl    clear_bss	
	ldr pc, = board_init_f

	/* Set stackpointer in internal RAM to call board_init_f */
call_board_init_f:	
	
	ldr	r0,=0x00000000	
	bl	board_init_f	

	
	ldr   r1, _TEXT_BASE	
	bl    board_init_r

同时对将CONFIG_SYS_TEXT_BASE修改为0x33f80000

 自己写了重定位,就去掉它写的重定位函数
    注释掉掉board.c中board_init_f中//relocate_code(addr_sp, id, addr);
    删掉start.S中下面不需要的代码

    • 0
      点赞
    • 1
      收藏
      觉得还不错? 一键收藏
    • 1
      评论
    评论 1
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

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

    抵扣说明:

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

    余额充值