程序项目代做,有需求私信(小程序、网站、爬虫、电路板设计、驱动、应用程序开发、毕设疑难问题处理等)

Rockchip RK3399 - 移植uboot 2023.04 & linux 6.3

----------------------------------------------------------------------------------------------------------------------------
开发板 :NanoPC-T4开发板
eMMC16GB
LPDDR34GB
显示屏 :15.6 HDMI接口显示屏
u-boot2023.04
linux6.3
----------------------------------------------------------------------------------------------------------------------------

在前面我们已经介绍了《编译Rockchip官方》提供的uboot源码,并下载到开发板中进行测试运行。这一节我们尝试下载最新的uboot版本试试,当前最新版本为2023.04

一、uboot 2023.04

1.1 下载源码

u-boot软件包下载网站:《https://ftp.denx.de/pub/u-boot/》。

DENX相关的网站:《http://www.denx.de/re/DPLG.html》。

u-boot git仓库:《https://gitlab.denx.de/u-boot/u-boot》。

我们在ubuntu运行如下命令:

root@zhengyang:/work/sambashare/rk3399# wget https://ftp.denx.de/pub/u-boot/u-boot-2023.04.tar.bz2

解压:

root@zhengyang:/work/sambashare/rk3399# tar -jxf u-boot-2023.04.tar.bz2

进入到uboot文件夹里,这就是我们需要的uboot的源码了:

root@zhengyang:/work/sambashare/rk3399#  cd u-boot-2023.04
root@zhengyang:/work/sambashare/rk3399/u-boot-2023.04# ll
总用量 484
drwxrwxr-x  25 root root  4096 Apr  4 04:38 ./
drwxr-xr-x  14 root root  4096 May 21 15:22 ../
drwxrwxr-x   2 root root  4096 Apr  4 04:38 api/
drwxrwxr-x  14 root root  4096 Apr  4 04:38 arch/
-rw-rw-r--   1 root root 21095 Apr  4 04:38 .azure-pipelines.yml
drwxrwxr-x 177 root root  4096 Apr  4 04:38 board/
drwxrwxr-x   2 root root  4096 Apr  4 04:38 boot/
-rw-rw-r--   1 root root   814 Apr  4 04:38 .checkpatch.conf
drwxrwxr-x  10 root root  4096 Apr  4 04:38 cmd/
drwxrwxr-x   5 root root  4096 Apr  4 04:38 common/
-rw-rw-r--   1 root root  2180 Apr  4 04:38 config.mk
drwxrwxr-x   2 root root 57344 Apr  4 04:38 configs/
drwxrwxr-x   2 root root  4096 Apr  4 04:38 disk/
drwxrwxr-x  20 root root  4096 Apr  4 04:38 doc/
drwxrwxr-x  74 root root  4096 Apr  4 04:38 drivers/
drwxrwxr-x   2 root root  4096 Apr  4 04:38 dts/
drwxrwxr-x   2 root root  4096 Apr  4 04:38 env/
drwxrwxr-x   4 root root  4096 Apr  4 04:38 examples/
drwxrwxr-x  15 root root  4096 Apr  4 04:38 fs/
-rw-rw-r--   1 root root    44 Apr  4 04:38 .get_maintainer.conf
-rw-rw-r--   1 root root   207 Apr  4 04:38 .gitattributes
drwxrwxr-x   2 root root  4096 Apr  4 04:38 .github/
-rw-rw-r--   1 root root  1115 Apr  4 04:38 .gitignore
-rw-rw-r--   1 root root 14133 Apr  4 04:38 .gitlab-ci.yml
drwxrwxr-x  36 root root 20480 Apr  4 04:38 include/
-rw-rw-r--   1 root root   783 Apr  4 04:38 Kbuild
-rw-rw-r--   1 root root 20750 Apr  4 04:38 Kconfig
drwxrwxr-x  24 root root  4096 Apr  4 04:38 lib/
drwxrwxr-x   2 root root  4096 Apr  4 04:38 Licenses/
-rw-rw-r--   1 root root  4022 Apr  4 04:38 .mailmap
-rw-rw-r--   1 root root 42030 Apr  4 04:38 MAINTAINERS
-rw-rw-r--   1 root root 81547 Apr  4 04:38 Makefile
drwxrwxr-x   2 root root  4096 Apr  4 04:38 net/
drwxrwxr-x   5 root root  4096 Apr  4 04:38 post/
-rw-rw-r--   1 root root 94985 Apr  4 04:38 README
-rw-rw-r--   1 root root   491 Apr  4 04:38 .readthedocs.yml
drwxrwxr-x   6 root root  4096 Apr  4 04:38 scripts/
drwxrwxr-x  17 root root  4096 Apr  4 04:38 test/
drwxrwxr-x  15 root root  4096 Apr  4 04:38 tools/

1.2 配置uboot

uboot的编译分为两步:配置、编译。单板的默认配置在configs目录下,这里我们直接选择configs/evb-rk3399_defconfig,这是Rockchip评估板的配置:

