1、启动模块修改
进入/cpu/arm1176/目录,修改start.S文件
首先找到需要修改的CONFIG_NAND_SPL汇编原码,修改如下:
#ifndef CONFIG_NAND_SPL
/*
* 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 2 (A) Align
orr r0, r0, #0x00001000 @ set bit 12 (I) I-Cache
//将原来之间的内容删除
mcr p15, 0, r0, c1, c0, 0
#endif
检索到“lowlevel_init”
添加如下内容,功能看注释
/* when we already run in ram, we don't need to relocate U-Boot.
* and actually, memory controller must be configured before U-Boot
* is running in ram.
*/
ldr r0, =0xff000fff
bic r1, pc, r0 /* r0 <- current base addr of code */
ldr r2, _TEXT_BASE /* r1 <- original base addr in ram */
bic r2, r2, r0 /* r0 <- current base addr of code */
cmp r1, r2 /* compare r0, r1 */
beq after_copy /* r0 == r1 then skip flash copy */
此处顺便温习arm汇编
ldr汇编码与伪汇编码区别在于是否有“=”号
ldr汇编为 ldr r1, [r2], 将 r2 当作地址放入 r1 寄存器,而intel与at&t汇编的mov指令是无法对地址直接操作的。
ldr伪汇编为 ldr r1, =
bic语法格式为 BIC{
bic一般用于清零处理:
1、此处若系统从nandflash中启动,则pc小于4k,取反、与运算后,将0传给r1
此处_TEXT_BASE可能为0x57e00000或者0c7e00000,取反、与运算后,将0x00e00000传回r2
beq相等则跳转指令,此处 r1,r2不相等,故不跳转,继续往下执行
2、此处若系统从ram中启动,则此处的pc应该与_TEXT_BASE相等,故直接跳转至after_copy(复制
完成)处运行。
紧接着前面的代码添加下面一段代码:
#ifdef CONFIG_BOOT_NAND
mov r0, #0x1000
bl copy_from_nand
#endif
此处的 bl 为调用子程序,接着上面的是因为未复制完成从新跳回 copy_from_nand 从新复制nandflash
然后找到_mmu_table_base,在它的#endif之后,添加如下代码,即上面所跳转的目标代码
/*
* copy U-Boot to SDRAM and jump to ram (from NAND or OneNAND)
* r0: size to be compared
* Load 1'st 2blocks to RAM because U-boot's size is larger than 1block(128k) size
*/
.globl copy_from_nand
copy_from_nand:
mov r10, lr /* save return address */
mov r9, r0
/* get ready to call C functions */
ldr sp, _TEXT_PHY_BASE /* setup temp stack pointer */
sub sp, sp, #12
mov fp, #0 /* no previous frame, so fp=0 */
mov r9, #0x1000
bl copy_uboot_to_ram
3: tst r0, #0x0
bne copy_failed
ldr r0, =0x0c000000
ldr r1, _TEXT_PHY_BASE
1: ldr r3, [r0], #4
ldr r4, [r1], #4
teq r3, r4
bne compare_failed /* not matched */
subs r9, r9, #4
bne 1b
4: mov lr, r10 /* all is OK */
mov pc, lr
copy_failed:
nop /* copy from nand failed */
b copy_failed
compare_failed:
nop /* compare failed */
b compare_failed
至此,start.S文件修改完成。
接着在/cpu/arm1176/目录下添加一个nand_cp.c文件
代码如下
#include
#ifdef CONFIG_S3C64XX
#include
#include
#include
static int nandll_read_page (uchar *buf, ulong addr, int large_block)
{
int i;
int page_size = 512;
/* 2K */
if (large_block==1)
page_size = 2048;
/* 4K */
if (large_block==2)
page_size = 4096;
NAND_ENABLE_CE();
NFCMD_REG = NAND_CMD_READ0;
/* Write Address */
NFADDR_REG = 0;
if (large_block)
NFADDR_REG = 0;
NFADDR_REG = (addr) & 0xff;
NFADDR_REG = (addr >> 8) & 0xff;
NFADDR_REG = (addr >> 16) & 0xff;
if (large_block)
NFCMD_REG = NAND_CMD_READSTART;
NF_TRANSRnB();
/* for compatibility(2460). u32 cannot be used. by scsuh */
for(i=0; i < page_size; i++)
{
*buf++ = NFDATA8_REG;
}
NAND_DISABLE_CE();
return 0;
}
static int nandll_read_blocks (ulong dst_addr, ulong size, int large_block)
{
uchar *buf = (uchar *)dst_addr;
int i;
uint page_shift = 9;
if (large_block==1)
page_shift = 11;
/* Read pages */
if(large_block==2)
page_shift = 12;
if(large_block == 2)
{
/* Read pages */
for (i = 0; i < 4; i++, buf+=(1<<(page_shift-1)))
{
nandll_read_page(buf, i, large_block);
}
/* Read pages */
/* 0x3c000 = 11 1100 0000 0000 0000 */
for (i = 4; i < (0x3c000>>page_shift); i++, buf+=(1<
{
nandll_read_page(buf, i, large_block);
}
}
else
{
for (i = 0; i < (0x3c000>>page_shift); i++, buf+=(1<
{
nandll_read_page(buf, i, large_block);
}
}
return 0;
}
int copy_uboot_to_ram(void)
{
int large_block = 0;
int i;
vu_char id;
/*
#define NAND_ENABLE_CE() (NFCONT_REG &= ~(1 << 1))
#define NFCONT_REG
__REG(ELFIN_NAND_BASE + NFCONT_OFFSET)
#define __REG(x) (*((volatile u32 *)(x)))
#define ELFIN_NAND_BASE 0x70200000
#define NFCONT_OFFSET 0x04
NFCONT_REG = ( *( (volatile u32 *) (0x70200004) ) )
NFCONT 0x70200004 读/写NAND Flash 控制寄存器
[0]1:NAND Flash 控制器使能
*/
NAND_ENABLE_CE();
/*
#define NFCMD_REG
__REG(ELFIN_NAND_BASE + NFCMMD_OFFSET)
#define ELFIN_NAND_BASE 0x70200000
#define NFCMMD_OFFSET 0x08
NFCMD_REG = ( *( (volatile u32 *) (0x70200008) ) )
NFCMMD 0x70200008 NAND Flash 命令设置寄存器0
#define NAND_CMD_READID 0x90
*/
NFCMD_REG = NAND_CMD_READID;
/*
#define NFADDR_REG
__REG(ELFIN_NAND_BASE + NFADDR_OFFSET)
#define ELFIN_NAND_BASE 0x70200000
#define NFADDR_OFFSET 0x0C
NFADDR_REG = ( *( (volatile u32 *) (0x7020000C) ) )
NFADDR 0x7020000C NAND Flash 地址设置寄存器
*/
NFADDR_REG = 0x00;
/*
#define NFDATA8_REG
__REGb(ELFIN_NAND_BASE + NFDATA_OFFSET)
#define __REGb(x) (*(vu_char *)(x))
NFDATA8_REG = ( *( (vu_char *) (0x70200010) ) )
NFDATA 0x70200010 读/写NAND Flash 数据寄存器
NAND Flash 读/烧写数据值用于I/O
*/
/* wait for a while */
for (i=0; i<200; i++);
id = NFDATA8_REG;
id = NFDATA8_REG;
if (id > 0x80)
large_block = 1;
if(id == 0xd5)
large_block = 2;
/* read NAND Block.
* 128KB ->240KB because of U-Boot size increase. by scsuh
* So, read 0x3c000 bytes not 0x20000(128KB).
*/
/*
#define CONFIG_SYS_PHY_UBOOT_BASE
(CONFIG_SYS_SDRAM_BASE + 0x07e00000)
#define CONFIG_SYS_SDRAM_BASE 0x50000000
CONFIG_SYS_PHY_UBOOT_BASE = 0x57e0 0000
0x3 c000 = 1M
*/
return nandll_read_blocks(CONFIG_SYS_PHY_UBOOT_BASE, 0x3c000, large_block);
}
#endif
然后在/cpu/arm1176/makefile中添加一个依赖到COBJS目标后面
COBJS = cpu.o nand_cp.o
接着在/nand_spl/board/samsung/smdk6410/Makefile中添加一个依赖到COBJS后面
COBJS = nand_boot.o nand_ecc.o s3c64xx.o nand_cp.o
补全规则
# from SoC directory
$(obj)cpu_init.S:
@rm -f $@
@ln -s $(TOPDIR)/cpu/arm1176/s3c64xx/cpu_init.S $@
$(obj)nand_cp.c:
@rm -f $@
@ln -s $(TOPDIR)/cpu/arm1176/nand_cp.c $@
接着修改smdk6410.h文件(在/include/configs/目录下):
1、添加宏定义
#define virt_to_phys(x) virt_to_phy_smdk6410(x)
2、用户名回显修改
#define CONFIG_SYS_PROMPT 'SMDK6400 #'
3、添加smdk6410 ID
检索到MACH_TYPE,将其注释掉,然后添加smdk6410 ID如下
#define MACH_TYPE 1626
4、增加NAND config的内容
添加位置 /* NAND configuration */
#define NAND_DISABLE_CE()(NFCONT_REG |=(1<<1))
#define NAND_ENABLE_CE()(NFCONT_REG &=~(1<<1))
#define NF_TRANSRnB() do{while(!(NFSTAT_REG&(1<<0)));}while(0)
5、NAND flash 大小
//#define PHYS_SDRAM_1_SIZE 0x08000000 /* 128 MB in Bank #1 */
#define PHYS_SDRAM_1_SIZE 0x10000000 /* 256 MB in Bank #1 */
6、NAND flash块大小
/* NAND chip block size */
//#define CONFIG_SYS_NAND_BLOCK_SIZE (128 * 1024)
#define CONFIG_SYS_NAND_BLOCK_SIZE (512 * 1024)
7、NAND flash页大小
/* NAND chip page size */
//#define CONFIG_SYS_NAND_PAGE_SIZE 2048
#define CONFIG_SYS_NAND_PAGE_SIZE 4096
8、位校验
/* NAND chip page per block count */
//#define CONFIG_SYS_NAND_PAGE_COUNT 64
#define CONFIG_SYS_NAND_PAGE_COUNT 128
9、更改内存分配空间
/*
* Size of malloc() pool