S3C6410移植u-boot-2010.3(2)基本的启动信息修改
2024-09-03 来源:cnblogs
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 */ //#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + 1024 * 1024) #define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + 512 * 1024) 10、修改开机延迟时间 #define CONFIG_BOOTDELAY 3 11、设置SDRAM大小 //#define PHYS_SDRAM_1_SIZE 0x08000000 /* 128 MB in Bank #1 */ #define PHYS_SDRAM_1_SIZE 0x10000000 /* 256 MB in Bank #1 */ /* 后面的大小自己设定 这里是256MB的SDRAM */ 12、修改SDROM大小 //#define CONFIG_SYS_MEMTEST_END (CONFIG_SYS_SDRAM_BASE + 0x7e00000) /* 126MB in DRAM */ #define CONFIG_SYS_MEMTEST_END (CONFIG_SYS_SDRAM_BASE + 0x9e00000) /* 256MB in DRAM */ 13、PWM设置 //#define CONFIG_SYS_HZ 1000 #define CONFIG_SYS_HZ 1562500 14、堆栈大小 /*----------------------------------------------------------------------- * Stack sizes * * The stack sizes are set up in start.S using the settings below */ //#define CONFIG_STACKSIZE 0x40000 /* regular stack 256KB */ #define CONFIG_STACKSIZE 0x80000 /* regular stack 512KB */ 15、环境变量空间 //#define CONFIG_ENV_SIZE 0x4000 /* Total Size of Environment Sector */ #define CONFIG_ENV_SIZE 0x80000 /* Total Size of Environment Sector */ 16、环境变量偏移地址 //#define CONFIG_ENV_OFFSET 0x0040000 #define CONFIG_ENV_OFFSET 0x0080000 17、BOOTCOMMAND 更改后的内容为 #ifdef CONFIG_ENABLE_MMU #define CONFIG_SYS_MAPPED_RAM_BASE 0xc0000000 #define CONFIG_BOOTCOMMAND 'nand read 0xc0008000 0x100000 0x500000;' 'bootm 0xc0008000' #else #define CONFIG_SYS_MAPPED_RAM_BASE CONFIG_SYS_SDRAM_BASE #define CONFIG_BOOTCOMMAND 'nand read 0x50008000 0x100000 0x500000;' 'bootm 0x50008000' #endif 然后开始添加内容到u-boot.lds,在目录cpu/arm1176/还有uboot根目录下面都有 完善如下代码段 . = ALIGN(4); .text : { cpu/arm1176/start.o (.text) cpu/arm1176/s3c64xx/cpu_init.o (.text) board/samsung/smdk6410/lowlevel_init.o (.text) cpu/arm1176/nand_cp.o (.text) lib_arm/board.o (.text) *(.text) } 添加内容到u-boot-nand.lds,在目录/board/samsung/smdk6410中 完善如下代码 . = ALIGN(4); .text : { cpu/arm1176/start.o (.text) cpu/arm1176/s3c64xx/cpu_init.o (.text) board/samsung/smdk6410/lowlevel_init.o (.text) cpu/arm1176/nand_cp.o (.text) lib_arm/board.o (.text) *(.text) } 接着就可以回到根目录进行make了。 然后就可以看到你的uboot正式运转了…、