View Code
CONFIG_ARM=y
CONFIG_SKIP_LOWLEVEL_INIT=y
CONFIG_COUNTER_FREQUENCY=24000000
CONFIG_ARCH_ROCKCHIP=y
CONFIG_TEXT_BASE=0x00200000
CONFIG_NR_DRAM_BANKS=1
CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y
CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x300000
CONFIG_ENV_OFFSET=0x3F8000
CONFIG_DEFAULT_DEVICE_TREE="rk3399-evb"
CONFIG_DM_RESET=y
CONFIG_ROCKCHIP_RK3399=y
CONFIG_TARGET_EVB_RK3399=y
CONFIG_SPL_STACK=0x400000
CONFIG_DEBUG_UART_BASE=0xFF1A0000
CONFIG_DEBUG_UART_CLOCK=24000000
CONFIG_SYS_LOAD_ADDR=0x800800
CONFIG_DEBUG_UART=y
CONFIG_DEFAULT_FDT_FILE="rockchip/rk3399-evb.dtb"
CONFIG_DISPLAY_BOARDINFO_LATE=y
CONFIG_SPL_MAX_SIZE=0x2e000
CONFIG_SPL_PAD_TO=0x7f8000
CONFIG_SPL_HAS_BSS_LINKER_SECTION=y
CONFIG_SPL_BSS_START_ADDR=0x400000
CONFIG_SPL_BSS_MAX_SIZE=0x2000
# CONFIG_SPL_RAW_IMAGE_SUPPORT is not set
# CONFIG_SPL_SHARES_INIT_SP_ADDR is not set
CONFIG_SPL_STACK_R=y
CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN=0x10000
CONFIG_TPL=y
CONFIG_CMD_BOOTZ=y
CONFIG_CMD_GPT=y
CONFIG_CMD_MMC=y
CONFIG_CMD_USB=y
# CONFIG_CMD_SETEXPR is not set
CONFIG_CMD_TIME=y
CONFIG_SPL_OF_CONTROL=y
CONFIG_OF_SPL_REMOVE_PROPS="pinctrl-0 pinctrl-names clock-names interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents"
CONFIG_ENV_IS_IN_MMC=y
CONFIG_SYS_RELOC_GD_ENV_ADDR=y
CONFIG_NET_RANDOM_ETHADDR=y
CONFIG_ROCKCHIP_GPIO=y
CONFIG_SYS_I2C_ROCKCHIP=y
CONFIG_MISC=y
CONFIG_MMC_HS400_SUPPORT=y
CONFIG_MMC_DW=y
CONFIG_MMC_DW_ROCKCHIP=y
CONFIG_MMC_SDHCI=y
CONFIG_MMC_SDHCI_SDMA=y
CONFIG_MMC_SDHCI_ROCKCHIP=y
CONFIG_SF_DEFAULT_SPEED=20000000
CONFIG_ETH_DESIGNWARE=y
CONFIG_GMAC_ROCKCHIP=y
CONFIG_PHY_ROCKCHIP_INNO_USB2=y
CONFIG_PHY_ROCKCHIP_TYPEC=y
CONFIG_PMIC_RK8XX=y
CONFIG_REGULATOR_PWM=y
CONFIG_REGULATOR_RK8XX=y
CONFIG_PWM_ROCKCHIP=y
CONFIG_DM_RNG=y
CONFIG_RNG_ROCKCHIP=y
CONFIG_BAUDRATE=1500000
CONFIG_DEBUG_UART_SHIFT=2
CONFIG_SYS_NS16550_MEM32=y
CONFIG_SYSRESET=y
CONFIG_USB=y
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_XHCI_DWC3=y
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_EHCI_GENERIC=y
CONFIG_USB_DWC3=y
CONFIG_USB_DWC3_GENERIC=y
CONFIG_USB_HOST_ETHER=y
CONFIG_USB_ETHER_ASIX=y
CONFIG_USB_ETHER_ASIX88179=y
CONFIG_USB_ETHER_MCS7830=y
CONFIG_USB_ETHER_RTL8152=y
CONFIG_USB_ETHER_SMSC95XX=y
CONFIG_VIDEO=y
# CONFIG_VIDEO_BPP8 is not set
CONFIG_DISPLAY=y
CONFIG_VIDEO_ROCKCHIP=y
CONFIG_VIDEO_ROCKCHIP_MAX_YRES=1200
CONFIG_DISPLAY_ROCKCHIP_MIPI=y
CONFIG_SPL_TINY_MEMSET=y
CONFIG_ERRNO_STR=y

因此执行如下命令,生成.config文件:

root@zhengyang:/work/sambashare/rk3399/u-boot-2023.04# make evb-rk3399_defconfig V=1

接着我们需要执行make menuconfig做一些配置。

1.2.1 配置串口波特率

uboot中默认的调试串口波特率是1500000,有很多的调试终端不支持1.5M的波特率,我们可以把波特率重新配置下;

Device Drivers  ---> 
      Serial --->     
           (115200) Default baudrate  

注意:波特率数值如果无法删除,按CTRL+回车键尝试。如果配置为1500000,后面测试时串口输出内容一部分正常,偶尔出现乱码,考虑是串口波特率太高不稳定造成的,降低波特率到115200尝试。

1.2.2 配置eMMC

为什么要去配置eMMC呢?这个是因为我使用默认配置,编译后的uboot下载到开发板出现了无法对eMMC进行读写的问题,并且输出了如下错误:

sdhci_transfer_data: Error detected in status(0x208000)

然后我去比对了当前版本ubootRockchip官方(《Rockchip RK3399 - TPL/SPL方式加载uboot》)提供的uboot单板配置configs/evb-rk3399_defconfig的差异,发现当前版本默认开启了以下配置:

CONFIG_MMC_HS400_SUPPORT=y   # 多出了这个
CONFIG_MMC_DW=y
CONFIG_MMC_DW_ROCKCHIP=y
CONFIG_MMC_SDHCI=y
CONFIG_MMC_SDHCI_SDMA=y  # 多出了这个

CONFIG_MMC_HS400_SUPPORCONFIG_MMC_SDHCI_SDMA是什么呢?

CONFIG_MMC_HS400_SUPPORT 是一个配置选项,用于支持嵌入式设备中的高速 MMC(Multimedia Card)/SD(Secure Digital)卡,默认情况下未启用。

启用这个选项可以让MMC/SD卡在HS400模式下运行,从而提高读写速度,但是需要确保硬件上支持HS400模式,并且芯片厂商提供了对应的驱动程序。如果硬件不支持或驱动程序不可用,则启用此选项将会导致系统无法正常启动。

既然我们已经明白了该配置项的作用,那我们就要看一下我们的eMMC芯片是否支持HS400模式,这里用的开发板板载的eMMC型号为:KLMAG2WEMB-B031,找到芯片的datasheet有关HS400 mode的信息,具体定位到EXT_CSD196个字节DEVICE_TYPE,其值为0x57;可以看到eMMC工作在HS400模式时,电压要求为1.8V

配置项CONFIG_MMC_SDHCI_SDMA用于启用SD/SDIO/MMC主机控制器使用DMA方式进行数据传输。

这里我们暂且将CONFIG_MMC_HS400_SUPPORTCONFIG_MMC_SDHCI_SDMA配置关掉:

Device Drivers  ---> 
      MMC Host controller Support  --->
            [ ] MMC debugging
            [ ] enable HS400 support  
            [ ] Support IO voltage configuration
            [ ] Support SDHCI SDMA     

