linux系统移植-2(imx93)

Uboot介绍

本人是刚毕业大学生,对linux系统移植了解尚浅,如果有疑问或者错误,欢迎在评论区指出

[1uboot基础了解 - 知乎.pdf](PDF\uboot\1uboot基础了解 - 知乎.pdf)

bootloader

  • boot,为了运行程序,做一些初始化
  • loader,执行应用逻辑,加载Linux内核

什么是bootloader

  • 嵌入式系统在加电之后执行的第一段代码
  • 用于将软硬件环境初始化到一个合适的状态,为操作系统的加载和运行做准备(本身不是操作系统)
  • 将操作系统映像或固化的嵌入式应用程序装载到内存中然后跳转到操作系统所在的空间,启动操作系统运行
  • 当操作系统内核加载完成后,Bootloader 生命周期就结束了

为什么使用bootloader

bootloader 是启动引导程序的统称

  • 介绍

    相当于windows下的BIOS,是操作系统内核的一段程序

    bootloader 赋值检测硬件、配置设备和加载操作系统内核,是操作系统中非常重要的组成部分,确保操作系统能够顺序启动并加载

  • 功能

    • 初始化软硬件环境
    • 引导加载Linux内核
    • 给linux内核传参
    • 执行用户命令

bootloder启动分析

第一阶段
  1. 硬件设备初始化,设置时钟,设置分配系数,关闭看泵,关中断,启动ICACHE,关闭DCACHE和TLB,关闭MMU,设置分配系数,FCLK:HCLK:PCLK=1:4:8
    • FCLK:内核时钟,提供给内核的时钟
    • HCLK:总线时钟,供给用于存储器控制器,中断控制器,LCD 控制器,DMA 和 USB 主机模块的 AHB总线的时钟
    • PCLK:I/O接口时钟,提供给用于外设APB总线的时钟
  2. 初始化内存空间
  3. 将bootloader的第二阶段代码复制到RAM中
  4. 设置堆栈
  5. 跳转到第二阶段的C入口点
第二阶段
  1. 初始化本阶段要使用到的硬件设备
  2. 检测系统内存映射
  3. 将内核映像和根文件系统映像从Flash读到SDRAM中
  4. 为内核设置启动参数
  5. 调用内核
  6. 跳转到内核

开发板启动过程

材料准备
windowslinux
windows镜像 和 U盘(启动盘)顺序linux内核镜像、SD卡启动盘
进入BIOS选择启动方式通过拨码开关选择启动方式
通过U盘中的引导程序安装系统通过SD卡中的引导程序安装系统
安装Windows驱动系统安装linux驱动系统
安装Windows应用系统安装linux应用程序
启动流程图
  1. 将BL0固化到芯片内部,只做UBoot(BL1)的加载
  2. UBoot(BL1)将linux内核加载到RAM上运行
  3. linux内核完成跟文件系统挂载,系统启动完成

请添加图片描述

bootloader有哪些

U-Boot:遵循GPL条款的开放源码目录
优点:功能最多,灵活最强,开源
功能:支持多个文件系统、附带调试、脚本、引导等工具
结构:与linux类似

BootLoader描述x86ARMPowerPC
LILOLinux磁盘引导程序
GRUBGNU的LILO替代程序
Loadlin从DOS引导Linux
ROLO从ROM引导Linux而不需要BIOS
Etherboot通过以太网卡启动Linux系统的固件
LinuxBIOS完全替代BUIS的Linux引导程序
BLOBLART等硬件平台的引导程序
U-boot通用引导程序
RedBoot基于eCos的引导程序

uboot工作方式

[2uboot启动流程分析 - 知乎.pdf](PDF\uboot\2uboot启动流程分析 - 知乎.pdf)

  1. 启动加载模式:Bootloader正常工作模式,正常上电和Bootloader将嵌入式操作系统从flash中加载到SDRAM中
  2. 下载模式,Bootloader通过通讯,将内核镜像、跟文件系统镜像从PC机直接下载到目标包的FLASH中

uboot执行流程

