u-boot-2016.05移植:(2)、修改时钟 初始化sdram 重定位u-boot 配置smdk2440.h 修改u-boot.lds

    xiaoxiao2025-09-09  555

    1、修改时钟: 在u-boot-2016.05\arch\arm\cpu\arm920t\start.S中将

    /* * 设置时钟 */ /* FCLK:HCLK:PCLK = 1:2:4 */ /* default FCLK is 120 MHz ! */ ldr r0, =CLKDIVN mov r1, #3 str r1, [r0]

    替换为:

    /* * 设置时钟 */ ldr r0, =0x4c000014 mov r1, #0x05; // FCLK:HCLK:PCLK=1:4:8 str r1, [r0] /* 如果HDIVN非0,CPU的总线模式应该从“fast bus mode”变为“asynchronous bus mode” */ mrc p15, 0, r1, c1, c0, 0 /* 读出控制寄存器 */ orr r1, r1, #0xc0000000 /* 设置为“asynchronous bus mode” */ mcr p15, 0, r1, c1, c0, 0 /* 写入控制寄存器 */ #define S3C2440_MPLL_400MHZ ((0x5c<<12)|(0x01<<4)|(0x01)) /* MPLLCON = S3C2440_MPLL_200MHZ */ ldr r0, =0x4c000004 ldr r1, =S3C2440_MPLL_400MHZ str r1, [r0] /* 启动ICACHE */ mrc p15, 0, r0, c1, c0, 0 @ read control reg orr r0, r0, #(1<<12) mcr p15, 0, r0, c1, c0, 0 @ write it back

    在u-boot-2016.05\board\samsung\smdk2440\smdk2440.c的board_early_init_f函数中将原来的时钟设置删掉:

    /* to reduce PLL lock time, adjust the LOCKTIME register */ writel(0xFFFFFF, &clk_power->locktime); /* configure MPLL */ writel((M_MDIV << 12) + (M_PDIV << 4) + M_SDIV,&clk_power->mpllcon);

    2、初始化sdram: 将u-boot-2016.05\board\samsung\smdk2440\lowlevel_init.S中原来的配置sdram的初始化数据

    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 0x00000740 //BANKCON4 .long 0x00000700 //BANKCON5 .long 0x00018005 //BANKCON6 .long 0x00018005 //BANKCON7 .long 0x008C04F4 //REFRESH .long 0x000000B1 //BANKSIZE .long 0x00000030 //MRSRB6 .long 0x00000030 //MRSRB7

    3、重定位u-boot: ①、将init.c文件添加到u-boot-2016.05\board\samsung\smdk2440文件夹中,并在该文件夹下的Makefile中末尾添上

    obj-y += init.o

    ②、在u-boot-2016.05\arch\arm\lib\crt0.S中将

    mov r0, sp bl board_init_f_alloc_reserve mov sp, r0 /* set up gd here, outside any C code */ mov r9, r0 bl board_init_f_init_reserve mov r0, #0 bl board_init_f

    替换为

    bl nand_init_ll mov r0, #0 ldr r1,= CONFIG_SYS_TEXT_BASE ldr r2,= 0x80000 bl copy_code_to_sdram bl clear_bss ldr pc, =call_board_init_f call_board_init_f: mov r0, sp bl board_init_f_alloc_reserve mov sp, r0 /* set up gd here, outside any C code */ mov r9, r0 bl board_init_f_init_reserve mov r0, #0 bl board_init_f

    注意:其中

    mov r0, #0 ldr r1,=CONFIG_SYS_TEXT_BASE ldr r2,=0x4b000

    分别是uboot重定位时的源、目的、长度。uboot的长度本想像修改u-boot-2012.04.01一样通过定义:

    .globl _bss_start_ofs _bss_start_ofs: .word __bss_start - _start

    来求得,但是失败了,具体原因还未找到,所以长度就先用稍微大于u-boot的数值。 4、配置smdk2440.h: 在u-boot-2016.05\include\configs\smdk2440.h中, ①、添加

    #define DEBUG

    以能够输出DEBUG信息。 ②、注释掉

    #define CONFIG_S3C2410 /* specifically a SAMSUNG S3C2410 SoC */ #define CONFIG_SMDK2410 /* on a SAMSUNG SMDK2410 Board */

    添加

    #define CONFIG_S3C2440 #define CONFIG_SMDK2440

    ③、修改CONFIG_SYS_TEXT_BASE的值为:

    #define CONFIG_SYS_TEXT_BASE 0x33f00000

    CONFIG_SYS_TEXT_BASE的值根据uboot的大小而定。 ④、注释掉以下暂时用不到的各项

    #define CONFIG_USB_KEYBOARD #define CONFIG_USB_STORAGE #define CONFIG_DOS_PARTITION #define CONFIG_RTC_S3C24X0 #define CONFIG_BOOTP_BOOTFILESIZE #define CONFIG_BOOTP_BOOTPATH #define CONFIG_BOOTP_GATEWAY #define CONFIG_BOOTP_HOSTNAME #define CONFIG_CMD_DATE #define CONFIG_CMD_UBI #define CONFIG_CMD_UBIFS #define CONFIG_CMD_MTDPARTS #define CONFIG_MTD_DEVICE #define CONFIG_MTD_PARTITIONS #define CONFIG_YAFFS2 #define CONFIG_RBTREE

    特别提示:CONFIG_ARM在自动配置文件include/config/auto.conf中设置为y:

    CONFIG_ARM=y

    编译u-boot时将自动配置,所以,CONFIG_ARM是宏定义了的。 5、修改u-boot.lds的代码段,使board/samsung/smdk2440和arch/arm/lib两个文件夹中的文件链接到靠前的位置

    .text : { *(.__image_copy_start) *(.vectors) CPUDIR/start.o (.text*) board/samsung/smdk2440/built-in.o (.text*) arch/arm/lib/built-in.o (.text*) *(.text*) }

    6、现在,编译并烧到开发板nand flash就应该有如下面的输出

    U-Boot 2016.05 (Aug 15 2016 - 16:00:34 +0800) CPUID: 32440001 FCLK: 400 MHz HCLK: 100 MHz PCLK: 50 MHz DRAM: 0 Bytes

    但是我们看到DRAM大小没有识别出来,现在来解决DRAM大小识别的问题,一步一步按照启动流程阅读代码,可发现

    DRAM: 0 Bytes

    的显示是在初始化函数序列init_sequence_f中的show_dram_config函数中,DRAM的大小输出的是gd->bd->bi_dram[i].size 的值,而gd->bd->bi_dram[i].size 是在同为初始化函数序列中的setup_dram_config中赋值的,如下:

    __weak void dram_init_banksize(void) { #if defined(CONFIG_NR_DRAM_BANKS) && defined(CONFIG_SYS_SDRAM_BASE) gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE; gd->bd->bi_dram[0].size = get_effective_memsize(); #endif }

    再看dram_init_banksize的反汇编代码:

    33f0ab84 <dram_init_banksize>: 33f0ab84: e5992000 ldr r2, [r9] 33f0ab88: e3a03203 mov r3, #805306368 ; 0x30000000 33f0ab8c: e92d4010 push {r4, lr} 33f0ab90: e5823048 str r3, [r2, #72] 33f0ab94: e5994000 ldr r4, [r9] 33f0ab98: eb001a42 bl 33f114a8 <get_effective_memsize> 33f0ab9c: e584004c str r0, [r4, #76] 33f0aba0: e8bd8010 pop {r4, pc}

    r9=gd=全局数据结构体的地址,经过JTAG调试发现赋值号右边的值没错,而问题是在gd->bd指针的值上,它的值并没有在sdram的地址范围内,是个无效地址,所以才没有赋值成功,gd->bd->bi_dram[i].size 总是0,gd->bd初始值是在初始化函数序列init_sequence_f中的reserve_board函数中和gd->start_addr_sp联系在一起的

    static int reserve_board(void) { if (!gd->bd) { ... gd->bd = (bd_t *)map_sysmem(gd->start_addr_sp, sizeof(bd_t)); memset(gd->bd, '\0', sizeof(bd_t)); ... } return 0; }

    而gd->start_addr_sp初始值是在初始化函数序列init_sequence_f中的reserve_uboot函数中被赋以gd->relocaddr,所以去修改gd->relocaddr的值,在 u-boot-2016.05\common\board_f.c:reserve_uboot函数中用

    gd->relocaddr = CONFIG_SYS_TEXT_BASE;

    替换

    gd->relocaddr -= gd->mon_len; gd->relocaddr &= ~(4096 - 1);

    然后编译并烧写到nand flash就可以显示DRAM的大小了。 7、board_init_r函数运行参数的准备: ①、在u-boot-2016.05\common\board_f.c:board_init_f函数中添加变量定义

    extern unsigned int new_gd;

    去掉

    #if !defined(CONFIG_ARM) && !defined(CONFIG_SANDBOX) && \ !defined(CONFIG_EFI_APP) /* NOTREACHED - jump_to_copy() does not return */ hang(); #endif

    并在函数结尾添加

    new_gd = (unsigned int)(gd->new_gd);

    其中 gd->new_gd 是在初始化函数序列init_sequence_f中的setup_reloc中赋值的,如下:

    static int setup_reloc(void) { ... memcpy(gd->new_gd, (char *)gd, sizeof(gd_t)); ... }

    ②、在u-boot-2016.05/arch/arm/lib/crt0.S中入口声明ENTRY(_main) 前面添加定义:

    .globl new_gd new_gd: .long 0

    在下面这段代码中

    /* * Set up intermediate environment (new sp and gd) and call * relocate_code(addr_moni). Trick here is that we'll return * 'here' but relocated. */ ldr sp, [r9, #GD_START_ADDR_SP] /* sp = gd->start_addr_sp */ #if defined(CONFIG_CPU_V7M) /* v7M forbids using SP as BIC destination */ mov r3, sp bic r3, r3, #7 mov sp, r3 #else bic sp, sp, #7 /* 8-byte alignment for ABI compliance */ #endif ldr r9, [r9, #GD_BD] /* r9 = gd->bd */ sub r9, r9, #GD_SIZE /* new GD is below bd */ adr lr, here ldr r0, [r9, #GD_RELOC_OFF] /* r0 = gd->reloc_off */ add lr, lr, r0 #if defined(CONFIG_CPU_V7M) orr lr, #1 /* As required by Thumb-only */ #endif ldr r0, [r9, #GD_RELOCADDR] /* r0 = gd->relocaddr */ b relocate_code

    分别去掉

    ldr r9, [r9, #GD_BD] sub r9, r9, #GD_SIZE ldr r0, [r9, #GD_RELOCADDR] b relocate_code

    然后,在下面这段代码中

    /* call board_init_r(gd_t *id, ulong dest_addr) */ mov r0, r9 /* gd_t */ ldr r1, [r9, #GD_RELOCADDR] /* dest_addr */

    去掉

    mov r0, r9 /* gd_t */

    添加

    ldr r0, new_gd

    特别注意:不要认为下面这段代码不重要,可以删掉,在尝试删掉之后出现了c文件中某些变量地址分配出现了错误,所以下面这段代码不能删除,必须保留。

    here: /* * now relocate vectors */ bl relocate_vectors /* Set up final (full) environment */ bl c_runtime_cpu_setup /* we still call old routine here */

    8、将u-boot-2016.05\common\board_r:board_init_r函数中

    #if !defined(CONFIG_X86) && !defined(CONFIG_ARM) && !defined(CONFIG_ARM64) gd = new_gd; #endif

    gd = new_gd 语句外的条件编译去掉。 9、去掉编译中的-pie参数 在u-boot-2016.05/arch/arm/config.mk中去掉

    LDFLAGS_u-boot += -pie

    此时编译u-boot会提示错误:

    Makefile:1385: recipe for target 'checkarmreloc' failed

    参考“recipe for target ‘checkarmreloc’ failed解决办法”去解决。之后编译烧写到nand flash就会正常输出了:

    U-Boot 2016.05 (Aug 22 2016 - 02:00:09 +0800) initcall: 33f0aa6c U-Boot code: 33F00000 -> 33F480E8 BSS: -> 33F92BE0 initcall: 33f0113c CPUID: 32440001 FCLK: 400 MHz HCLK: 100 MHz PCLK: 50 MHz initcall: 33f0ad18 DRAM: initcall: 33f004fc initcall: 33f0abd0 Monitor len: 00092BE0 Ram size: 04000000 Ram top: 34000000 initcall: 33f0a84c initcall: 33f0aa14 TLB table from 33ff0000 to 33ff4000 initcall: 33f0a864 initcall: 33f0a9dc Reserving 586k for U-Boot at: 33f00000 initcall: 33f0a9b0 Reserving 4160k for malloc() at: 33af0000 initcall: 33f0accc Reserving 80 Bytes for Board Info at: 33aeffb0 initcall: 33f0a86c initcall: 33f0a97c Reserving 168 Bytes for Global Data at: 33aeff08 initcall: 33f0a904 initcall: 33f0a8a0 initcall: 33f0a874 initcall: 33f0ac70 Ram size: 04000000 gd->bd->bi_dram[0].start: 30000000 gd->bd->bi_dram[0].size: 04000000 get_effective_memsize: 04000000 initcall: 33f0ab48 RAM Configuration: Bank #0: 30000000 64 MiB DRAM: 64 MiB initcall: 33f0a8e8 New Stack Pointer is: 33aefee0 initcall: 33f0ab0c initcall: 33f0aa9c Relocation Offset is: 00000000 Relocating to 33f00000, new gd at 33aeff08, sp at 33aefee0 initcall: 33f0ad94 initcall: 33f0aeac Relocating to 33f00000, new gd at 33aeff08, sp at 33aefee0 initcall: 33f0af9c (relocated to 33f0af9c) WARNING: Caches not enabled initcall: 33f0ad9c (relocated to 33f0ad9c) initcall: 33f0adc4 (relocated to 33f0adc4) initcall: 33f0af80 (relocated to 33f0af80) using memory 0x33af0000-0x33f00000 for malloc() initcall: 33f0adcc (relocated to 33f0adcc) initcall: 33f0ad70 (relocated to 33f0ad70) initcall: 33f0af6c (relocated to 33f0af6c) initcall: 33f0053c (relocated to 33f0053c) dram_bank_mmu_setup: bank: 0 initcall: 33f115a8 (relocated to 33f115a8) initcall: 33f0af5c (relocated to 33f0af5c) initcall: 33f0ae90 (relocated to 33f0ae90) Now running in RAM - U-Boot at: 33f00000 initcall: 33f0add4 (relocated to 33f0add4) initcall: 33f0aee0 (relocated to 33f0aee0) Flash: fwc addr 00000000 cmd f0 00f0 16bit x 16 bit fwc addr 0000aaaa cmd aa 00aa 16bit x 16 bit fwc addr 00005554 cmd 55 0055 16bit x 16 bit fwc addr 0000aaaa cmd 90 0090 16bit x 16 bit fwc addr 00000000 cmd f0 00f0 16bit x 16 bit JEDEC PROBE: ID f0 ea00 0 fwc addr 00000000 cmd ff 00ff 16bit x 16 bit fwc addr 00000000 cmd 90 0090 16bit x 16 bit fwc addr 00000000 cmd ff 00ff 16bit x 16 bit JEDEC PROBE: ID 90 ea00 0 0 Bytes initcall: 33f0ae74 (relocated to 33f0ae74) NAND: board_nand_init() end of nand_init dev_ready dev_ready dev_ready dev_ready 0 MiB initcall: 33f0ae44 (relocated to 33f0ae44) *** Warning - bad CRC, using default environment Destroy Hash Table: 33f42c20 table = 00000000 Create Hash Table: N=75 INSERT: table 33f42c20, filled 1/79 rv 33af50b8 ==> name="bootdelay" value="5" INSERT: table 33f42c20, filled 2/79 rv 33af4f78 ==> name="baudrate" value="115200" INSERT: table 33f42c20, filled 3/79 rv 33af4f28 ==> name="ipaddr" value="10.0.0.110" INSERT: table 33f42c20, filled 4/79 rv 33af50e0 ==> name="serverip" value="10.0.0.1" INSERT: table 33f42c20, filled 5/79 rv 33af5374 ==> name="netmask" value="255.255.255.0" INSERT: free(data = 33af4e88) INSERT: done initcall: 33f0ad84 (relocated to 33f0ad84) initcall: 33f11668 (relocated to 33f11668) initcall: 33f0ae34 (relocated to 33f0ae34) initcall: 33f0f334 (relocated to 33f0f334) In: serial Out: serial Err: serial Initial value for argc=3 Final value for argc=3 Initial value for argc=3 Final value for argc=3 Initial value for argc=3 Final value for argc=3 initcall: 33f00c6c (relocated to 33f00c6c) initcall: 33f0ae24 (relocated to 33f0ae24) initcall: 33f0ae04 (relocated to 33f0ae04) initcall: 33f0ade8 (relocated to 33f0ade8) Net: Initial value for argc=3 Final value for argc=3 CS8900-0 Error: CS8900-0 address not set. initcall: 33f0addc (relocated to 33f0addc) ### main_loop entered: bootdelay=5 ### main_loop: bootcmd="<UNDEFINED>" SMDK2440 #
    转载请注明原文地址: https://ju.6miu.com/read-1302459.html
    最新回复(0)