如果想查看eMMC读写命令信息,可以打开MMC debuging

1.2.3 配置FIT
Boot options  --->    
     Boot images  --->
         [*] Use a script to generate the .its script                                                 
        (arch/arm/mach-rockchip/make_fit_atf.py) .its file generator script for U-Boot FIT image

我们之前介绍过在生成u-boot.itb文件时,需要执行如下命令:

tools/mkimage -f u-boot.its u-boot.itb

mkimageits文件以及对应的image data file,打包成一个itb文件,也就是uboot可以识别的image file(FIT-uImage)

因为mkimage是根据its文件中的描述来打包镜像生成itb文件(FIT-uImage),所以首先需要制作一个its文件,在its文件中描述需要被打包的镜像,主要是bl31.bindtb文件,u-boot-nodtb.bin

这里我们需要使用到arch/arm/mach-rockchip/make_fit_atf.py文件,这个是从Rockchip官网uboot下拷贝过来的,内容如下,这是一个python脚本,主要就是生成一个u-boot.its文件:

View Code
#!/usr/bin/env python2
"""
A script to generate FIT image source for rockchip boards
with ARM Trusted Firmware
and multiple device trees (given on the command line)

usage: $0 <dt_name> [<dt_name> [<dt_name] ...]
"""

import os
import sys
import getopt

# pip install pyelftools
from elftools.elf.elffile import ELFFile
from elftools.elf.sections import SymbolTableSection
from elftools.elf.segments import Segment, InterpSegment, NoteSegment

ELF_SEG_P_TYPE='p_type'
ELF_SEG_P_PADDR='p_paddr'
ELF_SEG_P_VADDR='p_vaddr'
ELF_SEG_P_OFFSET='p_offset'
ELF_SEG_P_FILESZ='p_filesz'
ELF_SEG_P_MEMSZ='p_memsz'

DT_HEADER="""/*
 * Copyright (C) 2017 Fuzhou Rockchip Electronics Co., Ltd
 *
 * Minimal dts for a SPL FIT image payload.
 *
 * SPDX-License-Identifier: GPL-2.0+  X11
 */
/dts-v1/;

/ {
        description = "Configuration to load ATF before U-Boot";
        #address-cells = <1>;

        images {
                uboot {
                        description = "U-Boot (64-bit)";
                        data = /incbin/("u-boot-nodtb.bin");
                        type = "standalone";
                        os = "U-Boot";
                        arch = "arm64";
                        compression = "none";
                        load = <0x%08x>;
                        hash {
                                algo = "sha256";
                        };
                };
"""

DT_IMAGES_NODE_END="""
        };
"""

DT_END="""
};
"""

def append_atf_node(file, atf_index, phy_addr):
    """
    Append ATF DT node to input FIT dts file.
    """
    data = 'bl31_0x%08x.bin' % phy_addr
    print >> file, '\t\tatf@%d {' % atf_index
    print >> file, '\t\t\tdescription = \"ARM Trusted Firmware\";'
    print >> file, '\t\t\tdata = /incbin/("%s");' % data
    print >> file, '\t\t\ttype = "firmware";'
    print >> file, '\t\t\tarch = "arm64";'
    print >> file, '\t\t\tos = "arm-trusted-firmware";'
    print >> file, '\t\t\tcompression = "none";'
    print >> file, '\t\t\tload = <0x%08x>;' % phy_addr
    if atf_index == 1:
        print >> file, '\t\t\tentry = <0x%08x>;' % phy_addr
    print >> file, '\t\t\thash {'
    print >> file, '\t\t\t\talgo = "sha256";'
    print >> file, '\t\t\t};'
    print >> file, '\t\t};'
    print >> file, ''

def append_fdt_node(file, dtbs):
    """
    Append FDT nodes.
    """
    cnt = 1
    for dtb in dtbs:
        dtname = os.path.basename(dtb)
        print >> file, '\t\tfdt {'
        print >> file, '\t\t\tdescription = "U-Boot device tree blob";'
        print >> file, '\t\t\tdata = /incbin/("u-boot.dtb");'
        print >> file, '\t\t\ttype = "flat_dt";'
        print >> file, '\t\t\tarch = "arm64";'
        print >> file, '\t\t\tcompression = "none";'
        print >> file, '\t\t\thash {'
        print >> file, '\t\t\t\talgo = "sha256";'
        print >> file, '\t\t\t};'
        print >> file, '\t\t};'
        print >> file, ''
        cnt = cnt + 1

def append_conf_section(file, cnt, dtname, atf_cnt):
    print >> file, '\t\tconfig {'
    print >> file, '\t\t\tdescription = "Rockchip armv8 with ATF";'
    print >> file, '\t\t\trollback-index = <0x0>;'
    print >> file, '\t\t\tfirmware = "atf@1";'
    print >> file, '\t\t\tloadables = "uboot",',
    for i in range(1, atf_cnt):
        print >> file, '"atf@%d"' % (i+1),
        if i != (atf_cnt - 1):
            print >> file, ',',
        else:
            print >> file, ';'
    print >> file, '\t\t\tfdt = "fdt";'
    print >> file, '\t\t\tsignature {'
    print >> file, '\t\t\t\talgo = "sha256,rsa2048";'
    print >> file, '\t\t\t\tpadding = "pss";'
    print >> file, '\t\t\t\tkey-name-hint = "dev";'
    print >> file, '\t\t\t\tsign-images = "fdt", "firmware", "loadables";'
    print >> file, '\t\t\t};'
    print >> file, '\t\t};'
    print >> file, ''

def append_conf_node(file, dtbs, atf_cnt):
    """
    Append configeration nodes.
    """
    cnt = 1
    print >> file, '\tconfigurations {'
    print >> file, '\t\tdefault = "config";'
    for dtb in dtbs:
        dtname = os.path.basename(dtb)
        append_conf_section(file, cnt, dtname, atf_cnt)
        cnt = cnt + 1
    print >> file, '\t};'
    print >> file, ''

