微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > ARM技术讨论 > 移植uboot2012 10 串口无输出

移植uboot2012 10 串口无输出

时间:10-02 整理:3721RD 点击:
按照嵌入式linux学习手册移植uboot到ok6410后串口输出,会是什么问题呢(排除硬件还有端口号问题。)

希望帮到你
Ok6410 Uboot nand_spl 分析
1.这次分析是基于 uboot 2012.10 和 uboot 2013.01.01 的。
2.做这个分析主要是因为网上关于这方面资料比较少(反正我当时遇到困难) 。
3.文章主要参考宁静致远的《嵌入式 linux 学习手册》
4.初次移植 uboot 或正在移植 uboot 但没有输出信息的可以参考一下
一、uboot 的组成
我们知道新的 uboot 有两部分组成:nand_spl 目录下的 u-boot-spl-16k.bin 和顶层
目录下的 u-boot。第一部分由硬件自动拷贝到片内 sram 中运行,第二部分由第
一部分代码拷贝到 ram 中运行。
二.代码分析
在顶层 Makefile 中有这样一段代码

  1. nand_spl: $(TIMESTAMP_FILE) $(VERSION_FILE) depend
  2. $(MAKE) -C nand_spl/board/$(BOARDDIR) all
  3. $(obj)u-boot-nand.bin: nand_spl $(obj)u-boot.bin
  4. cat $(obj)nand_spl/u-boot-spl-16k.bin $(obj)u-boot.bin 》
  5. $(obj)u-boot-nand.bin

复制代码


说明我们 nandflash 启动的 uboot 依赖于 nand_spl u-boot.bin 两个目标, 而 nand_spl
正是要进入 nand_spl/board/$(BOARDDIR),然后 make ,BOARDDIR 的值可以
查到:在顶层目录下 config.mk 中有

  1. ifdef VENDOR
  2. BOARDDIR = $(VENDOR)/$(BOARD)
  3. else
  4. BOARDDIR = $(BOARD)
  5. Endif

复制代码


厂商为 samsung,板为 smdk6410,所以要进入”nand_spl/board/samsung/smdk6410 “make
打开该目录下的 Makefile
我们可以看到
SOBJS = start.o cpu_init.o lowlevel_init.o
COBJS = nand_boot.o nand_ecc.o s3c64xx.o smdk6410_nand_spl.o nand_base.o
对这几个文件编译连接等处理之后就得到我们要的 u-boot-spl-16k.bin, 而这几个文件哪
里来?其实都是从其他文件链接过来的(什么叫链接?不懂百度一下吧) ,我们
看到有熟悉的 start.S,lowlevel.S 等,这些文件在第二阶段的代码中要用到,但
是通过宏开关, 使编译过程不一样, 得到的代码也有不小差异, 下面就来进行具
体的分析
打开 start.S
在 bl lowlevel_init /* go setup pll,mux,memory */之前
与《嵌入式 linux 学习手册》中讲的是一样的,接下来

  1. call_board_init_f:
  2. ldr sp, =(CONFIG_SYS_INIT_SP_ADDR)
  3. bic sp, sp, #7 /* 8-byte alignment for ABI compliance */
  4. ldr r0,=0x00000000
  5. bl board_init_f

复制代码


这个 board_init_f 函数就不是 board.c 中的了,因为编译链接时,board.c 根本就没参与进来,
在这里这个函数是在 smdk6410_nand_spl.c 中,

  1. void board_init_f(unsigned long bootflag)
  2. {
  3. relocate_code(8*1024, NULL,CONFIG_SYS_TEXT_BASE);
  4. }

复制代码


打开 config.mk
有:include $(TOPDIR)/board/$(BOARDDIR)/config.mk
打开/board/samsung/smdk6410/config.mk
有:

  1. ifndef CONFIG_NAND_SPL
  2. CONFIG_SYS_TEXT_BASE = $(RAM_TEXT) # RAM_TEXT=57e00000
  3. else
  4. CONFIG_SYS_TEXT_BASE = 0
  5. Endif

复制代码


有没有定义 CONFIG_NAND_SPL 呢?
搜索时没有发现 define XX 的
但是在 nand_spl/board/samsung/smdk6410 的 Makefile 中有
AFLAGS += -DCONFIG_NAND_SPL
CFLAGS += -DCONFIG_NAND_SPL -ffunction-sections
Gcc 编译规则中有说
gcc 编译的时候提供了预定义功能,参数是-D, 通过 man gcc 可以了解更多:
-D name
Predefine name as a macro, with definition 1.
-D name=definition
Predefine name as a macro, with definition definition. The
contents of definition are tokenized and processed as if they appeared
during translation phase three in a #define directive. In particular,
the definition will be truncated by embedded new-line characters.
就是说加参数-D name 就相当于#define name
这样 CONFIG_SYS_TEXT_BASE = 0
接着又回到 start.S 的 relocate_code
R2 的值就是函数的第三个参数的值,即为 0,直接跳到 clear_bss

  1. .globl relocate_code
  2. relocate_code:
  3. mov r4, r0 /* save addr_sp */
  4. mov r5, r1 /* save addr of gd */
  5. mov r6, r2 /* save addr of destination */ //CONFIG_SYS_TEXT_BASE
  6. /* Set up the stack */
  7. stack_setup:
  8. mov sp, r4
  9. adr r0, _start
  10. cmp r0, r6
  11. moveq r9, #0
  12. beq clear_bss //执行到这里
  13. mov r1, r6
  14. ldr r3, _bss_start_ofs
  15. add r2, r0, r3

复制代码


////////////////////////////////////////////我是无敌分界线///////////////////////////////////////////////////////////////////////
清完 bss 之后就跳到_nand_boot,拷贝第二阶段的代码到 ram,然后跳到 ram 中执行
三、启动无信息原因
我总结了下:
1、/nand_spl/board/samsung/smdk6410/config.mk
PAD_TO := $(shell expr $$[$(CONFIG_SYS_TEXT_BASE) + 8192])
8192(原版是 4096)就是 u-boot-spl-16k.bin 的大小,到时会从 8192 之后复制代码
到 ram 中执行,如果第一阶段代码太多,超过 4K,又没有修改成 8192(或则大
于第一阶段代码) ,则复制的代码不是开头不是第二阶段代码的开头
2.在 lowlevel.S 中有

  1. //#ifndef CONFIG_S3C6410
  2. ldr r1, [r0, #OTHERS_OFFSET]
  3. bic r1, r1, #0xC0
  4. orr r1, r1, #0x40
  5. str r1, [r0, #OTHERS_OFFSET]
  6. wait_for_async:
  7. ldr r1, [r0, #OTHERS_OFFSET]
  8. and r1, r1, #0xf00
  9. cmp r1, #0x0
  10. bne wait_for_async
  11. //#endif

复制代码


要将//#ifndef CONFIG_S3C6410 注释掉,具体为什么?好像没有定义 CONFIG_S3C6410

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top