请添加图片描述

  • uboot入口函数

    • uboot工程连接脚本文件,决定了Uboot的组装
    • uboot文件中ENTRY(_start)指定了uboot的入口地址

    建立一个基本指向环境,初始化硬件寄存器和堆栈等

    OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
    OUTPUT_ARCH(arm)
    ENTRY(_start)					@程序的入口函数
    SECTIONS						@定义了段
    {
     . = 0x00000000;                @起始地址
     . = ALIGN(4);                  @四字节对齐
     .text :            
     {  
      *(.__image_copy_start)        @映像文件复制起始地址
      *(.vectors)                   @异常向量表
      arch/arm/cpu/armv7/start.o (.text*)   @启动函数
     }
     ......
    }
    
  • board_init_f板级前置初始化

    • 调用init_sequence_f,对串口、定时器设备树等进行一系列初始化工作
    • 初始化末尾执行了reloc_xxx函数,实现的UBoot的重定向功能

    对特定的硬件板进行设置和配置

    void board_init_f(ulong boot_flags)
    {
        gd->flags = boot_flags;
        gd->have_console = 0;
    
        if (initcall_run_list(init_sequence_f))
            hang();
    }
    
    static const init_fnc_t init_sequence_f[] = {
        setup_mon_len,
        ...
        log_init,
        arch_cpu_init,      /* 基本的 arch cpu 相关设置 */
        env_init,       	/* 初始化环境 */
        ...       
        reloc_fdt,			/* 重定向 */
        reloc_bootstage,
        reloc_bloblist,
        setup_reloc,
        ...
    }
    
  • relocate_code重定向,将uboot自身镜像拷贝到ddr上的另一个位置的动作

    • uboot在ROM上,需要将代码拷贝到内存上才能完整运行
    • 为kernel腾空间,kernel一般放在内存上,需要把uboot重定向到顶端,避免内存践踏
  • board_init_r:板级后置初始化

    • 同board_init_f,拥有一个init_sequence_r初始化列表,DM模型初始化,MMC驱动初始化

    对设备进行调试和故障排除

  • main_loop:Uboot主循环

    Uboot最终指向函数

    • 加载kernel
    • uboot命令体系

uboot的存放位置

  • flash上存放着U-boot、环境变量、内核映像、文件系统等
  • U-boot存放于Flash的指定位置,这个位置由厂商决定

uboot移植

编译uboot

  • https://www.nxp.com.cn/lgfiles/NMG/MAD/YOCTO/firmware-sentinel-0.9.bin ——哨兵映像

请添加图片描述

make  distclean //清理工程
make imx93_11x11_evk_defconfig //配置uboot 配置文件
make V=1 -j4 //编译
    V=1:打印更多的详细信息
    -j4:使用4核心进行编译

uboot写SD卡

  • MMC/SD

    sudo dd if=<U-Boot image> of=/dev/sdx bs=1k seek=<offset> conv=fsync
    
    • 偏移量

      1 - 用于imx6 和 imx7

      33 - 用于i.MX 8QuadMax A0, i.MX 8QuadXPlus A0, 和 i.MX 8M Quad, 和 i.MX 8M Mini

      13 - 用于i.MX 8QuadXPlus B0, i.MX 8QuadMax B0, i.MX 8DualX, i.MX 8DXL, i.MX 8M Nano, i.MX 8M Plus,
      i.MX 8ULP, 和 i.MX 9

UUU下载uboot

30_系统移植_移植uboot
  1. sudo uuu -b <emmc|emmc_all|sd|sd_all|spl> imx-boot.......flash_singleboot
    
    • emmc / emm_all:向emmc写uboot
    • sd / sd_all:向sd卡写uboot
    • spl:向ram写uboot
  2. uuu  uboot.imx
    uuu  flash.bin		//uboot.imx ≈  flash.bin
    
    • 先将uboot启动在ram中,然后在写入闪存中