def generate_atf_fit_dts(fit_file_name, bl31_file_name, uboot_file_name, dtbs_file_name):
    """
    Generate FIT script for ATF image.
    """
    if fit_file_name != sys.stdout:
        fit_file = open(fit_file_name, "wb")
    else:
        fit_file = sys.stdout

    num_load_seg = 0
    p_paddr = 0xFFFFFFFF
    with open(uboot_file_name) as uboot_file:
        uboot = ELFFile(uboot_file)
        for i in range(uboot.num_segments()):
            seg = uboot.get_segment(i)
            if ('PT_LOAD' == seg.__getitem__(ELF_SEG_P_TYPE)):
                p_paddr = seg.__getitem__(ELF_SEG_P_PADDR)
                num_load_seg = num_load_seg + 1

    assert (p_paddr != 0xFFFFFFFF and num_load_seg == 1)

    print >> fit_file, DT_HEADER % p_paddr

    with open(bl31_file_name) as bl31_file:
        bl31 = ELFFile(bl31_file)
        for i in range(bl31.num_segments()):
            seg = bl31.get_segment(i)
            if ('PT_LOAD' == seg.__getitem__(ELF_SEG_P_TYPE)):
                paddr = seg.__getitem__(ELF_SEG_P_PADDR)
                p= seg.__getitem__(ELF_SEG_P_PADDR)
                append_atf_node(fit_file, i+1, paddr)
    atf_cnt = i+1
    append_fdt_node(fit_file, dtbs_file_name)
    print >> fit_file, '%s' % DT_IMAGES_NODE_END
    append_conf_node(fit_file, dtbs_file_name, atf_cnt)
    print >> fit_file, '%s' % DT_END

    if fit_file_name != sys.stdout:
        fit_file.close()

def generate_atf_binary(bl31_file_name):
    with open(bl31_file_name) as bl31_file:
        bl31 = ELFFile(bl31_file)

        num = bl31.num_segments()
        for i in range(num):
            seg = bl31.get_segment(i)
            if ('PT_LOAD' == seg.__getitem__(ELF_SEG_P_TYPE)):
                paddr = seg.__getitem__(ELF_SEG_P_PADDR)
                file_name = 'bl31_0x%08x.bin' % paddr
                with open(file_name, "wb") as atf:
                    atf.write(seg.data());

def get_bl31_segments_info(bl31_file_name):
    """
    Get load offset, physical offset, file size
    from bl31 elf file program headers.
    """
    with open(bl31_file_name) as bl31_file:
        bl31 = ELFFile(bl31_file)

        num = bl31.num_segments()
        print 'Number of Segments : %d' % bl31.num_segments()
        for i in range(num):
            print 'Segment %d' % i
            seg = bl31.get_segment(i)
            ptype = seg[ELF_SEG_P_TYPE]
            poffset = seg[ELF_SEG_P_OFFSET]
            pmemsz = seg[ELF_SEG_P_MEMSZ]
            pfilesz = seg[ELF_SEG_P_FILESZ]
            print 'type: %s\nfilesz: %08x\nmemsz: %08x\noffset: %08x' % (ptype, pfilesz, pmemsz, poffset)
            paddr = seg[ELF_SEG_P_PADDR]
            print 'paddr: %08x' % paddr

def main():
    uboot_elf="./u-boot"
    bl31_elf="./bl31.elf"
    FIT_ITS=sys.stdout

    opts, args = getopt.getopt(sys.argv[1:], "o:u:b:h")
    for opt, val in opts:
        if opt == "-o":
            FIT_ITS=val
        elif opt == "-u":
            uboot_elf=val
        elif opt == "-b":
            bl31_elf=val
        elif opt == "-h":
            print __doc__
            sys.exit(2)

    dtbs = args
    #get_bl31_segments_info("u-boot")
    #get_bl31_segments_info("bl31.elf")

    generate_atf_fit_dts(FIT_ITS, bl31_elf, uboot_elf, dtbs)
    generate_atf_binary(bl31_elf);

if __name__ == "__main__":
    main()

拷贝命令过来:

root@zhengyang:/work/sambashare/rk3399/u-boot-2023.04# cp ../u-boot/arch/arm/mach-rockchip/make_fit_atf.py ./arch/arm/mach-rockchip/
1.2.4 配置uboot启动倒计时

如果在uboot启动倒计时结束之前,没有按下任何键,将会执行那么将执行也就是bootcmd中配置中的命令,bootcmd中保存着默认的启动命令。

(5) delay in seconds before automatically booting

保存文件,输入文件名为evb-rk3399_defconfig ,在当前路径下生成evb-rk3399_defconfig ,存档:

root@zhengyang:/work/sambashare/rk3399/u-boot# mv evb-rk3399_defconfig ./configs/

注意:如果需要配置生效,需要使用make distclean清除之前的配置,重新执行配置命令。

1.3 编译uboot

执行make命令,生成u-boot文件:

root@zhengyang:/work/sambashare/rk3399/u-boot# make ARCH=arm CROSS_COMPILE=arm-linux- 

然后出现了如下错误:

binman: Filename 'atf-bl31' not found in input path (.,.,./board/rockchip/evb_rk3399,arch/arm/dts) (cwd='/work/sambashare/rk3399/u-boot-2023.04')

大致意思就是缺少了bl31.elf文件,我们将《Rockchip RK3399 - TPL/SPL方式加载uboot》章节制作的bl31.elf拷贝到uboot根目录下:

root@zhengyang:/work/sambashare/rk3399/u-boot-2023.04# cp /work/sambashare/rk3399/arm-trusted-firmware/build/rk3399/release/bl31/bl31.elf ./
root@zhengyang:/work/sambashare/rk3399/u-boot-2023.04# cp bl31.elf atf-bl31

重新编译,可以看到在 ./spl./tpl目录下生成镜像文件:

root@zhengyang:/work/sambashare/rk3399/u-boot-2023.04# ls tpl/u-boot*
tpl/u-boot.cfg      tpl/u-boot-tpl      tpl/u-boot-tpl.dtb      tpl/u-boot-tpl.map        tpl/u-boot-tpl.sym
tpl/u-boot-spl.lds  tpl/u-boot-tpl.bin  tpl/u-boot-tpl-dtb.bin  tpl/u-boot-tpl-nodtb.bin
root@zhengyang:/work/sambashare/rk3399/u-boot-2023.04# ls spl/u-boot*
spl/u-boot.cfg  spl/u-boot-spl.bin  spl/u-boot-spl-dtb.bin  spl/u-boot-spl.map        spl/u-boot-spl.sym
spl/u-boot-spl  spl/u-boot-spl.dtb  spl/u-boot-spl.lds      spl/u-boot-spl-nodtb.bin

