【嵌入式Linux驱动进阶】U-boot 学习

I.MX6UL启动方式

通过设置i.MX6UL启动相关引脚的电平状态来改变芯片的启动方式。 BOOT_MODE[1:0] = 10B ,i.MX6UL将会从“内部”启动,所谓“内部”是相对于“Serial Download”来说的, “内部”可以认为是i.MX6UL支持的启动存储设备,例如emmc、nandflash、SD card、norFlash等等。 具体从那种“内部”设备启动,由BOOT_CFG1[7:4]决定,如下表所示。

BOOT_CFG1[7:4]Boot Device
0000NOR/O呢NAND(EIM)
0001QSPI(norFlash启动)
0011Serial ROM(SPI)
010xSD/eSD/SDXC(SD卡启动)
011xMMC/eMMC(eMMC启动)
1xxxRaw NAND(nandFlash启动)

在这里插入图片描述

烧写系统

  • 在window下烧写,通过mfgtool这个工具,先将Linux系统烧写到DDR中,再烧写到EMMC或NAND中
    • mfgtool这个工具会将uboot、zImage、rootfs全部烧写,所以后期当我们只更新一个uboot,可能全部都再重新烧录,这个可能就是mfgtool一个最大的缺点了。
    • 解决方案1:mfgtool单独创建一个.vbs文件只烧写uboot
    • 解决方案2:uboot.bin使用imxdownload脚本烧写到SD卡中(带有调试性质的开发,这样比较方便。)./imxdownload u-boot.bin /dev/sdf
  • 在Ubuntu下少些,通过脚本,先将Linux系统烧写到SD卡中,再烧写到EMMC或NAND中

烧写系统时SD卡注意事项

  • SD卡一定要是FAT32格式!
  • 如何确定SD卡?
    • ls /dev/sd* 比如出现sdf、sdf1,那就是sdf了
    • sudo fdisl -l 也可以查看到对应分区
  • 将文件拷贝到SD卡中需要等待系统进行缓存同步,这段时间不确定,所以最好直接在命令行输入sync进行手动同步

uboot介绍

  • uboot就是一个bootloader,作用就是用于启动Linux或其他系统。
  • Uboot最主要的工作就是初始化DDR,因为Linux是运行在DDR里面的。
  • 一般Linux镜像zImage(uImage)+设备树(.dtb)存放在SD、EMMC、NAND、SPI FLASH等等外置存储区域。这就需要将Linux镜像从外置flash拷贝到DDR中,再去启动。
    • Uboot不仅仅能启动Linux,也可以启动其他系统;Linux不仅仅能通过uboot启动。

uboot获取

  • 首先就是uboot官网,缺点就是支持少,比如某一款具体芯片驱动等不完善。
  • SOC厂商会从uboot官网下载某一个版本的uboot,然后在这个版本的uboot上加入相应的SOC以及驱动,这就是SOC厂商定制版的uboot。
    • 做开发板的厂商会参考SOC厂商的板子,开发板必然会和官方的板子不一样。因此开发板厂商又会去修改SOC厂商做好的uboot,以适应自己的板子。

uboot编译

  • 为了方便开发,建议直接在uboot顶层Makefile里面设置好ARCH和CORSS_COMPILE这两个变量的值。
  • 编译UBOOT的时候需要先配置。
    • 图形界面配置
    • 源码配置
  • 编译完成以后就会生成一个u-boot.bin。必须向u-boot.bin添加头部信息。Uboot编译最后会通过/tools/mkimage软件添加头部信息,生成u-boot.imx。
  • 如果配置过uboot,make clean会清除整个工程,那么配置的文件也会被删除,配置项也会被删除掉。
    • 注意这里说的是通过图形界面配置uboot需要注意make clean会清除配置项,但是你如果是通过修改uboot源码来配置的话,就不需要担心!
  • uboot编译命令三部曲
make distclean //清理配置
make xxx_defconfig //配置到.config文件
make -j4 //4核编译

可以通过时间戳,查看uboot是不是最新编译的!

uboot命令