uboot命令

  • 内核引导

    • boot——完成内核重定位,将内核从外存加载到内存,然后启动内核

      • boot读取环境变量bootcmd启动系统

      • 格式:

        boot
        
    • bootm/booti——调用时一般要传入内核在内存中的地址,然后取该地址处启动内核

      • bootm/booti用于启动uImage镜像文件,m调用32位,i调用64位

      • 格式:

        1. bootm addr    	//不使用设备树
        2. bootm [addr [initrd [:size]] [fdt]]	//要使用设备树
        	* addr:镜像在DRAM中的首地址
        	* initrd是initrd的地址,为空时用"-"代替
        	* fdt是设备树在DRAM中的首地址
        
    • bootz——镜像文件已经存储在DRAM中,bootz来启动

      • 用于自动zImage镜像文件

      • 格式:

        bootz [addr [initrd[:size]] [fdt]]
            * addr:镜像在DRAM中的首地址
        	* initrd是initrd的地址,为空时用"-"代替
        	* fdt是设备树在DRAM中的首地址
        
  • 内存操作

    • md——显示内存值

      • 格式
      md [.b .w .l] address [#of objects]
      	[.b .w .l]:byte、word、long	//以1字节、2字节、4字节显示内存值
      	address:内存起始地址
      	[#of objects]:查看数据的长度
      
    • nm——修改指定地址的内存值,修改时指向地址不会自增

      • 格式
      nm [.b .w .l] address
      	[.b .w .l]:byte、word、long	//以1字节、2字节、4字节指定操作格式
      	address:内存起始地址
      
    • mm——修改指定地址的内存值,修改时指向地址会自增

      • 格式
      nm [.b .w .l] address
      	[.b .w .l]:byte、word、long	//以1字节、2字节、4字节指定操作格式
      	address:内存起始地址
      
    • mw——使用一个指定的数据填充一段内存

      • 格式
      mw [.b, .w, .l] address value [count]
      	[.b .w .l]:byte、word、long	//以1字节、2字节、4字节指定操作格式
      	address:内存起始地址
      	value:要填充的数据
      	[count]:要填充的长度
      
    • cp——数据拷贝,将DRAM中的数据从一段内存拷贝到另一端内存中

      • 格式
      cp [.b, .w, .l] source target count
      	[.b .w .l]:byte、word、long	//以1字节、2字节、4字节指定操作格式
          source:源地址
          target:目的地址
          count:拷贝长度
      
    • cmp——用于比较两端内存数据是否相等

      • 格式
      cmp [.b, .w, .l] addr1 addr2 count
      	[.b .w .l]:byte、word、long	//以1字节、2字节、4字节指定操作格式
      	addr1:第一段内存首地址
      	addr2:第二段内存首地址
      	count:比较长度
      
  • flash操作

    • uboot支持EMMC和SD卡,一般认为emmc和sd卡是同种大小,没有特殊说明,mmc是一系列命令

      加上SD卡一共两个设备,FSL_SDHC:0是SD卡,FSL_SDHC:1是emmc,默认将emmc设为当前设备

      命令描述格式
      mmc info输出mmc设备信息mmc info
      mmc read读取mmc中的数据mcc read [存储地址] [起始块号] [读取块数]
      mmc write向mmc写数据mmc write [读取地址] [写入块号] [写入块数]
      mmc rescan扫描mmc设备mmc rescan
      mmc part列出mmc设备分区mmc part
      mmc dev切换mmc设备mmc dev [设备号] [分区号]
      mmc list列出当前有些的所有mmc设备mmc list
      mmc hwpartition设置mmc设备的分区mmc hwpartition [设备号] [分区ID] [访问权限] [分区起始块号] [分区大小]
      mmc bootbus设置指定mmc设备的BOOT_BUS_WIDTH区域mmc bootbus [设备号] [数据总线宽度] [启动总线模式] [复位阶段]
      mmc bootpart设置指定mmc设备的boot和RPMB分区的大小mmc bootpart [设备编号] [启动分区的分区号] [启动时是否显示启动分区信息]
      mmc partconf设置指定的mmc设备的PARTITON_CONFIG域的值mmc partconf [设备号] [配置编号] [配置值]
      mmc rst复位mmc设备mmc rst [设备号]
      mmc setdsr设置dsr寄存器的值mmc setdsr [设备号] [要设置的值]
    • FAT格式文件操作命令

      • fatinfo命令

        • 功能:查询指定MMC设置指定分区文件系统信息
        • 格式:
        fatinfo <interface> [<dev[:part]>]
        	interface:表示接口
        	dev:设备号
        	part:分区
        
      • fatls命令

        • 功能:查询FAT格式设备的目录和文件信息
        • 格式:
        fatls <interface> [<dev[:part]>] [directory]
        	interface:表示接口
        	dev:设备号
        	part:分区
            directory:要查询的目录
        
      • fstype命令

        • 功能:查看mmc设备某个文件的文件系统格式
        • 格式:
        fstype <interface> <dev>:<part>
            interface:表示接口
        	dev:设备号
        	part:分区
        
      • fatload命令

        • 功能:将指定的文件读取到DRAM中
        • 格式:
        fatload <interface> [<dev[:part]> [<addr> [<filename> [bytes [pos]]]]]
        	interface:接口
        	dev:设备号
        	part:分区
        	addr:报错在DRAM中的起始地址
        	filename:要去读的文件名
        	bytes:读多少字节数据
        	pos要读的文件相对于文件搜地址的偏移
        
    • EXT格式文件操作命令

      ext2load、 ext2ls、 ext4load、 ext4ls 和 ext4write。这些命令的含义和使用与 fatload、 fatls 和 fatwrit一样,只是 ext2 和 ext4 都是针对 ext 文件系统的

  • 网络操作

    • 环境变量
    环境变量描述
    ipaddr开发板ip地址,可以不设置,使用dhcp命令来从路由器获取ip地址
    ethaddr开发板的MAC地址
    gatewayip网关地址
    netmask子网掩码
    serverip服务器IP地址,Ubuntu主机IP地址,用于调试代码
    • ping命令

      • 验证开发板网络是否可用,是否可用和主机进行通信
      • 使用:
      ping 主机ip
      
    • dhcp命令

      • 从路由器获取IP地址,需要将开发板接入路由器
      • 使用
      dhcp
      
    • nfs命令

      • 网络文件系统,通过nfs在计算机直接通过网络来分享资源
      nfs zImage_addr ip 路径
      	zImage_addr:zImage报错地址
      	ip:主机ip
      	路径:镜像在主机中的路径
      
    • ftp命令

      • 同nfs,tftp使用的协议基于TCP/IP

      • 使用

        1. 创建文件夹存储文件

          mkdir /home/< name >/linux/tftpboot
          chmod 777 /home/< name >/linux/tftpboot
          
        2. 配置tftp

           server tftp
          {
          	 socket_type = dgram
          	 protocol = udp
          	 wait = yes
          	 user = root
          	 server = /usr/sbin/in.tftpd
          	 server_args = -s /home/wanli/linux/tftpboot/
          	 disable = no
          	 per_source = 11
          	 cps = 100 2
          	 flags = IPv4
          }
          
        3. 启动tftp服务

          sudo service tftpd-hpa start
          
        4. 重启tftp服务器

          sudo service tftpd-hpa restart
          
        5. uboot启动tftp服务器

          tftpboot [loadAddress] [[hostIPaddr:]bootfilename]
          	loadAddress:文件在DRAM中存放地址
          	[[hostIPaddr:]bootfilename]:文件名即可	//与nfs区别
          

从网络更新uboot镜像

  1. 设备连接到tftp服务器网络

    • 确保ubuntu安装了tftp
    重启tftp:sudo service tftpd-hpa restart
    
  2. uboot命令行界面下配置网络参数

    setenv gatewayip <网关ip>
    setenv ipaddr <板子ip>
    setenv serverip <服务器ip>
    setenv netmask <子网掩码ip>
    saveenv  //如果报错,可能uboot在ram中没有写入闪存
    printenv	//查看板子环境变量信息
    
  3. 使用tftpboot从tftp下载uboot镜像

    tftpboot <存储位置> <文件名>	//使用TFTP从服务器下载指定文件,到指定内存
    mmc write <存储位置> <指定闪存>  //从内存拷贝uboot到指定emmc中
    
  4. 使用bootm命令启动U-boot镜像

    bootm <内存地址>
    

通过命令方式读取拨码开关状态

  • 使用gpio info查看引脚状态

    gpio stat -a		//列出端口详细电平
    gpio input GPIOx_y		//将GPIOx口下y引脚设置为输入模式,并读取电平
    
  • 使用md查看寄存器数据

    md  <地址>	//列出寄存器地址的数据
    
boot_modegpioReuse
BOOT_MODE[0]gpio1.IO[5]UART1_TXD
BOOT_MODE[1]gpio1.IO[7]UART2_TXD
BOOT_MODE[2]gpio1.IO[11]SAI1_TXFS
BOOT_MODE[3]gpio1.IO[13]SAI1_TXD

uboot环境变量

变量含义
sdt_addrSDT的存储地址,SDT是用于描述系统硬件配置的数据结构
bootm_size启动映像的大小,以字节为单位,通常指的是内核映像大小
cntr_addr控制台的存储地址,控制台是用户与计算机进行交互的输入/输出设置
fd_addr_r文件系统设备的存储地址,用于启动过程中虚拟文件系统的根目录地址
fdt_highFDT的加载地址,用于描述硬件设备和配置信息的数据结构
fileaddr文件的加载地址,引导过程中需要加载的某个文件的存储地址
filesize文件大小
initrd_addrinitrd的加载地址,initrd是一个临时的文件系统,用于启动过程中提供额外的驱动程序和工具
kernel_addr_r内核的加载地址,这是引导式加载内核的存储地址
scriptaddr启动加班的存储地址,启动脚本是包含引导过程中指向命令的脚本文件
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值