U-Boot开发手册
=================

J6X启动流程概述
-----------------

J6X系统软件启动流程包括如下几部分，如下图所示：

|image1|

U-Boot功能概述
-----------------

在启动流程图中，BL33即U-Boot部分，具有故障恢复、下载软件、加载验证内核的功能。

Verified Boot
~~~~~~~~~~~~~~~~

在J6X BOOT软件系统中，验证启动功能使用Android平台成熟的AVB2.0方案，该方案完善、成熟、高效、支持AB分区，并且具有完整的工具可供使用。

Download
~~~~~~~~~~~

U-Boot需要支持从以太网刷写固件，目前方案是采用fastboot协议，通过以太网来链接。

|image2|


U-Boot开发简介
-----------------

U-Boot编译及打包
~~~~~~~~~~~~~~~~~~~

开发环境参考 :doc:`开发环境准备 <../j6_sysdev_development_environment>`

build环境搭建参考 :doc:`build与生成镜像 <../build/j6_sysdev_build>`

编译及打包命令参考如下：

.. code:: text

    #加载编译相关环境变量
    user.name@hz-server-1:~/work/J6/soc$ source envsetup.sh lunch
    ++ make clean
    rm -rf /home/user.name/work/J6/soc/.config* /home/user.name/work/J6/soc/out/generated_kconfigs
    ++ make lunch
    make -C /home/user.name/work/J6/soc/build_tools/kbuild_tools/src O=/home/user.name/work/J6/soc/out/host/kbuild_tools config
    make[1]: Entering directory '/home/user.name/work/J6/soc/build_tools/kbuild_tools/src'
      GEN     /home/user.name/work/J6/soc/out/host/kbuild_tools/Makefile
    make[3]: Nothing to be done for 'config'.
    make[1]: Leaving directory '/home/user.name/work/J6/soc/build_tools/kbuild_tools/src'
    You're in configuration
    Lunch menu...pick a combo:

    J6
            1 ---> j6e_evm_defconfig
            2 ---> j6e_gcc9_evm_defconfig

    Which would you like?  1

    You select CHIP=J6E Config=j6e_evm_defconfig
    #
    # configuration written to .config
    #
    Configuration created from  lunch
    =========================================
    BOARD_CONFIG="j6e_evm_defconfig"
    ARCH="arm64"
    CROSS_COMPILE="/usr/bin/aarch64-linux-gnu-"
    HR_TARGET_VENDOR="horizon"
    HR_TARGET_PROJECT="j6e"
    HR_TARGET_MODE="debug"
    HR_TARGET_BIT="64"
    KERNEL_VER="6.1.94"
    =========================================
    Shortcut commands:
        build.sh docker: bd, bdall, bdm, bdkmhb, bdkmk
        kernel menuconfig: bkmc
    =========================================

    #编译U-Boot
    bdm uboot

    #打包完整镜像，打包完成后镜像生成在$HR_TOP_DIR/out/debug-gcc_12.2-64/target/product/img_packages目录下
    cd $HR_TOP_DIR
    bd img disk

    #打包U-Boot镜像，打包完成后镜像生成在$HR_TOP_DIR/out/debug-gcc_12.2-64/target/product/img_packages目录下
    bd img uboot_a
    bd img uboot_b

兼容不同单板
~~~~~~~~~~~~~~~~

获取boardid
^^^^^^^^^^^^^^

目前J6X芯片使用adc0、1来识别board id。mcu将启动参数信息传到指定的ddr acore_cfg位置，uboot从中获取adc的这两路通道值。如下：

.. code:: c

    int32_t i;
    uint32_t btype_lsb, btype_msb;
    void *bdinfo_addr = (void *)(((uint64_t)config_dtb_addr - 0xb000000) & 0xFFE00000);
    struct sci_boot_flags *hb_sci_boot = (struct sci_boot_flags *)bdinfo_addr;

    btype_lsb = hb_sci_boot->boardid_adc_ch0;
    btype_msb = hb_sci_boot->boardid_adc_ch1;

    for(i = 0; i < (sizeof(hb_j6x_btype_list) / sizeof(struct hb_j6x_btype_node)); i++) {
        if ((btype_lsb == hb_j6x_btype_list[i].boardid_lsb) && (btype_msb == hb_j6x_btype_list[i].boardid_msb)) {
            btype_select_node = hb_j6x_btype_list[i];
            break;
        }
    }

通过如下数组，根据boardid选择对应的config：

.. code:: c

    const static struct hb_j6x_btype_node hb_j6x_btype_list[] = {
        {0x3, 0x9, "hobot-j6e-evm", "j6e-evm-kernel"},
        {0x4, 0x8, "hobot-j6e-matrix", "j6e-matrix-kernel"},
        {0x6, 0x0, "hobot-j6e-matrix-sip", "j6e-matrix-sip-kernel"},
        // ...
    };

网络调试
~~~~~~~~~~~

在J6X系统软件中，U-Boot中主要功能之一烧录镜像依赖于网络，因此网络适配与调试为U-Boot开发过程中主要关注问题。

Phy配置
^^^^^^^^^^

在phy相关适配中，除phy芯片本身驱动外，主要关注dts中gmac节点下phy地址及pin配置，如下图所示：

