Uboot学习笔记

Uboot笔记

Powered By ——Dr.Miao

什么是uboot?

  1. 首先u-boot可以理解成一个大型的、复杂的裸机程序。

    2.uboot是一个bootloader,作用就是用于启动Linux或其他系统(可以理解为windows的BIOS)。Uboot最主要的工作就是初始化DDR。因为Linux是运行在DDR里面的。

uboot如何获取?

  1. 万事找厂家,有事它负责(U-Boot – DENX Software Engineering

    2.找对应芯片的SOC厂商,他们是对uboot进行了相应的芯片优化的,属于是定制版uboot

编译uboot

  1. 编译UBOOT的时候需要先配置

  2. 编译完成以后就会生成一个u-boot.bin。必须向u-boot.bin添加头部信息。Uboot编译最后会通过/tools/mkimage软件添加头部信息,生成u-boot.imx。

  3. 如果配置过uboot,那么一定要注意shell脚本会清除整个工程,那么配置的文件也会被删除,配置项也会被删除掉。

  4. 为了方便开发,建议直接在uboot顶层Makefile里面设置好ARCH和CORSS_COMPILE这两个变量的值。

Uboot命令的使用

hlep命令的使用:

  1. 查看某一个命令的帮助信息,?+ 命令名

  2. 信息查询

    • bdiofo:

    • printenv命令:

    查看当前板子环境变量

  3. setenv命令(重点)

    设置环境变量、自定义环境变量、删除环境变量(设置为空值)

  4. saveenv(重点)

    保存环境变量

内存管理命令:

  1. md命令(内存查询):

  • md.b\md.w\md.l

    2.nm命令(内存修改):

3.mm命令(自增修改内存):

4.mw命令:

5.cp命令(拷贝):

6.cmp命令:

返回值为从何处开始不相等

网络操作命令(重点)

ping命令(重点)

setenv addrip ip地址(设置开发板的IP,注意:网段一定要与设置的网卡IP保持一致)

setenv ethaddr XXX(设置MAC)

setenv gatewayip 192.168.1.1(网关)

setenv netmask 255.255.255.0(子网掩码)

setenv serverip 192.168.XXX.XXX(服务器地址)

NFS命令(重点)

目的:方便调试代码

  • 首先在Ubuntu服务器下安装好nfs的服务端

  • 之后按照流程配置网卡、uboot的IP(一定要在同一个网段下,可以不设置网关)

  • nfs服务器版本一定要对(配置如下):

tftp命令(重点)

等同于nfs,主要是配置服务器端

mmc及文件操作命令

  1. mmc命令:

    2.FAT 格式文件系统操作命令:

对于 I.MX6U 来说,SD/EMMC 分为三个分区: 第一个:存放 uboot 第二个:存放 Linux zImage,.dtb。FAT 第三个:系统的根文件系统,EXT4

  • fatinfo命令

  • fatls

  • fstype(格式查看)

  • fatload命令(重要)

    3.EXT格式:

BOOT操作指令

1、booz 命令 要启动 Linux 必须将 zImage,dtb 放到 DRAM。

bootz 80800000 - 83000000

2、bootm 命令

3、boot 命令

setenv bootcmd 'tftp 80800000 zImage;tftp 83000000 imx6ull....;bootz 80800000 - 83000000;'

saveenv

boot

其他指令

1、reset 命令

2、go 命令(可以跳转到执行裸机程序)

3、run命令:

        run 命令用于运行环境变量中定义的命令,比如可以通过“run bootcmd”来运行 bootcmd 中的启动命令

Uboot源码分析

        要分析一定要分析编译后的Uboot

(压缩编译后的uboot并解压缩到Windows)

1.u-boot.lds就是整个uboot的连接脚本:

2.board\freescale\mx6ullevk(重点)

3.configs(Miao_uboot/configs)目录是uboot的默认配置文件。此目录下都是以defconfig结尾的。这些文件对应不同的板子

4.移植uboot的时候一定要重点关注:

board\freescale

./configs

5.当我们执行 make xxx_ defconfig 以后就会生成.config 文件,此文件保存了详细的 uboot 配置信息。

6.顶层 READ.ME,非常重要,介绍 uboot,包含其用法。

7.u-boot。这个就是编译出来带 ELF 信息的 uboot 可执行文件。

顶层Makefile文件分析

1.创建VSCODE工程文件,便于分析,配置工作区,将不必要的文件屏蔽

2.Mkefile流程研究(重点):

  • make distclean

  • make XXX_defconfig规则(复杂、多看、看不懂正常):

    解析:

    1、目标为 scripts_basic scripts_basic:

    $(Q)$(MAKE) $(build)=scripts/basic
    展开以后就是:
    make -f ./scripts/Makefile.build obj= scripts/basic
    build 定义在 scripts\Kbuild.include
    build := -f $(srctree)/scripts/Makefile.build obj
    build := -f ./scripts/Makefile.build obj

    2、outputmakefile, 因为 KBUILD_SRC,因此 outputmakefile 无效。 最终要执行的命令

    make -f ./scripts/Makefile.build obj=scripts/basic
    · Make -f ./scripts/Makefile.build obj=scripts/kconfig xxx_defconfig

第一条命令:

  src = scripts/basic
  kbuild-dir = ./scripts/basic
  kbuild-file = ./scripts/basic/Makefile
  include ./scripts/basic/Makefile
  __build: $(if $(KBUILD_BUILTIN),$(builtin-target) $(lib-target) $(extra-y)) \
  $(if $(KBUILD_MODULES),$(obj-m) $(modorder-target)) \
  $(subdir-ym) $(always)
  @:
  
  __build: $(builtin-target) $(lib-target) $(extra-y) $(subdir-ym) $(always)
  @:
  scripts/basic/fixdep
  
  __build: scripts/basic/fixdep

因此需要编译出 scripts/basic/fixdep,对应的.c 是 scripts/basic/fixdep.c,

第二条命令:

  Make -f ./scripts/Makefile.build obj=scripts/kconfig xxx_defconfig
  src = scripts/kconfig
  kbuild-dir = ./scripts/ kconfig
  kbuild-file = ./scripts/ kconfig/Makefile
  include ./scripts/kconfig/Makefile
  %_defconfig: $(obj)/conf
  $(Q)$< $(silent) --defconfig=arch/$(SRCARCH)/configs/$@ $(Kconfig)
  xxx_defconfig: scripts/kconfig/conf
  $(Q)$< $(silent) --defconfig=arch/$(SRCARCH)/configs/$@ $(Kconfig)
  scripts/kconfig/conf --defconfig=arch/../configs/ xxx_defconfig Kconfig
  • make V = 1 -j12

    默认目标 PHONY := _all

    _all:

    _all: all

    all: $(ALL-y)

    ALL-y += u-boot.srec u-boot.bin u-boot.sym System.map u-boot.cfg binary_size_check
    u-boot.bin: u-boot-nodtb.bin FORCE
    $(call if_changed,copy)
    u-boot-nodtb.bin: u-boot FORCE
    $(call if_changed,objcopy)
    $(call DO_STATIC_RELA,$<,$@,$(CONFIG_SYS_TEXT_BASE))
    $(BOARD_SIZE_CHECK)
    u-boot: $(u-boot-init) $(u-boot-main) u-boot.lds FORCE
    $(call if_changed,u-boot__)
    u-boot-init := $(head-y)
    u-boot-main := $(libs-y)
    head-y= arch/arm/cpu/armv7/start.o
    libs-y=保存源码的目录
        
    libs-y += lib/ -> lib/built-in.o # 把lib/替换为lib/build-in.o
        
    libs-y 保存大量的 built-in.o
    u-boot 就是将 start.o 和大量的 built-in.o 链接在一起。

    假如: CONFIG_ONENAND_U_BOOT =y ALL-$(CONFIG_ONENAND_U_BOOT) ALL-y += u-boot-onenand.bin

3.链接:

链接脚本为 u-boot.lds,uboot 链接首地址为 0X87800000,

在 mx6_common.h 文件中设置 CONFIG_SYS_TEXT_BASE=0X87800000

Uboot启动流程详解

1、从 u-boot.lds (链接)可知,uboot 入口地址为_start

image_copy_start-> 0x87800000

.vetcors -> 0x87800000 存放中断向量表 arch/arm/cpu/armv7/start.o start.c

image_copy_end -> 0x8785dc6c

_rel_dyn_start -> 0x8785dc6c #rel 段 _rel_dyn_end -> 0x878668a4

_end -> 0x878668a4

_image_binary_end -> 0x878668a4

_bss_start -> 0x8785dc6c #bss 段。 _bss_end -> 0x878a8d74

2、uboot启动流程(多看):

1、reset 函数

bicne=bic + ne ①、reset 函数目的是将处理器设置为 SVC 模式,并且关闭 FIQ 和 IRQ. ②、设置中断向量。 ③、初始化 CP15 ④、调用_lowlevel_init和 _main

2、lowlevel_init 函数

CONFIG_SYS_INIT_SP_ADDR #define CONFIG_SYS_INIT_SP_ADDR \ (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_SP_OFFSET)

#define CONFIG_SYS_INIT_SP_OFFSET \ (CONFIG_SYS_INIT_RAM_SIZE - GENERATED_GBL_DATA_SIZE) #define CONFIG_SYS_INIT_RAM_SIZE IRAM_SIZE #define IRAM_SIZE 0x00020000 #define CONFIG_SYS_INIT_RAM_ADDR IRAM_BASE_ADDR #define IRAM_BASE_ADDR 0x00900000 6ULL 内 部 OCRAM #define GENERATED_GBL_DATA_SIZE 256 0x00900000 + CONFIG_SYS_INIT_SP_OFFSE => 0x00900000 + CONFIG_SYS_INIT_RAM_SIZE - GENERATED_GBL_DATA_SIZE => 0x00900000 + 0x00020000 – 256 = 0x0091ff00 设置 SP 指针、R9 寄存器

3、s_init 函数

空函数。

4、_main 函数

5、board_init_f 函数

initcall_run_lis 此函数会调用一系列的函数,这些函数保存在 init_sequence_f 数组 里面, version_string[] = U_BOOT_VERSION_STRING #define U_BOOT_VERSION_STRING U_BOOT_VERSION " (" U_BOOT_DATE " - " \ U_BOOT_TIME " " U_BOOT_TZ ")" CONFIG_IDENT_STRING U_BOOT_VERSION = U-Boot 2016.03 TOTAL_MALLOC_LEN (CONFIG_SYS_MALLOC_LEN + CONFIG_ENV_SIZE) CONFIG_SYS_MALLOC_LEN (16 * SZ_1M) CONFIG_ENV_SIZE SZ_8K

mx6ullevk.c mx6ullevk.h 这两个文件长打交道

6、relocate_code 函数

作用:

①、初始化一系列外设,比如串口、定时器,或者打印一些消息等。

②、初始化 gd 的各个成员变量,uboot 会将自己重定位到 DRAM 最后面的地址区域,也就是将自己拷贝到 DRAM 最后面的内存区域中。这么做的目的是给 Linux 腾出空间,防止 Linuxkernel 覆盖掉 uboot,将 DRAM 前面的区域完整的空出来。

relocate_code 函数有一个参数,r0=gd->relocaddr=0X9FF47000,uboot 重定位后的首地址。 r1=0X87800000 源地址起始地址。 r4=0X9FF47000-0X87800000=0X18747000 偏移。 r2=0x8785dc6c 当简单粗暴的将 uboot 从 0X87800000 拷贝到其他地方以后,关于函数调用、全局变量引用就会出问题。Uboot 对于这个的处理方法就是采用位置无关码,这个就需要借助于.rel.dyn 段。

8785dcf8 <rel_a>: 8785dcf8: 00000000 andeq r0, r0, r0 878042b4 <rel_test>: 878042b4: e59f300c ldr r3, [pc, #12] ; 878042c8 <rel_test+0x14> 878042b8: e3a02064 mov r2, #100 ; 0x64 878042bc: e59f0008 ldr r0, [pc, #8] ; 878042cc <rel_test+0x18> 878042c0: e5832000 str r2, [r3] 878042c4: ea00d64c b 87839bfc <printf> 878042c8: 8785dcf8 ; <UNDEFINED> instruction: 0x8785dcf8 878042cc: 87842aaf strhi r2, [r4, pc, lsr #21] 设置 r3 为 878042b4+8+12=878042c8 的值,r3=8785dcf8。这里并没有直接去读 取 rel_a 的地址,而是借助了 878042c。 878042c8 叫做 Label。 重定位以后 9ffa4cf8 <rel_a>: 9ffa4cf8: 00000000 andeq r0, r0, r0 9ff4b2b4<rel_test>: 9ff4b2b4: e59f300c ldr r3, [pc, #12] ; 878042c8 <rel_test+0x14> 9ff4b2b8: e3a02064 mov r2, #100 ; 0x64 9ff4b2bc: e59f0008 ldr r0, [pc, #8] ; 878042cc <rel_test+0x18> 9ff4b2c0: e5832000 str r2, [r3] 9ff4b2c4: ea00d64c b 87839bfc <printf>

9ff4b2c8: 8785dcf8 ; <UNDEFINED> instruction: 0x8785dcf8 9ff4b2cc: 87842aaf strhi r2, [r4, pc, lsr #21] Label 中 的 值 还 是 原 来 的 ! 必 须 要 将 8785dcf8 换 为 重 定 位 后 的 rel_a 地 址 。 读 取 9ff4b2c8 里 面 的 数 据 , 也 就 是 老 的 rel_a 的 地 址 =8785dcf8+0x18747000=0x9ffa4cf8 重定位以后,需要对所有的 Label 保存的数据加上偏移!! 8785dcec: 87800020 strhi r0, [r0, r0, lsr #32] 8785dcf0: 00000017 andeq r0, r0, r7, lsl r0 ...... 8785e2fc: 878042c8 strhi r4, [r0, r8, asr #5] 8785e300: 00000017 andeq r0, r0, r7, lsl r0 878042c8+offset = 读取新的 Label 处的数据+offset 完成这个功能在连接的时候需要加上”-pie”

7、relocate_vectors 函数

设置 VBAR 寄存器为重定位后的中断向量表起始地址。

8、board_init_r 函数

Board_init_r 函 数 和 board_init_f 函 数 很 类 似 。 board_init_r 也 是 执 行init_sequence_r 初始化序列。

9、run_main_loop 函数

run_main_loop -> main_loop -> bootdelay_process 获 取 bootdelay 的 值 , 然 后 保 存 到stored_bootdelay 全局变量里面,获取 bootcmd 环境变量值,并且将其返回 -> autoboot_command 参数是 bootcmd 的值。 -> abortboot 参数为 boot delay,此函数会处理倒计时 -> abortboot_normal 参数为 boot delay,此函数会处理倒计时 -> cli_loop uboot 命令模式处理函数。 -> parse_file_outer -> parse_stream_outer -> parse_stream 解析输入的字符,得到命令 -> run_list 运行命令

-> run_list_real -> run_pipe_real -> cmd_process 处理命令,也就是执行命令

10、cli_loop 函数

11、cmd_process 函数

Uboot 使用 U_BOOT_CMD 来定义一个命令。CONFIG_CMD_XXX 来使能 uboot 中的某个命令。 U_BOOT_CMD 最终是定义了一个 cmd_tbl_t 类型的变量,所有的命令最终都是存放在.u_boot_list 段里面。cmd_tbl_t 的 cmd 成员变量就是具体的命令执行函数,命令执行函数都是 do_xxx。 cmd_process ->find_cmd 从.u_boot_list 段里面查找命令,当找到对应的命令以后以返回值的形式给出,为 cmd_tbl_t 类型 ->cmd_call ->cmdtp->cmd 直接引用 cmd 成员变量

3、bootz启动Linux内核的过程

Uboot 启动 Linux 内核使用 bootz 命令,bootm。。bootz 是如何启动 Linux 内核?uboot 的生命是怎么终止的呢?linux 又是怎么启动的呢?

1、images(保存镜像信息)全局变量

bootm_headers_t images;

2、do_bootz 函数(重点):

tftp 80800000 zImage
tftp 83000000 imx6ull-14x14-emmc-7-1024x600-c.dtb
#tftp下载
bootz 80800000 - 83000000
#启动!!!

bootz 命令的执行函数,do_xxxx,do_bootz 是 bootz 的执行函数。 分析do_bootz调用函数: 1.-> bootz_start: -> do_bootm_states 阶段为 BOOTM_STATE_START -> bootm_start #对 images 全局变量清零 -> images->ep = 0X80800000 #设置入口地址 ->bootz_setup #判断 zImage 是否正确(与后文的zimage_header相关) -> bootm_find_images · -> boot_get_fdt #找 到 设 备 树 , 然 后 将 设 备 树 起 始 地 址 和 长 度 , 写 入 到images的 ft_addr 和 ft_len 成员变量中。 -> 2.bootm_disable_interrupts:关闭中断相关 -> images.os.os = IH_OS_LINUX; #表示要启动 Linux 系统 -> 3.do_bootm_states:状 态 BOOTM_STATE_OS_PREP、BOOTM_STATE_OS_FAKE_GO 、BOOTM_STATE_OS_GO, -> bootm_os_get_boot_func #查找 Linux 内核启动函数。找到 Linux 内核启动函数do_bootm_linux,赋值给 boot_fn。 -> boot_fn #(BOOTM_STATE_OS_PREP, argc, argv, images); 就是do_bootm_linux。 -> boot_prep_linux #启动之前的一些工作,对于使用设备树来说,他会将Bootargs 传递给 Linux 内核,通过设 备树完成。也就是向Linux内核传参。

-> boot_selected_os BOOTM_STATE_OS_GO, do_bootm_linux -> do_bootm_linux,BOOTM_STATE_OS_GO -> boot_jump_linux -> machid= gd->bd->bi_arch_number; #获取机器id -> void (kernel_entry)(int zero, int arch, uint params); -> kernel_entry = (void ()(int, int, uint))images->ep; #kernel_entry地址:0X80800000。 -> announce_and_cleanup #输出 Starting kernel...... -> kernel_entry(0, machid, r2); #启动 Linux 内核。Uboot 的最终使命,启动 Linux 内核。

zimage_header 的 zi_magic 为 zimage 的幻数,魔术数。应该为 0x016f2818。前面有 9 个 32 位的数据,那么 9*4=36,0~35,第 36 个字节的数据开始就是 zimage 的幻数

Uboot移植

一、NXP官方Uboot编译与测试

将NXP提供的uboot拷贝到ubuntu中。一个开发板也好运行uboot,DDR或者叫DRAM,串口,SD、EMMC、NAND。板子能工作。

测似结果:

1、uboot能正常启动

2、LCD驱动要根据所使用的屏幕修改。

3、NET初始化失败。

二、移植 NXP 官方 uboot 到 ALPHA 开发板

2.1 添加板子默认配置文件

借鉴 NXP 官方 6ULL EVK 开发板,默认配置文件也用他的

2.2 添加板子对应的头文件

不同的板子,有一些需要配置的信息,一般是在一个头文件里面配置,每个板子有一个。对于 NXP 官方的 6ULL EVK 板子,这个头文件就是:

2.3 添加板子对应的板级文件夹

每个板子都有特有的文件,也叫做板级文件(在board文件夹下)。这里我们将 6ULL EVK 的板级文件直接拷贝过来。

要修改的文件:

1./board/freescale/mx6ullevk复制一份重命名为mx6ull_miao_emmc(自定义)

2.更改其中的imximage.cfg、Kconfig、Makefile、mx6ullevk(重命名为mx6ull_miao_emmc)

3./include/configs:复制imx6ullevk.h文件重命名为mx6ull_miao_emmc.h

2.4 修改 uboot 的配置界面

2.5 使用新添加的板子配置并编译 Uboot

2.6 LCD 驱动修改

1、确定 LCD IO 初始化正确,mx6ull_alientek_emmc.c 中的 lcd_pads。

2 、 LCD 参 数 ,mx6ull_alientek_emmc.c 中 的 displays 。 fb_videomode 表 示RGB LCD 参数。

MX6ULL_LCDIF1_BASE_ADDR (=AIPS2_OFF_BASE_ADDR + 0x48000) AIPS2_OFF_BASE_ADDR (=ATZ2_BASE_ADDR + 0x80000) ATZ2_BASE_ADDR AIPS2_ARB_BASE_ADDR AIPS2_ARB_BASE_ADDR = 0x02100000 MX6ULL_LCDIF1_BASE_ADDR = 0x02100000 + 0x80000 + 0x48000 =0x21c8000

Panel 环境变量(mx6ull_miao_emmc.h里面全都要改成对应的屏幕代号)表示 LCD ID。

查看使用的屏幕手册对照着改动

2.7 网络驱动修改(重点)

6ULL 网络方案采用内部 MAC+外部 PHY,6ULL 官方开发板使用的 PHY 芯片就是KSZ8081。正点原子的 ALPHA 开发板没有使用 KSZ8081,我们使用的 LAN8720A。因此要修改驱动。

LAN872 有一个管理接口,叫做 MDIO,两根线,MDIO 和 MDC,一个 MDIO 接口,可以管理 32 个 PHY 芯片。MIDO 通过 PHY ADDR 来确定访问那个 PHY 芯片(双路选择)。ALPHA 开发板 ENET1 的 PHY ADDR 是 0x0,ENET2 的 PHY ADDR 是 0X1.

每 个 LAN8720 都 有 一 个 复 位 引 脚 , ENET1 是 SNVS_TAMPER7 ,ENET12是 SNVS_TAMPER78。

LAN8720 驱动,因为所有的 PHY,其前 32 个寄存器一模一样,因此 uboot 里面已经写好了通用 PHY 驱动,所以理论上不需要修改(国际联盟标准)。

驱动修改: 1、修改 PHY ADDR:

找到想要使用的网口:

2、删除原有的 74LV595 相关代码。

在.c文件中

3、添加 ALPHA 开发板的网络复位 IO:

fec1_pads:描述网口一的数组

fec2_pads:描述网口二的数组

找到函数setup_iomux_fec()在其中添加网口复位代码:

之后找到文件/drivers/net/phy/phy.c中,修改函数genphy_update_link()。添加lan8720驱动复位代码:

2.8 其他需要修改的地方

三、bootcmd 和 bootargs 环境变量(.h文件中)

3.1 bootcmd 环境变量

宏 CONFIG_BOOTCOMMAND 也可以设置 bootcmd 的值。

/脚本/

"run findfdt;" \ "mmc dev ${mmcdev};" \ "mmc dev ${mmcdev}; if mmc rescan; then " \ "if run loadbootscript; then " \ "run bootscript; " \ "else " \ "if run loadimage; then " \ "run mmcboot; " \ "else run netboot; " \ "fi; " \ "fi; " \ "else run netboot; fi"

Findfdt 设置 fdt_file 环境变量,也就是 dtb 文件名字。

mmc dev 1 //切换到 emmc

fatload mmc 1:1 80800000 zImage fatload mmc 1:1 83000000 imx6ull-14x14-evk.dtb booz 80800000 - 83000000

解释:

"loadbootscript=" \ "fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${script};\0" \

展开:fatload mmc 1:1 80800000 boot.scr(与上面的fatload mmc相对应)

loadimage=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${image}\0" \

展开:fatload mmc 1:1 80800000 zImage(与上面的loadimage相对应)

"loadfdt=fatload mmc ${mmcdev}:${mmcpart} ${fdt_addr} ${fdt_file}\0" \

展开:fatload mmc 1:1 83000000 imx6ull-14x14-evk.dtb(与上面的loadfdt相对应)

bootz ${loadaddr} - ${fdt_addr}; 展开:booz 80800000 - 83000000

3.2 bootargs 环境变量

宏 CONFIG_BOOTARGS 也可以设置 bootargs 的值 mmcargs=setenv bootargs console=${console},${baudrate} " \ CONFIG_BOOTARGS_CMA_SIZE \ "root=${mmcroot}\0" \

展开以后就是: bootargs console= ttymxc0,115200 root=/dev/mmcblk1p2 Bootargs #是会传递给 Linux 内核,设置了一些东西 Bootargs #环境变量也叫做命令行参数。

四、uboot 启动 Linux 测试

4.1 从 EMMC 启动

1、首先查看 EMMC 里面是否有系统,linux 镜像 zImage 和.dtb 文件。先将当前设备切换到 EMMC:mmc dev 1 //切换到 EMMC。 ​

fatls mmc 1:1 //查看 EMMC 分区 1 里面的文件 ​

fatload mmc 1:1 80800000 zImage //将 zimage 下载到 DDR 的 0x80800000 处 ​

fatload mmc 1:1 83000000 imx6ull-14x14-emmc-7-1024x600-c.dtb // 将 dtb 读取到 0X83000000 ​

bootz 80800000 – 83000000 //启动内核 ​

如果内核启动成功,说明 uboot 支持 emmc 启动,验证成功。

4.2 从网络启动

tftp 80800000 zImage //从 tftp 服务器下载 zimage ​

tftp 83000000 imx6ull-14x14-emmc-7-1024x600-c.dtb // 从 tftp 服 务 器 下载.dtb ​

bootz 80800000 – 83000000 //启动系统

五、uboot DDR 初始化

1、裸 机

imxdownload 软件下载,会在 bin 文件头部添加 IVT DCD 数据,

2、uboot

uboot 编译生成 u-boot.imx。u-boot.imx 已经包含了 IVT DCD 数据。 u-boot.imx 的头部信息是怎么添加的? u-boot.imx 的 DCD 中的 DDR 初始化代码该怎么修改。

uboot 编译会输出: ./tools/mkimage -n board/freescale/mx6ull_alientek_emmc/imximage.cfg.cfgtmp -T imximage -e 0x87800000 -d u-boot.bin u-boot.imx

可 以 看 出 uboot 使 用 /tools/mkimage 工 具 , 向 u-boot.bin 添加:board/freescale/mx6ull_alientek_emmc/imximage.cfg.cfgtmp 文件信息,从而得到 u-boot.imx。

默认只有 imximage.cfg 文件,imximage.cfg 里面保存的就是 DCD 数据。DDR 初始化也此文件里面。我们要修改 DDR 初始化代码,就需要修改 imximage.cfg 文件。此文件默认拷贝的NXP 给 IMX6ULL EVK 开发板写的,默认是给 512MB DDR3L 写的。

修改DDR的校准值和初始化使用工具(在裸机实验中DDR章节一致)

总结:

至此Uboot的移植部分基本结束,学完了这一部分之后其实还是一脸懵,但是有一点就是学会了,了解了整个uboot启动移植的流程,大概清楚了对应部分应该如何修改代码,只是还需要后续再去理解对应部分的函数该如何修改.

Uboot图形化配置

一、Uboot 图形化配置方法

1、通过终端配置。 2、进入到 uboot 的源码根目录下。 3、首先默认配置: make mx6ull_alientek_emmc_defconfig(make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- mx6ull_alientek_emmc_defconfig) //默认配置 4、输入 make menuconfig。打开图形化配置界面。

5、注意,新电脑需要安装 ncurses 库。

ncurses 库:

图形化配置界面对于一个功能的编译,或者叫做选择有 3 种模式: Y:对应的功能编译进入uboot 里面。 N:对应的功能不编译进uboot 里面 M:将对应的功能编译为模块,以.ko结尾,Linux 内核里面常用。 当我们配置好以后,需要保存一下自己的配置文件。

二、menuconfig 图形化配置原理

Kconfig 文件,uboot 源码根目录下的 Kconfig。Kconfig 文件就是图形化界面配置文件。 2.1 mainmenu 主菜单,

2.2 调用子目录下的 Kconfig source “xxx/Kconfig”

2.3 menu/endmenu 这两个之间是子菜单。

2.4 choice/endchoice 多选一。

2.5 config 条目 Config 条 目 都 是 以 config 条 目 开 头 的 。 后 面 紧 跟 着 配 置 项 , 比 如LOCALVERSION , 使 能 了 条 目 以 后 就 会 在 .config 里 面 生 成: CONFIG_LOCALVERSION=y。

2.6 depends on 和 select 当选中某一项以后,select 对应的项目都会选中。 Depends on 指定的项目要先被·选中,否则指定的项目不能选择。

2.7 menuconfig

三、添加自定义菜单

图形化配置工具的主要工作就是在.config下面生成前缀为“CONFIG”的变量,这些变量一般都要值,为 y,m 或 n,在 uboot 源码里面会根据这些变量来决定编译哪个文件。自定义菜单要求如下:

  1. 在主界面中添加一个名为“My test menu”,此菜单内部有一个配置项。

  2. 配置项为“MY_TESTCONFIG”,此配置项处于菜单“My test menu”中。

  3. 配置项的为变量类型为 bool,默认值为 y。

  4. 配置项菜单名字为“This is my test config”。

  5. 配置项的帮助内容为“This is a empty config, just for tset!”。

总结:

关于Uboot的学习到这里就基本结束了,个人感觉学习下来,还是觉得uboot在嵌入式方向来说还是非常重要的,他是移动设备移植系统的必经之路,关于她的改写与移植是非常复杂的,所以特别要感谢Uboot开源官方给我们提供的底层,让我们能更多地关注上层代码的改写与移植。

关于温习方面,我感觉需要重点关注一下uboot顶层Makefile中的文件以及启动流程中的那些功能函数。

——全文参

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

喝水只喝纯净水

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值