uboot命令中的数字都是十六进制的!不是十进制!

  • mmc list
    • 查看当前板子的mmc设备。
    • 将EMMC和SD卡统称为MMC
  • help或者?
    • 打印uboot支持的所有的命名
    • 查看某一个命令的帮助 ? xxx
  • bdinfo
    • 打印板子信息
  • version
    • 查看uboot版本相关信息
  • reset
    • uboot的重启命令
环境变量相关
  • printenv(重要)
    • 查看当前板子的环境变量
    • 当然直接输入print要是可以的
  • saveenv(重要)
    • 保存环境变量
  • setenv(重要)
    • 修改现有环境变量
      • eg:setenv bootdelay 5然后saveenv这样就把uboot的倒计时改成了5s
      • eg:set bootcmd 'console=ttymxc0,115200 root=/dev/mmcblk1p2 rootwait rw'然后saveenv注意环境变量是字符串的一定要用单引号引起来!
    • 新建环境变量
      • eg:setenv author 'xxx'然后saveenv
    • 删除环境变量
      • eg:setenv author然后saveenv,不设置值即可实现删除操作!
内存操作相关
  • md - 显示指定地址内存值

    • md[.b, .w, .l] address [# of objects]
    • b w l 分别对应1 2 4字节,address对应内存起始地址 [# of objects]要查看的数据长度(十六进制格式)
    • eg:想查看以 0X80000000 开始的 20 个字节的内存值,显示格式为.b 的话:md.b 80000000 14注意14是0x14!直接写md.b 80000000 0x14不容易弄混。
  • nm - 修改指定地址内存值(修改完地址不会自增)

    • nm [.b, .w, .l] address
      • eg:以.l 格式修改 0x80000000 地址的数据为 0x12345678:输入nm.l 0x80000000按下回车后,输入0x12345678,按下回车,然后再输入q即可退出。
  • mm- 修改指定地址内存值(修改完地址会自增)

  • mw - 使用一个指定数据填充一段内存

    • mw [.b, .w, .l] address value [count]
    • eg:使用.l 格式将以 0X80000000 为起始地址的 0x10 个内存块(0x10 * 4=64 字节)填充为 0X0A0A0A0A:mw.l 80000000 0A0A0A0A 10
  • cp - 数据拷贝

    • cp [.b, .w, .l] source target count
    • eg:使用.l 格式将 0x80000000 处的地址拷贝到 0X80000100 处,长度为 0x10 个内存块(0x10 * 4=64 个字节):cp.l 80000000 80000100 10
  • cmp - 比较命令

    • cmp [.b, .w, .l] addr1 addr2 count
    • eg:使用.l 格式来比较 0x80000000 和 0X80000100 这两个地址数据是否相等,比较长度为 0x10 个内存块:cmp.l 80000000 80000100 10
网络相关命令(重点)

  开发板网线需要插到网口2上(左边那个) ,保证开发板和电脑在同一个网段。只要uboot的网络配置好了,便可以通过tftp或NFS连接ubuntu,这样直接从ubuntu下载zImage和rootfs将会方便开发许多!

环境变量描述
ipaddr开发板 ip 地址,可以不设置,使用 dhcp 命令来从路由器获取 IP 地址(dhcp获取的仅仅本次有效,不会修改环境变量的ipaddr,下次启动依然是ipaddr的地址)。
ethaddr开发板的 MAC 地址,一定要设置。
gatewayip网关地址。
netmask子网掩码。
serverip服务器 IP 地址,也就是 Ubuntu 主机 IP 地址,用于调试代码。
setenv ipaddr 192.168.1.50
setenv ethaddr 00:04:9f:04:d2:35
setenv gatewayip 192.168.1.1
setenv netmask 255.255.255.0
setenv serverip 192.168.1.250
saveenv
  • 开始之前,最好将ubuntu的ip地址给写死(手动设置)
  • ipaddr - 设置之前在ubuntu看看能不能ping通,ping不通板子才能用。
  • ethaddr - 也要保证唯一
  • serverip - 这个地址就是ubuntu的地址

在这里插入图片描述

  • ping 测试网络

    • 上述设置完毕之后,通过ping ubuntu地址,查看是否设置成功!
  • nfs命令 - 目的就是为了调试程序

    • nfs 也就是网络文件系统,通过 nfs 可以在计算机之间通过网络来分享资源,比如我们将linux 镜像和设备树文件放到 Ubuntu 中,然后在 uboot 中使用 nfs 命令将 Ubuntu 中的 linux 镜像和设备树下载到开发板的 DRAM 中。这样做的目的是为了方便调试 linux 镜像和设备树,也就是网络调试, 通过网络调试是 Linux 开发中最常用的调试方法。
    • 当然使用NFS前提需要在ubuntu开启NFS服务,并且创建设置NFS目录。
    • nfs [loadAddress] [[hostIPaddr:]bootfilename]
    • eg:将 zImage 下载到开发板 DRAM 的 0X80800000 地址处:nfs 80800000 192.168.1.250:/home/zuozhongkai/linux/nfs/zImage
  • tftp命令 - 目的就是为了调试程序

    • tftp 命令的作用和 nfs 命令一样,都是用于通过网络下载东西到 DRAM 中,只是 tftp 命令使用的 TFTP 协议, Ubuntu 主机作为 TFTP 服务器。
    • tftpboot [loadAddress] [[hostIPaddr:]bootfilename]
    • 和 nfs 命令的区别在于, tftp 命令不需要输入文件在 Ubuntu 中的完整路径,只需要输入文件名即可。
    • eg:将 tftpboot 文件夹里面的 zImage 文件下载到开发板 DRAM 的 0X80800000 地址处:tftp 80800000 zImage
    • 注意:从windows下拷贝到ubuntu中的文件,在用tftp下载的时候就会有权限问题。但是直接在ubuntu下编译生成的文件在用tftp下载的时候就不存在权限问题。
mmc相关命令
命令描述
mmc info输出 MMC 设备信息
mmc read读取 MMC 中的数据。
mmc wirte向 MMC 设备写入数据(可以通过网络下载.imx文件升级uboot)。
mmc rescan扫描 MMC 设备。
mmc part列出 MMC 设备的分区。
mmc dev 0切换 MMC 设备0。
mmc list列出当前有效的所有 MMC 设备。
mmc hwpartition设置 MMC 设备的分区。
mmc bootbus……设置指定 MMC 设备的 BOOT_BUS_WIDTH 域的值。
mmc bootpart……设置指定 MMC 设备的 boot 和 RPMB 分区的大小。
mmc partconf……设置指定 MMC 设备的 PARTITION_CONFG 域的值。
mmc rst复位 MMC 设备
mmc setdsr设置 DSR 寄存器的值
FAT文件系统相关命令

对于I.MX6U来说,SD/EMMC分为三个分区:

  • 第一个:存放uboot
  • 第二个:存放Linux zImage,.dtb。FAT格式
  • 第三个:系统的根文件系统。EXT4格式
  • fatinfo - 查询指定 MMC 设置指定分区的文件系统信息

    • fatinfo <interface> [<dev[:part]>]interface 表示接口,比如 mmc, dev 是查询的设备号, part 是要查询的分区。
    • eg:要查询 EMMC 分区 1 的文件系统信息:fatinfo mmc 1:1
  • fatls - 查询 FAT 格式设备的目录和文件信息

    • fatls <interface> [<dev[:part]>] [directory]directory是要查询的目录
    • eg:查询 EMMC 分区 1 中的所有的目录和文件:fatls mmc 1:1
  • fstype - 查看 MMC 设备某个分区的文件系统格式

    • fstype <interface> <dev>:<part>
    • eg:EMMC 核心板上的 EMMC 默认有 3 个分区,我们来查看一下第0个分区的文件
      系统格式:fstype mmc 1:0
  • fatload - 将指定的文件读取到 DRAM 中

    • eg:将 EMMC 分区 1 中的 zImage 文件读取到 DRAM 中的0X80800000 地址处:fatload mmc 1:1 80800000 zImage
  • fatwrite - 将 DRAM 中的数据写入到 MMC 设备中

    • fatwrite <interface> <dev[:part]> <addr> <filename> <bytes>
EXT文件系统相关命令

  uboot 有 ext2 和 ext4 这两种格式的文件系统的操作命令,常用的就四个命令,分别为:ext2load、 ext2ls、 ext4load、 ext4ls 和 ext4write。这些命令的含义和使用与 fatload、 fatls 和 fatwrit一样,只是 ext2 和 ext4 都是针对 ext 文件系统的。

  • eg:查询 EMMC 的分区 2 中的文件和目录:ext4ls mmc 1:2
BOOT操作命令

  要启动 Linux,需要先将 Linux 镜像文件和设备树拷贝到 DRAM 中,然后使用 bootz 命令来启动Linux系统。拷贝镜像和设备树到DRAM有好2中方式:①、通过tftp从ubuntu下载 ②、通过fatload从EMMC中读取到DRAM中!

  • bootz - 用于自动 zImage 镜像文件

    • bootz [addr [initrd[:size]] [fdt]] addr 是 Linux 镜像文件在 DRAM 中的位置, initrd 是 initrd 文件在DRAM 中的地址,如果不使用 initrd 的话使用‘-’代替即可, fdt 就是设备树文件在 DRAM 中的地址。
    • zImage 一般放到 DRAM 的 0X80800000 地址;设备树放到 DRAM 中的 0X83000000 地址处
    • 输入bootz 80800000 - 83000000便可启动Linux!
  • boot - 启动Linux系统

    • boot 命令也是用来启动 Linux 系统的,只是 boot 会读取环境变量 bootcmd 来启动 Linux 系统, bootcmd 是一个很重要的环境变量!这个环境变量保存着引导命令,其实就是启动的命令集合,具体的引导命令内容是可以修改的。
    • eg:我们要想使用 tftp 命令从网络启动 Linux 那么就可以设置 bootcmd 为“tftp
      80800000 zImage; tftp 83000000 imx6ull-alientek-emmc.dtb; bootz 80800000 - 83000000”,然后使用 saveenv 将 bootcmd 保存起来。然后直接输入 boot 命令即可从网络启动 Linux 系统,命令如下:
setenv bootcmd 'tftp 80800000 zImage; tftp 83000000 imx6ull-alientek-emmc.dtb; bootz
80800000 - 83000000'
saveenv
boot

Uboot源码目录分析

  • 因为uboot会使用到一些经过编译才会生成的文件,因此在分析uboot的时候,需要先编译一下uboot。
  • 整个UBOOT的链接脚本在arch\arm\cpu\u-boot.lds,编译后uboot根目录下也会有个u-boot.lds,注意后者由前者生成的!

移植uboot的时候重点要关注

  • board\freescale\mx6ullevk目录,参考此目录创建自己的板子

  • configs目录,uboot的默认配置文件目录,此目录下都是以_defconfig结尾的,这些配置文件对应不同的板子。

    • 其中mx6ull_alientek_alpha_ddr256_emmc_defconfig是正点原子的配置文件!
  • 执行make xxx_defconfig,会在uboot根目录下生成.config文件,此文件保存了详细的uboot配置信息。

  • 顶层README,非常重要,介绍uboot。

  • 根目录下的u-boot,这个是编译出来带ELF信息的uboot可执行文件

  • bootcmd - 命令列表,这些命令一般都是用来启动 Linux 内核的。(如通过tftp下载zImage和dtb文件,启动Linux内核)

    • bootcmd=tftp 80800000 zImage;tftp 83000000 imx6ull.dtb;bootz 80800000 - 83000000;
  • Bootargs - 命令行参数,传递给Linux内核。(通常用来设置控制台和指定根文件系统)

    • bootargs=console=ttymxc0,115200 root=/dev/mmcblk1p2 rootwait rw
配置uboot有3种方法:
  • 通过 mx6ull_alientek_emmc_defconfig 来配置
  • 通过文件 mx6ull_alientek_emmc.h 来配置
  • 通过图形化配置
    • 在图形化界面可以保存配置
    • 图形界面可以通过?查看使能具体宏的名字。
    • 图形界面启动前需要安装ncurses 库
sudo apt-get install build-essential
sudo apt-get install libncurses5-dev

配置完成之后会在.config中定义相应的宏。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

ReCclay

如果觉得不错,不妨请我喝杯咖啡

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

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

打赏作者

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

抵扣说明:

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

余额充值