.. code:: bash

    eth0: eth0 {
            status = "disabled";
            compatible = "hobot,j6-gmac";
            /*MAC, XPCS, ETH PHY, PCIE PHY, hsis reg*/
            reg = <0x0 0x330f0000 0x0 0x10000>,
                <0x0 0x33200000 0x0 0x80000>;
            phy-handle = <&phy1>;
            phy-mode = "sgmii";
            managed = "in-band-status";
            pinctrl-names = "default";
            pinctrl-0 = <&peri_emac>;
            #address-cells = <1>;
            #size-cells = <0>;
            phy1: phy@1 {
                compatible = "ethernet-phy-ieee802.3-c45";
                reg = <0x3>;
            };
        };

        eth1: eth1 {
            status = "okay";
            compatible = "hobot,j6-gmac";
            /*MAC, XPCS, ETH PHY, PCIE PHY, hsis reg*/
            reg = <0x0 0x33100000 0x0 0x10000>,
                <0x0 0x33280000 0x0 0x80000>;
            phy-mode = "sgmii";
            #address-cells = <1>;
            #size-cells = <0>;
            fixed-link {
                speed = <1000>;
                full-duplex;
            };
        };

        peri_emac: peri_emac_func {
            pinmux {
                function = "peri_emac";
                groups = "peri_emac_mdc_hsi0", "peri_emac_mdio_hsi0";
            };
            pinconf {
                groups = "peri_emac_mdc_hsi0", "peri_emac_mdio_hsi0";
                drive-strength = <8>;
            };
        };



J6X引脚配置
^^^^^^^^^^^^^

在emmc调试过程中，需要检查emmc的供电电压与J6X sdio接口的供电电压是否相同，检查PAD的配置电压是否匹配，以及在波形不符合预期的情况下，可以配置J6X对应引脚的驱动能力。可以在$HR_TOP_DIR/uboot/arch/arm/dts/hobot-j6e-pinctrl.dtsi配置。

|image5|

其中low-power-enable代表该组引脚配置为1.8V，与其对应的low-power-disable代表该组引脚配置为3.3V。drive-strength代表该组引脚的驱动能力调整为等级8。



Fix-link配置
^^^^^^^^^^^^^^^

在J6X不经过phy芯片，直连switch的情况下，即称之为fix-link模式，可以参考设备树$HR_TOP_DIR/uboot/arch/arm/dts/hobot-j6e-matrix.dts中的eth1节点设置，如下所示：

.. code:: bash

    eth1: eth1 {
        status = "okay";
        compatible = "hobot,j6-gmac";
        /*MAC, XPCS, ETH PHY, PCIE PHY, hsis reg*/
        reg = <0x0 0x33100000 0x0 0x10000>,
            <0x0 0x33280000 0x0 0x80000>;
        phy-mode = "sgmii";
        #address-cells = <1>;
        #size-cells = <0>;
        fixed-link {
            speed = <1000>;
            full-duplex;
        };
    };

其中speed = <1000>表示工作在千兆模式下，full-duplex表示工作状态为全双工模式。

常用调试方法
---------------

debug log
~~~~~~~~~~~~

boot console可用于输出error和trace log，但默认情况下U-Boot使用的debug()、pr\_debug()等宏都不会输出任何内容。

在某个.c文件中开启这些debug输出，我们需要定义DEBUG宏并且改变CONFIG\_LOGLEVEL宏，在#include之前添加下面三条宏定义，或者修改这个.c文件的Makefile，如下图所示：

|image7|

|image8|

如果希望将U-Boot的所有源代码都开启debug输出，那么首先要往$HR_TOP_DIR/uboot/configs/\*defconfig添加一个CONFIG\_LOGLEVEL=8选项，然后在top Makefile中添加KBUILD\_CFLAGS += -DDEBUG=1 选项，如下图所示：

|image9|

|image10|

常用命令
~~~~~~~~~~~

.. code:: bash

    #环境变量相关
    printenv #打印当前环境变量
    setenv #设置环境变量
    editenv #编辑环境变量
    saveenv #保存环境变量
    #网络相关
    setenv ipaddr xx.xx.xx.xx #设置本机ip
    setenv serverip xx.xx.xx.xx #设置服务端ip
    setenv ethaddr/eth1addr x.x.x.x.x.x #设置mac地址
    setenv netmask xx.xx.xx.xx #设置网关
    setenv ethact ethernet@59110000/59120000 #设置目标网口
    #给kernel cmdline添加参数
    setenv bootargs ${bootargs} <items to add>
    #打开Kernel debug输出
    setenv loglevel 10
    setenv console “ttyS1”
    setenv console “uart8250,mmio32,0x43B90000”
    #其他
    fastboot udp #fastboot 通过网络烧写镜像
    fastboot 0   #fastboot 通过USB dfu工具烧写镜像


.. |image1| image:: ./media/boot.drawio.png
   :width: 5.49375in
   :height: 5.94236in
.. |image2| image:: ./media/fastboot-uboot.png
   :width: 6.29097in
   :height: 4.10972in
.. |image3| image:: ./media/image4.png
   :width: 6.29861in
   :height: 2.65486in
.. |image4| image:: ./media/image5.png
   :width: 5.34514in
   :height: 1.39097in
.. |image5| image:: ./media/pin.jpg
   :width: 6.29861in
   :height: 3.86944in
.. |image6| image:: ./media/image7.png
   :width: 3.85139in
   :height: 1.46597in
.. |image7| image:: ./media/image8.png
   :width: 3.69792in
   :height: 1.01042in
.. |image8| image:: ./media/image9.png
   :width: 4.32292in
   :height: 0.56250in
.. |image9| image:: ./media/image10.png
   :width: 2.69792in
   :height: 0.51042in
.. |image10| image:: ./media/image11.png
   :width: 4.93750in
   :height: 1.81250in