二、idbloader.img

我们基于uboot源码编译出TPL/SPL,其中TPL负责实现DDR初始化,TPL初始化结束之后会回跳到BootROM程序,BootROM程序继续加载SPLSPL加载u-boot.itb文件,然后跳转到uboot执行。

idbloader.img是由tpl/u-boot-tpl.binspl/u-boot-spl.bin文件生成,这里我们需要使用到tools目录下的mkimage工具。

2.1 tpl/u-boot-tpl.bin

u-boot目录下执行:

root@zhengyang:/work/sambashare/rk3399/u-boot-2023.04# tools/mkimage -n rk3399 -T rksd -d tpl/u-boot-tpl.bin idbloader.img
Image Type:   Rockchip RK33 (SD/MMC) boot image
Init Data Size: 53248 bytes

其中:

  • -n rk3399将镜像文件的名称设置为rk3399
  • -T rksd将映像类型指定为Rockchip SD卡启动映像;
  • -d tpl/u-boot-tpl.bin将生成的TPL镜像文件tpl/u-boot-tpl.bin指定为输入文件,而idbloader.img则指定为输出文件。

生成idbloader.img文件:

root@zhengyang:/work/sambashare/rk3399/u-boot-2023.04#  ll idbloader.img
-rw-r--r-- 1 root root 55296 May 21 17:12 idbloader.img

2.2 spl/u-boot-spl.bin

spl/u-boot-spl.bin合并到idbloader.img

root@zhengyang:/work/sambashare/rk3399/u-boot-2023.04# cat spl/u-boot-spl.bin >> idbloader.img
root@zhengyang:/work/sambashare/rk3399/u-boot-2023.04# ll idbloader.img
-rw-r--r-- 1 root root 143866 May 21 17:13 idbloader.img

三、u-boot.idb

3.1 u-boot.itd生成规则

这里我们需要生成FIT image,对应的镜像文件名称为u-boot.itd,在顶层Makefile定义有:

ifdef U_BOOT_ITS
u-boot.itb: u-boot-nodtb.bin \
                $(if $(CONFIG_OF_SEPARATE)$(CONFIG_OF_EMBED)$(CONFIG_SANDBOX),dts/dt.dtb) \
                $(if $(CONFIG_MULTI_DTB_FIT),$(FINAL_DTB_CONTAINER)) \
                $(U_BOOT_ITS) FORCE
        $(call if_changed,mkfitimage)
        $(BOARD_SIZE_CHECK)
endif

