• uboot 和 内存地址


    前言

    在使用 uboot 升级的时候,有个疑问:
    通过 tftp 下载的 bin 文件,我该暂存在哪段内存空间?换句话说,哪段内存空间可供我存放临时数据?
    带着这个疑问,开启今天的 uboot 和 内存地址 研究之旅。

    环境

    硬件:OrangePi PC(H3)

    bdinfo

    在 uboot 命令行中,使用 bdinfo 命令查看板子信息

    => bdinfo
    boot_params = 0x40000100
    DRAM bank   = 0x00000000
    -> start    = 0x40000000
    -> size     = 0x40000000
    memstart    = 0x40000000
    memsize     = 0x40000000
    flashstart  = 0x00000000
    flashsize   = 0x00000000
    flashoffset = 0x00000000
    baudrate    = 115200 bps
    relocaddr   = 0x7df96000
    reloc off   = 0x33f96000
    Build       = 32-bit
    current eth = ethernet@1c30000
    ethaddr     = 02:81:e6:56:d9:1f
    IP addr     = <NULL>
    fdt_blob    = 0x79f6ef30
    new_fdt     = 0x79f6ef30
    fdt_size    = 0x00006fa0
    FB base     = 0x7e000000
    lmb_dump_all:
        memory.cnt		   = 0x1
        memory.size		   = 0x0
        memory.reg[0x0].base   = 0x40000000
    		   .size   = 0x40000000
    
        reserved.cnt	   = 0x1
        reserved.size	   = 0x0
        reserved.reg[0x0].base = 0x79f6dd24
    		     .size = 0x60922dc
    arch_number = 0x00000000
    TLB addr    = 0x7fff0000
    irq_sp      = 0x79f6ef20
    sp start    = 0x79f6ef10
    Early malloc usage: 2b8 / 400
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    可以看到,内存起始地址为 0x40000000,大小为 0x40000000,所以范围是 0x40000000~0x7FFFFFFF,这和我们在内核中查看 /proc/iomem 得到的内存范围一致

    # cat /proc/iomem 
    ...
    40000000-7fffffff : System RAM
      40008000-40afffff : Kernel code
      40c00000-40d268d7 : Kernel data
    
    • 1
    • 2
    • 3
    • 4
    • 5

    内存起始地址

    又冒出一个疑问,内存起始地址 0x40000000 是谁规定的?
    这个通常是在 SoC 数据手册中 Memory mapping 这一节规定的,查看 H3 芯片的数据手册
    在这里插入图片描述
    看到 DRAM 使用的物理地址范围为 0x40000000-0xBFFFFFFF,共 2G 范围,这也决定了 H3 最大支持 2GB 内存。
    我们板子上焊接的是两片 512MB 的 DDR 颗粒,共 1GB,所以内存地址范围是 0x40000000~0x7FFFFFFF。

    uboot 起始地址

    讲了那么多,uboot 会被加载到内存的哪个地址呢?是内存的起始地址 0x40000000?还是中间位置 0x60000000?
    这得从 uboot 源码和链接脚本中找寻。
    uboot 是没有使用虚拟内存地址的,直接跑在物理内存上,所以 uboot 在被编译链接时,肯定指定了代码的入口地址,这个地址肯定落在 0x40000000~0x7FFFFFFF 这个范围内

    CONFIG_SYS_TEXT_BASE

    在 uboot 的 .config 和 Makefile 文件中,使用 CONFIG_SYS_TEXT_BASE 宏来指定代码的入口地址

    .config

    CONFIG_SYS_TEXT_BASE=0x4a000000
    
    • 1

    Makefile

    LDFLAGS_u-boot += -Ttext $(CONFIG_SYS_TEXT_BASE)
    
    • 1

    验证

    liyongjun@Box:~/project/board/buildroot$ OrangePiPC/host/bin/arm-linux-readelf -h OrangePiPC/build/uboot-2020.10/u-boot
    ELF Header:
      Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 
      Class:                             ELF32
      Data:                              2's complement, little endian
      Version:                           1 (current)
      OS/ABI:                            UNIX - System V
      ABI Version:                       0
      Type:                              EXEC (Executable file)
      Machine:                           ARM
      Version:                           0x1
      Entry point address:               0x4a000000
      Start of program headers:          52 (bytes into file)
      Start of section headers:          3872012 (bytes into file)
      Flags:                             0x5000200, Version5 EABI, soft-float ABI
      Size of this header:               52 (bytes)
      Size of program headers:           32 (bytes)
      Number of program headers:         4
      Size of section headers:           40 (bytes)
      Number of section headers:         37
      Section header string table index: 36
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    可以看到 uboot 的入口地址确实是 0x4a000000

    uboot 验证

    uboot 读取 0x4a000000
    在这里插入图片描述
    u-boot.bin 二进制内容
    在这里插入图片描述
    可以看到,uboot 使用命令从 0x4a000000 处读到的内容就是 u-boot.bin 的内容。
    这也充分证实了:SPL 已经将 uboot 程序加载到了内存地址 0x4a000000 处

    空闲内存

    那么 0x40000000 ~ 0x4a000000 这段内存空间(160MB),uboot 没有使用,我们可以用这段内存来暂存 tftp 下载的文件。

    => tftp 42000000 u-boot-sunxi-with-spl.bin
    Using ethernet@1c30000 device
    TFTP from server 192.168.31.223; our IP address is 192.168.31.32
    Filename 'u-boot-sunxi-with-spl.bin'.
    Load address: 0x42000000
    Loading: ##################################
    	 1.4 MiB/s
    done
    Bytes transferred = 498944 (79d00 hex)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    使用 tftp 命令,从 server 下载 u-boot-sunxi-with-spl.bin,存放在内存 0x42000000 处,大小共 498944B。

    写入 SD 卡

    => mmc write 42000000 10 3ce              
    
    MMC write: dev # 0, block # 16, count 974 ... 974 blocks written: OK
    
    • 1
    • 2
    • 3

    将暂存在内存的 u-boot-sunxi-with-spl.bin 文件写入 SD 卡来完成升级操作。
    0x42000000 为内存地址
    0x10 为 SD 卡的块号,一个块为 512 字节,我们需要从 SD 卡偏移 8KB 的位置开始写入
    0x3ce 为写入的块数,0x3ce = 974 = 498944 / 512

    写入 SD 卡后,重启就行了

    => reset
    resetting ...
    
    U-Boot SPL 2020.10 (Nov 08 2023 - 22:15:30 +0800)
    DRAM: 1024 MiB
    Trying to boot from MMC1
    
    
    U-Boot 2020.10 (Nov 08 2023 - 22:15:30 +0800) Allwinner Technology
    
    CPU:   Allwinner H3 (SUN8I 1680)
    Model: Xunlong Orange Pi PC
    DRAM:  1 GiB
    MMC:   mmc@1c0f000: 0
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    检查编译日期,可以看到升级成功了。

    uboot 升级到内存

    为了快速验证 uboot 功能,我们可以直接将 uboot 升级到内存,无需写入 SD 卡
    以下两组命令都是可以的,使用 u-boot-sunxi-with-spl.bin 的话,要注意计算好 uboot 在该文件中的偏移,使得 uboot 的起始落在 0x4a000000 处就可以了。

    setenv serverip 192.168.31.223
    setenv ipaddr 192.168.31.32
    tftp 0x4a000000 u-boot.bin
    go 4a000000
    
    • 1
    • 2
    • 3
    • 4
    setenv serverip 192.168.31.223
    setenv ipaddr 192.168.31.32
    tftp 0x49FF7FC0 u-boot-sunxi-with-spl.bin
    go 4a000000
    
    • 1
    • 2
    • 3
    • 4
  • 相关阅读:
    windows消息机制
    ARM接口编程—UART(exynos 4412平台)
    uniapp自定义图标库引入
    python文件数据分析治理提取
    HashMap复杂方法总结
    12.2.1、Docker__docker的概述、docker的命令
    Pytorch框架的学习(4)
    利用三次样条插值调整鱼眼扭曲程度
    数据结构---二叉树
    Flask之路由(app.route)详解
  • 原文地址:https://blog.csdn.net/lyndon_li/article/details/134305748