ifneq ($(CONFIG_SPL_FIT_SOURCE),"")             // 方式1. 如果自己已经有u-boot.its,配置CONFIG_SPL_FIT_SOURCE=u-boot.its
U_BOOT_ITS := u-boot.its
$(U_BOOT_ITS): $(subst ",,$(CONFIG_SPL_FIT_SOURCE))
        $(call if_changed,copy)
else
ifneq ($(CONFIG_USE_SPL_FIT_GENERATOR),)   // 方式2.  使用脚本生成 配置CONFIG_USE_SPL_FIT_GENERATOR=y
U_BOOT_ITS := u-boot.its
$(U_BOOT_ITS): $(U_BOOT_ITS_DEPS) FORCE
        $(srctree)/$(CONFIG_SPL_FIT_GENERATOR) \ 
        $(patsubst %,arch/$(ARCH)/dts/%.dtb,$(subst ",,$(CONFIG_OF_LIST))) > $@           // 在$(patsubst %.c,%.o,$(dir) )中,patsubst把$(dir)中的变量符合后缀是.c的全部替换成.o
endif
endif

这里我们采用的配置CONFIG_SPL_FIT_GENERATOR的方式来生成u-boot.its,也就是我们在执行make menuconfig时配置的:

CONFIG_SPL_FIT_SOURCE=""
CONFIG_USE_SPL_FIT_GENERATOR=y
CONFIG_SPL_FIT_GENERATOR="arch/arm/mach-rockchip/make_fit_atf.py"

3.2 编译

执行编译命令:

root@zhengyang:/work/sambashare/rk3399/u-boot-2023.04# make u-boot.itb ARCH=arm CROSS_COMPILE=arm-linux-
  UPD     include/generated/timestamp_autogenerated.h
  ENVC    include/generated/env.txt
  ENVP    include/generated/env.in
  ENVT    include/generated/environment.h
  CC      cmd/version.o
  AR      cmd/built-in.o
  CC      env/common.o
  AR      env/built-in.o
  CC      lib/efi_loader/dtbdump.o
  LD      lib/efi_loader/dtbdump_efi.so
  OBJCOPY lib/efi_loader/dtbdump.efi
  CC      lib/efi_loader/initrddump.o
  LD      lib/efi_loader/initrddump_efi.so
  OBJCOPY lib/efi_loader/initrddump.efi
  LD      u-boot
  OBJCOPY u-boot-nodtb.bin
  RELOC   u-boot-nodtb.bin
./"arch/arm/mach-rockchip/make_fit_atf.py" \
arch/arm/dts/rk3399-evb.dtb > u-boot.its
  MKIMAGE u-boot.itb

编译完成在当前路径下生成u-boot.itsu-boot.itb文件。

root@zhengyang:/work/sambashare/rk3399/u-boot-2023.04# ll u-boot.it*
-rw-r--r-- 1 root root 974224 May 21 17:14 u-boot.itb
-rw-r--r-- 1 root root   2423 May 21 17:14 u-boot.its

其中u-boot.its文件内容如下:

/*
 * Copyright (C) 2017 Fuzhou Rockchip Electronics Co., Ltd
 *
 * Minimal dts for a SPL FIT image payload.
 *
 * SPDX-License-Identifier: GPL-2.0+  X11
 */
/dts-v1/;

/ {
        description = "Configuration to load ATF before U-Boot";
        #address-cells = <1>;

        images {
                uboot {
                        description = "U-Boot (64-bit)";
                        data = /incbin/("u-boot-nodtb.bin");
                        type = "standalone";
                        os = "U-Boot";
                        arch = "arm64";
                        compression = "none";
                        load = <0x00200000>;
                        hash {
                                algo = "sha256";
                        };
                };

                atf@1 {
                        description = "ARM Trusted Firmware";
                        data = /incbin/("bl31_0x00040000.bin");
                        type = "firmware";
                        arch = "arm64";
                        os = "arm-trusted-firmware";
                        compression = "none";
                        load = <0x00040000>;
                        entry = <0x00040000>;
                        hash {
                                algo = "sha256";
                        };
                };

                atf@2 {
                        description = "ARM Trusted Firmware";
                        data = /incbin/("bl31_0xff3b0000.bin");
                        type = "firmware";
                        arch = "arm64";
                        os = "arm-trusted-firmware";
                        compression = "none";
                        load = <0xff3b0000>;
                        hash {
                                algo = "sha256";
                        };
                };

                atf@3 {
                        description = "ARM Trusted Firmware";
                        data = /incbin/("bl31_0xff8c0000.bin");
                        type = "firmware";
                        arch = "arm64";
                        os = "arm-trusted-firmware";
                        compression = "none";
                        load = <0xff8c0000>;
                        hash {
                                algo = "sha256";
                        };
                };
                atf@4 {
                        description = "ARM Trusted Firmware";
                        data = /incbin/("bl31_0xff8c1000.bin");
                        type = "firmware";
                        arch = "arm64";
                        os = "arm-trusted-firmware";
                        compression = "none";
                        load = <0xff8c1000>;
                        hash {
                                algo = "sha256";
                        };
                };

                atf@5 {
                        description = "ARM Trusted Firmware";
                        data = /incbin/("bl31_0xff8c2000.bin");
                        type = "firmware";
                        arch = "arm64";
                        os = "arm-trusted-firmware";
                        compression = "none";
                        load = <0xff8c2000>;
                        hash {
                                algo = "sha256";
                        };
                };

                fdt {
                        description = "U-Boot device tree blob";
                        data = /incbin/("u-boot.dtb");
                        type = "flat_dt";
                        arch = "arm64";
                        compression = "none";
                        hash {
                                algo = "sha256";
                        };
                };

        };

        configurations {
                default = "config";
                config {
                        description = "Rockchip armv8 with ATF";
                        rollback-index = <0x0>;
                        firmware = "atf@1";
                        loadables = "uboot", "atf@2" , "atf@3" , "atf@4" , "atf@5" , "atf@6" ;
                        fdt = "fdt";
                        signature {
                                algo = "sha256,rsa2048";
                                padding = "pss";
                                key-name-hint = "dev";
                                sign-images = "fdt", "firmware", "loadables";
                        };
                };

        };

};

四、Linux 6.3版本FIT uImage

在《Rockchip RK3399 - 移植linux 5.2.8》中我们已经介绍了linux 5.2.8版本FIT uImage镜像的制作,这一节我们将简单介绍一下linux 6.3版本FIT uImage镜像的制作。

4.1 源码下载

我们这里下载linux-6.3版本,执行如下命令:

root@zhengyang:/work/sambashare/rk3399# wget http://ftp.sjtu.edu.cn/sites/ftp.kernel.org/pub/linux/kernel/v6.x/linux-6.3.tar.gz

解压:

root@zhengyang:/work/sambashare/rk3399# tar -xvf linux-6.3.tar.gz

4.2 配置Makefile

修改顶层的Makefile,打开Makefile文件,找到下面语句:

ARCH        ?= $(SUBARCH)

修改为:

ARCH        ?= arm64
CROSS_COMPILE    ?= arm-linux-

其中,ARCH是指定目标平台为 arm64 , CROSS_COMPILE 是指定交叉编译器,这里指定的是系统默认的交叉编译器,如要使用其它的,则要把编译器的全路径在这里写出。

交叉编译工具链安装参考:《https://www.cnblogs.com/zyly/p/17380243.html#_label3》。

4.3 内核defconfig配置

接下来要做的就是内核配置、编译了。单板的默认配置文件在arch/arm64/configs目录下:

root@zhengyang:/work/sambashare/rk3399/linux-6.3# ll arch/arm64/configs/defconfig
-rw-rw-r-- 1 root root 35014 Apr 24 03:02 arch/arm64/configs/defconfig
root@zhengyang:/work/sambashare/rk3399/linux-6.3# make defconfig

4.4 内核裁切

关于内核裁切内容比较多,参考《Rockchip RK3399 - 移植linux 5.2.8》即可。其中有一些步骤略有不同:

(1) 由于我们不使用ramdisk根文件系统,所以不用配置支持RAM块设备;

(2) 在配置有限网卡驱动的时候发生一些变化:

Device Drivers  ---> 
  [*] Network device support  --->
     [*] Ethernet driver support  --->    
        [*] STMicroelectronics devices 
            [*] STMicroelectronics Multi-Gigabit Ethernet driver
                 [*] STMMAC Platform bus support
                       [*] Rockchip dwmac support

(3) 配置支持SquashFS文件系统;

File systems ---> 
   -*- Miscellaneous filesystems 
       <*> SquashFS 4.0 - Squashed file system support 
           [*] Squashfs XATTR support 
           [*] Include support for ZLIB compressed file systems
           [*] Include support for LZ4 compressed file systems
           [*] Include support for LZO compressed file systems
           [*] Include support for XZ compressed file systems

配置这个的目的是后面移植的ubuntu根文件系统需要使用;如果不配置这个,当移植了ubuntu根文件系统时,内核启动会出现类似下面的错误;

[    9.192204] squashfs: SQUASHFS error: Filesystem uses "xz" compression. This is not supported

4.5 修改设备树

4.5.1 配置display-subsystem设备节点

执行如下命令:

root@zhengyang:/work/sambashare/rk3399/linux-6.3# vim arch/arm64/boot/dts/rockchip/rk3399.dtsi

将以下节点:

display-subsystem {
        compatible = "rockchip,display-subsystem";
        ports = <&vopl_out>, <&vopb_out>;
};

修改为:

display_subsystem: display-subsystem {
        compatible = "rockchip,display-subsystem";
        ports = <&vopl_out>, <&vopb_out>;
};
4.5.2 新增子节点属性

由于我使用的是HDMI显示器,因此需要在arch/arm64/boot/dts/rockchip/rk3399-evb.dts中为以下节点新增属性:

&i2c7 {
        status = "okay";
};

&display_subsystem {
         status = "okay";
};

&vopl {
        status = "okay";
};

&vopl_mmu {
        status = "okay";
};
     

&vopb {
        status = "okay";
};

&vopb_mmu {
        status = "okay";
};

&hdmi {
        ddc-i2c-bus = <&i2c7>;
        pinctrl-names = "default";
        pinctrl-0 = <&hdmi_cec>;
        status = "okay";
};

同时需要将edp更改为禁用状态;

&edp {
        status = "disabled";
        ....    
};

4.6 编译内核

linux内核根目录下执行如下命令:

root@zhengyang:/work/sambashare/rk3399/linux-6.3# make -j8

编译完成,在arch/arm64/boot/文件夹下生成Image镜像文件,以及设备树dst/rockchip/xxx.dtb文件;

root@zhengyang:/work/sambashare/rk3399/linux-6.3# ll arch/arm64/boot/
总用量 52836
drwxrwxr-x  3 root root     4096 Jun 12 23:10 ./
drwxrwxr-x 14 root root     4096 Jun 12 22:54 ../
drwxrwxr-x 35 root root     4096 Apr 24 03:02 dts/
-rw-rw-r--  1 root root       64 Apr 24 03:02 .gitignore
-rw-r--r--  1 root root 40665600 Jun 12 23:10 Image
-rw-r--r--  1 root root      139 Jun 12 23:10 .Image.cmd
-rw-r--r--  1 root root 13585031 Jun 12 23:10 Image.gz
-rw-r--r--  1 root root      106 Jun 12 23:10 .Image.gz.cmd
-rwxrwxr-x  1 root root      962 Apr 24 03:02 install.sh*
-rw-rw-r--  1 root root     1198 Apr 24 03:02 Makefile
root@zhengyang:/work/sambashare/rk3399/linux-6.3/arch/arm64/boot/dts/rockchip# ls *rk3399*.dtb
rk3399-eaidk-610.dtb         rk3399-gru-scarlet-kd.dtb       rk3399-nanopi-m4b.dtb             rk3399pro-rock-pi-n10.dtb   rk3399-rock-pi-4c.dtb
rk3399-evb.dtb               rk3399-hugsun-x99.dtb           rk3399-nanopi-m4.dtb              rk3399-puma-haikou.dtb      rk3399-rockpro64.dtb
rk3399-ficus.dtb             rk3399-khadas-edge-captain.dtb  rk3399-nanopi-neo4.dtb            rk3399-rock-4c-plus.dtb     rk3399-rockpro64-v2.dtb
rk3399-firefly.dtb           rk3399-khadas-edge.dtb          rk3399-nanopi-r4s.dtb             rk3399-rock960.dtb          rk3399-roc-pc.dtb
rk3399-gru-bob.dtb           rk3399-khadas-edge-v.dtb        rk3399-nanopi-r4s-enterprise.dtb  rk3399-rock-pi-4a.dtb       rk3399-roc-pc-mezzanine.dtb
rk3399-gru-kevin.dtb         rk3399-kobol-helios64.dtb       rk3399-orangepi.dtb               rk3399-rock-pi-4a-plus.dtb  rk3399-roc-pc-plus.dtb
rk3399-gru-scarlet-dumo.dtb  rk3399-leez-p710.dtb            rk3399-pinebook-pro.dtb           rk3399-rock-pi-4b.dtb       rk3399-sapphire.dtb
rk3399-gru-scarlet-inx.dtb   rk3399-nanopc-t4.dtb            rk3399-pinephone-pro.dtb          rk3399-rock-pi-4b-plus.dtb  rk3399-sapphire-excavator.dtb

4.7 创建its文件

因为mkimage是根据its文件中的描述来打包镜像生成itb文件(FIT uImage),所以首先需要制作一个its文件,在its文件中描述需要被打包的镜像,主要是kernel镜像,dtb文件。

我们创建一个kernel.its文件,内容如下:

/*
 * Simple U-Boot uImage source file containing a single kernel and FDT blob
 */
/dts-v1/;

/ {
        description = "Simple image with single Linux kernel and FDT blob";
        #address-cells = <1>;

        images {

                kernel {
                        description = "Vanilla Linux kernel";
                        data = /incbin/("arch/arm64/boot/Image.gz");
                        type = "kernel";
                        arch = "arm64";
                        os = "linux";
                        compression = "gzip";
                        load = <0x280000>;
                        entry = <0x280000>;
                        hash-1 {
                                algo = "crc32";
                        };
                        hash-2 {
                                algo = "sha1";
                        };
                };

               fdt {
                        description = "Flattened Device Tree blob";
                        data = /incbin/("arch/arm64/boot/dts/rockchip/rk3399-evb.dtb");
                        type = "flat_dt";
                        arch = "arm64";
                        compression = "none";
                        load = <0x8300000>;
                        entry = <0x8300000>;
                        hash-1 {
                                algo = "crc32";
                        };
                        hash-2 {
                                algo = "sha1";
                        };
                };

        };

        configurations {
                default = "conf-1";
                conf-1 {
                        description = "Boot Linux kernel with FDT blob";
                        kernel = "kernel";
                        fdt = "fdt";
                };
        };
};

4.8 生成kernel.itb

在制作kernel.itb时编译命令和《Rockchip RK3399 - 移植linux 5.2.8》中说的略有不同,这里我们需要将u-boot-2023.04路径下的mkimage工具拷贝过来,然后在命令行使用mkimage工具编译即可:

root@zhengyang:/work/sambashare/rk3399/linux-6.3# cp ../u-boot-2023.04/tools/mkimage ./
root@zhengyang:/work/sambashare/rk3399/linux-6.3# ./mkimage -f kernel.its kernel.itb

需要注意的是这里一定不能指定-E参数,不然uboot在进行kernel镜像hash校验的时候就会失败。

五、烧录测试

由于我们每次修改程序后,重新编译步骤比较麻烦,这里我们可以将这些步骤编写成一个shell脚本,这样每次执行就比较容易了。

5.1 自动构建脚本

uboot根目录下创建一个build.sh文件:

#!/bin/bash

# 接收第一个参数 支持 ''|'config'|'clean'
step=$1
# 接收 V=1  支持编译输出详细信息
V=$2
cmd=${V%=*}

if [[ ${cmd} = 'V' ]]; then
    V=${V#*=}
fi

if [[ ${step} == "config" ]];then
    echo '----------------config evb-rk3399_defconfig------- -------------'
    make evb-rk3399_defconfig V=${V}
fi

if [[ -z ${step} ]];then
    echo "---------------1. compile uboot-------------------------------- "
    make ARCH=arm CROSS_COMPILE=arm-linux- V=${V}
    echo "---------------2. mkimahe idbloader----------------------------"
    tools/mkimage -n rk3399 -T rksd -d tpl/u-boot-tpl.bin idbloader.img
    cat spl/u-boot-spl.bin >> idbloader.img
    echo "---------------3. make itb-------------------------------------"
    make u-boot.itb ARCH=arm CROSS_COMPILE=arm-linux-
    cp ./u-boot.itb ../rkdeveloptool
    cp ./idbloader.img ../rkdeveloptool
fi

if [[ ${step} == "clean" ]];then
    echo "-----------------clean-----------------------------------------"
    make clean  
    make distclean
fi

然后给文件赋予可执行权限:

root@zhengyang:/work/sambashare/rk3399/u-boot-2023.04#  chmod +x build.sh
5.1.1 clean

执行如下命令进行清理:

root@zhengyang:/work/sambashare/rk3399/u-boot-2023.04#  ./build.sh clean
5.1.2 配置

执行如下命令进行uboot配置:

root@zhengyang:/work/sambashare/rk3399/u-boot# ./build.sh config
----------------config evb-rk3399_defconfig------- -------------
  HOSTCC  scripts/basic/fixdep
  HOSTCC  scripts/kconfig/conf.o
  HOSTCC  scripts/kconfig/zconf.tab.o
  HOSTLD  scripts/kconfig/conf
#
# configuration written to .config
#
5.1.3 构建

执行如下命令进行uboot编译、生成idbloader.img u-boot.itb文件,并拷贝到rkdeveloptool目录下:

root@zhengyang:/work/sambashare/rk3399/u-boot-2023.04# ./build.sh

如果需要输出编译详情信息,追加V=1参数即可。

5.2 烧录uboot

烧录方法有两种:

  • 一种是基于Rockchip的官方烧录工具RKDevTool;官方RKDevTool是基于recovery模式实现的,如果板子带有recovery按键,可以使用这种方式;
  • 另外一种是在开发板上使用rkdeveloptool工具直接烧写eMMC;这里我们采用rkdeveloptool烧录的方式;
5.2.1 准备镜像

我们需按照之前的流程得到了idbloader.imgu-boot.itb文件,由于我们这里不进行内核和根文件系统的烧录,所以暂时不需要准备这俩。

按照Rockchip官方要求将idbloader.img烧录到eMMC0x40扇区,u-boot.itb烧录到0x4000扇区。

我们需要将idbloader.imgu-boot.itbkernel.itb拷贝到rkdeveloptool路径下:

root@zhengyang:/work/sambashare/rk3399/rkdeveloptool# cp ../u-boot-2023.04/u-boot.itb ./
root@zhengyang:/work/sambashare/rk3399/rkdeveloptool# cp ../linux-6.3/kernel.itb ./
5.2.2 进入MASKROM升级模式

NanoPC-T4开发板如需进入MASKROM升级模式,需要进入如下操作:

  • 将开发板连接上电源,并且连接Type-C数据线到PC
  • 按住BOOT键再长按Power键开机(保持按下BOOT5秒以上),将强制进入MASKROM模式。

一般电脑识别到USB连接,都会发出声音。或者观察虚拟机右下角是否突然多个USB设备:右键点击链接;

亲爱的读者和支持者们,自动博客加入了打赏功能,陆陆续续收到了各位老铁的打赏。在此,我想由衷地感谢每一位对我们博客的支持和打赏。你们的慷慨与支持,是我们前行的动力与源泉。

日期姓名金额
2023-09-06*源19
2023-09-11*朝科88
2023-09-21*号5
2023-09-16*真60
2023-10-26*通9.9
2023-11-04*慎0.66
2023-11-24*恩0.01
2023-12-30I*B1
2024-01-28*兴20
2024-02-01QYing20
2024-02-11*督6
2024-02-18一*x1
2024-02-20c*l18.88
2024-01-01*I5
2024-04-08*程150
2024-04-18*超20
2024-04-26.*V30
2024-05-08D*W5
2024-05-29*辉20
2024-05-30*雄10
2024-06-08*:10
2024-06-23小狮子666
2024-06-28*s6.66
2024-06-29*炼1
2024-06-30*!1
2024-07-08*方20
2024-07-18A*16.66
2024-07-31*北12
2024-08-13*基1
2024-08-23n*s2
2024-09-02*源50
2024-09-04*J2
2024-09-06*强8.8
2024-09-09*波1
2024-09-10*口1
2024-09-10*波1
2024-09-12*波10
2024-09-18*明1.68
2024-09-26B*h10
2024-09-3010
2024-10-02M*i1
2024-10-14*朋10
2024-10-22*海10
2024-10-23*南10
2024-10-26*节6.66
2024-10-27*o5
2024-10-28W*F6.66
2024-10-29R*n6.66
2024-11-02*球6
2024-11-021*鑫6.66
2024-11-25*沙5
2024-11-29C*n2.88
posted @   大奥特曼打小怪兽  阅读(7742)  评论(6编辑  收藏  举报
如果有任何技术小问题,欢迎大家交流沟通,共同进步

公告 & 打赏

>>

欢迎打赏支持我 ^_^

最新公告

程序项目代做,有需求私信(小程序、网站、爬虫、电路板设计、驱动、应用程序开发、毕设疑难问题处理等)。

了解更多

点击右上角即可分享
微信分享提示