U-Boot移植

这篇具有很好参考价值的文章主要介绍了U-Boot移植。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、为什么要U-Boot移植?

我们知道uboot就是一个bootloader,但是ARM不像我们的PC机一样,并不是用U盘随便下一个Windows镜像就可以安装了。我们的uboot对应的就是一个U盘里面刷的引导程序。虽然uboot支持很多架构以及很多不同厂商的板子,但是UBOOT并不具备通用性。跟我们的电脑不一样,无论是华为、小米、联想他们的底层引导程序都是一样的。所以uboot移植是要跟做手术一样对一些东西进行裁剪和配置,从而让uboot适配我们的板子。

二、NXP官方开发板uboot编译

uboot的移植并不是说我们完完全全的从零开始将uboot移植到我们现在所使用的开发板或者开发平台上。这个对于我们来说基本是不可能的,这个工作一般是半导体厂商做的,半导体厂商负责将uboot一直到他们的芯片上,因此半导体厂商都会自己做一个开发板,然后将uboot移植到他们自己的原厂开发板上,测试好以后就把他们的uboot发布出去,这个就是我们所说的原厂BSP包。我们一般做产品的时候就会参考原厂的开发板做硬件,在原厂的BSP上做修改,将uboot或者linux kernel移植到我们的硬件上。

uboot移植的一般流程:

(1)在uboot中找到参考的开发平台,一般是原厂的开发板

(2)参考原厂开发板移植uboot到我们所使用的开发板上

我们是将NXP官方的uboot移植到正点原子的I.MX6ULL开发板上,我们将uboot-imx-rel_imx_4.1.15_2.1.0_ga.tar.bz2发送到ubuntu中并解压,然后创建VScode工程

  1. 查找NXP官方的开发板默认配置文件
uboot移植,uboot,arm开发,嵌入式硬件,Powered by 金山文档

在此路径下面有很多的配置文件,其中以mx6ull开头的是IMX6ULL开发板的。IMX6ULL有9x9mm和14x14mm两种尺寸的。我们使用是mx6ull_14x14开头的默认配置文件,由于我们使用EMMC版本的,所以我们使用mx6ull_14x14_evk_emmc_defconfig作为默认配置文件

  1. 编译NXP官方开发板对应的uboot

执行命令:

make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- mx6ull_14x14_evk_emmc_defconfig
make V=1 ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j4

编译完成以后结果如下

uboot移植,uboot,arm开发,嵌入式硬件,Powered by 金山文档

也可通过修改Makefile,但是这样编译太麻烦了,可以通过编写一个shell脚本,shell脚本名称为mx6ull_14x14_emmc.sh。执行命令vi mx6ull_14x14_emmc.sh,添加内容

#!/bin/bash
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- distclean
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- mx6ull_14x14_evk_emmc_defconfig
make V=1 ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j4

distclean是清理工程后在编译,-j4表示线程数

然后给予mx6ull_14x14_emmc.sh这个文件可执行权限

chmod 777 mx6ull_14x14_emmc.sh

可以查看这个文件已经变成了绿色,然后执行编译命令

./mx6ull_14x14_evk_emmc.sh

编译完之后会生成u-boot.bin、u-boot.imx等文件

  1. 烧写验证与驱动测试

将imxdownload软件拷贝到uboot源码根目录下,然后使用imxdownload软件将u-boot.bin烧写到SD卡中。烧写命令如下;

chmod 777 imxdownload
./imxdownload u-boot.bin /dev/sdb    //烧写到SD卡中,不能烧写到sda中
uboot移植,uboot,arm开发,嵌入式硬件,Powered by 金山文档

使用超级终端,上电测试正常

uboot移植,uboot,arm开发,嵌入式硬件,Powered by 金山文档

DRAM识别正常,是512MB

检查SD卡和EMMC

使用命令mmc list列出当前的MMC设备

uboot移植,uboot,arm开发,嵌入式硬件,Powered by 金山文档

可见当前有两个设备

检查SD卡信息

uboot移植,uboot,arm开发,嵌入式硬件,Powered by 金山文档

检查MMC1

uboot移植,uboot,arm开发,嵌入式硬件,Powered by 金山文档

由于LCD和网络驱动目前都不适配板子,所以先不讲解

三、在U-Boot中添加自己的开发板

直接创建一个VScode工程,把之前的.vscode拷贝进去

uboot移植,uboot,arm开发,嵌入式硬件,Powered by 金山文档
  1. 添加开发板默认配置文件

先在configs目录下创建默认配置文件,复制mx6ull_14x14_evk_emmc_defconfig,然后重命名为mx6ull_alientek_emmc_defconfig,命令如下:

cd configs
cp mx6ull_14x14_evk_emmc_defconfig mx6ull_alientek_emmc_defconfig

然后将文件mx6ull_alientek_emmc_defconfig中的内容改成下面的

CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/freescale/mx6ull_alientek_emmc/imximage.cfg,MX6ULL_EVK_EMMC_REWORK"
CONFIG_ARM=y
CONFIG_ARCH_MX6=y
CONFIG_TARGET_MX6ULL_ALIENTEK_EMMC=y
CONFIG_CMD_GPIO=y
  1. 添加开发板对应的头文件

在目录include/configs下添加IMX6ULL-ALPHA开发板对应的头文件,复制include/configs/mx6ullevk.h,并重命名为mx6ull_alientek_emmc.h,命令如下

cp include/configs/mx6ullevk.h mx6ull_alientek_emmc.h

拷贝完成以后将:

#ifndef __MX6ULLEVK_CONFIG_H
#define __MX6ULLEVK_CONFIG_H

改为:

#ifndef __MX6ULL_ALIENTEK_EMMC_CONFIG_H
#define __MX6ULL_ALIENTEK_EMMC_CONFIG_H
  1. 添加开发板对应的板级文件夹

uboot中每个板子都有一个对应的文件夹来存放板级文件,比如开发板上外设驱动文件等。NXPde 板级文件夹是mx6ullevk,将其重命名为mx6ull_alientek_emmc

cd board/freescale/
cp mx6ullevk/ -r mx6ull_alientek_emmc

修改文件名

cd mx6ull_alientek_emmc
mv mx6ullevk.c mx6ull_alientek_emmc.c

修改mx6ull_alientek_emmc目录下的Makefile文件

# (C) Copyright 2015 Freescale Semiconductor, Inc.
#
# SPDX-License-Identifier:    GPL-2.0+
#

obj-y  := mx6ull_alientek_emmc.o

extra-$(CONFIG_USE_PLUGIN) :=  plugin.bin
$(obj)/plugin.bin: $(obj)/plugin.o
    $(OBJCOPY) -O binary --gap-fill 0xff $< $@

重点是修改第6行,改为mx6ull_alientek_emmc.o

修改mx6ull_alientek_emmc目录下的imximage.cfg文件

将imximage.cfg中的下面一句
PLUGIN board/freescale/mx6ullevk/plugin.bin 0x00907000
改为
PLUGIN board/freescale/mx6ull_alientek_emmc /plugin.bin 0x00907000

修改Kconfig文件,修改后如下

if TARGET_MX6ULL_ALIENTEK_EMMC

config SYS_BOARD
    default "mx6ull_alientek_emmc"

config SYS_VENDOR
    default "freescale"

config SYS_CONFIG_NAME
    default "mx6ull_alientek_emmc"

endif

修改mx6ull_alientek_emmc目录下的MAINTAINERS文件

MX6ULLEVK BOARD
M:    Peng Fan <peng.fan@nxp.com>
S:    Maintained
F:    board/freescale/mx6ull_alientek_emmc/
F:    include/configs/mx6ull_alientek_emmc.h
F:    configs/mx6ull_alientek_emmc_defconfig
  1. 修改U-Boot图形配置界面配置文件

应该修改arch/arm/Kconfig文件,在最后一行的endif的前一行添加如下内容

source "board/freescale/mx6ull_alientek_emmc/Kconfig"
  1. 使用新添加的板子配置编译uboot

在uboot根目录下新建一个mx6ull_alientek_emmc.sh的shell脚本

#!/bin/bash
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- distclean
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- (加空格)mx6ull_alientek_emmc_defconfig
make V=1 ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j4

给与可执行权限

chmod 777 mx6ull_alientek_emmc.sh //给予可执行权限,一次即可
./mx6ull_alientek_emmc.sh //运行脚本编译 uboot

等待编译完成,输入如下指令,查看mx6ull_alientek_emmc.h这个头文件有没有被引用

grep -nR "mx6ull_alientek_emmc.h"

将u-boot.bin烧写到SD卡测试

uboot移植,uboot,arm开发,嵌入式硬件,Powered by 金山文档
  1. LCD驱动修改

一般uboot中修改驱动基本都是在xxx.h和xxx.c这两个文件中进行,比如在mx6ull_alientek.h和mx6ull_alientek_emmc.c

一般修改LCD驱动重点注意以下几点:

  • LCD所使用的GPIO,查看uboot中LCD的IO配置是否正确

  • LCD背光引脚GPIO的配置

  • LCD配置参数是否正确

正点原子的开发板LCD原理图和NXP的开发板一致,也就是LCD的IO和背光IO都一样,因此只需要修改配置参数

struct display_info_t const displays[] = {{
    .bus = MX6UL_LCDIF1_BASE_ADDR,
    .addr = 0,
    .pixfmt = 24,
    .detect = NULL,
    .enable    = do_enable_parallel_lcd,
    .mode    = {
        .name            = "TFT7016",
        .xres           = 1024,
        .yres           = 600,
        .pixclock       = 19531,
        .left_margin    = 140,
        .right_margin   = 160,
        .upper_margin   = 20,
        .lower_margin   = 12,
        .hsync_len      = 20,
        .vsync_len      = 3,
        .sync           = 0,
        .vmode          = FB_VMODE_NONINTERLACED
} } };

这个结构体是LCD信息结构体,其中包含了LCD的分辨率。像素格式,LCD的各个参数。

struct display_info_t {
    int    bus;
    int    addr;
    int    pixfmt;
    int    (*detect)(struct display_info_t const *dev);
    void    (*enable)(struct display_info_t const *dev);
    struct    fb_videomode mode;
};

pixfmt是像素格式,也就是一个像素点是多少位,如果是RGB565就是16位,RGB888是24位,一般使用RGB888。结构体display_info_t还有个mode成员变量,此成员变量也是个结构体fb_videomode

struct fb_videomode {
    const char *name;    /* optional */
    u32 refresh;        /* optional */
    u32 xres;
    u32 yres;
    u32 pixclock;
    u32 left_margin;
    u32 right_margin;
    u32 upper_margin;
    u32 lower_margin;
    u32 hsync_len;
    u32 vsync_len;
    u32 sync;
    u32 vmode;
    u32 flag;
};

结构体fb_videomode里面的成员变量是LCD的参数

name:LCD名字,要和成员变量中 的panel相等

xres、yres:LCD X轴和Y轴像素数量

pixclock:像素时钟,每个像素时钟周期的长度,单位是皮秒

left_margin:HBP,水平同步后肩。

right_margin:HFP,水平同步前肩。

upper_margin:VBP,垂直同步后肩。

lower_margin:VFP,垂直同步前肩。

hsync_len:HSPW,行同步脉宽。

vsync_len:VSPW,垂直同步脉宽。

vmode:大多数使用 FB_VMODE_NONINTERLACED,也就是不使用隔行扫描。

以正点原子的7寸1024*600分辨率的屏幕(ATK7016)为例,屏幕要求的像素时钟是51.2MHz

pixclock=(1/51200000)*10^12=19531

因此配置代码如下

struct display_info_t const displays[] = {{
    .bus = MX6UL_LCDIF1_BASE_ADDR,
    .addr = 0,
    .pixfmt = 24,
    .detect = NULL,
    .enable    = do_enable_parallel_lcd,
    .mode    = {
        .name            = "TFT7016",
        .xres           = 1024,
        .yres           = 600,
        .pixclock       = 19531,
        .left_margin    = 140,
        .right_margin   = 160,
        .upper_margin   = 20,
        .lower_margin   = 12,
        .hsync_len      = 20,
        .vsync_len      = 3,
        .sync           = 0,
        .vmode          = FB_VMODE_NONINTERLACED
} } };

打开mx6ull_alientek_emmc.h将panel=TFT43AB

改为panel=TFT7016

重新编译一遍uboot再烧写到SD启动,此时LCD上显示NXP的logo。如果还是黑屏,那么在uboot中修改panel的值

setenv panel TFT7016
saveenv

然后保存,重启uboot。此时LCD正常工作

  1. 网络驱动修改

IMX6ULL内部有个以太网MAC外设,也就是ENET,需要外接一个PHY芯片来实现网络通信功能,也就是内部MAC+外部PHY芯片的方案。正点原子的IMX6U-ALPHA开发板提供了两个接口,其中ENET1和ENET2都使用LAN8720A作为PHY芯片

uboot移植,uboot,arm开发,嵌入式硬件,Powered by 金山文档

ENET1的网络PHY芯片位LAN8720A,通过RMII接口与IMX6ULL相连,正点原子开发板的额ENET1引脚与NXP官方的开发板基本一样,只有复位引脚不一样。

LAN8720A内部是有寄存器的,IMX6ULL会读取LAN8720内部寄存器来判断当前的物理连接状态、连接速度(10M还是100M)和双工状态(半双工还是全双工)。IMX6ULL通过MDIO接口来读取PHY芯片的内部寄存器,MDIO接口有两个引脚,ENET_MDC和ENET_MDIO。ENET_MDC提供时钟,ENET_MDIO进行数据传输。一个MDIO接口可以管理32个PHY芯片,同一个MDIO接口下的PHY使用不同的器件地址即可访问到相应的PHY芯片。IMX6ULL-ALPHA开发板ENET1上连接的LAN8720A器件地址是0X0,所以我们要修改的ENET1网络驱动就三点

  • ENET1复位引脚初始化

  • LAN8720A的器件ID

  • LAN8720驱动

uboot移植,uboot,arm开发,嵌入式硬件,Powered by 金山文档
  • ENET2所使用的PHY器件地址是0X1

  • ENET1和ENET2都是用的LAN8720A,所以驱动是一样的

网络地址修改

打开mx6ull_alientek_emmc.h

#ifdef CONFIG_CMD_NET
#define CONFIG_CMD_PING
#define CONFIG_CMD_DHCP
#define CONFIG_CMD_MII
#define CONFIG_FEC_MXC
#define CONFIG_MII
#define CONFIG_FEC_ENET_DEV        1

#if (CONFIG_FEC_ENET_DEV == 0)
#define IMX_FEC_BASE            ENET_BASE_ADDR
#define CONFIG_FEC_MXC_PHYADDR          0x0
#define CONFIG_FEC_XCV_TYPE             RMII
#elif (CONFIG_FEC_ENET_DEV == 1)
#define IMX_FEC_BASE            ENET2_BASE_ADDR
#define CONFIG_FEC_MXC_PHYADDR        0x1
#define CONFIG_FEC_XCV_TYPE        RMII
#endif
#define CONFIG_ETHPRIME            "FEC"

#define CONFIG_PHYLIB
#define CONFIG_PHY_SMSC
#endif

第 7 行的宏 CONFIG_FEC_ENET_DEV 用于选择使用哪个网口,默认为 1,也就是选择ENET2。第 11 行为 ENET1 的 PHY 地址,默认是 0X2,第 15 行为 ENET2 的 PHY 地址,默认为 0x1。根据前面的分析可知,正点原子的 I.MX6U-ALPHA 开发板 ENET1 的 PHY 地址为0X0,ENET2 的 PHY 地址为 0X1,所以需要将第 11 行的宏 CONFIG_FEC_MXC_PHYADDR改为 0x0。

1、修改ENET1网络PHY的地址
2、修改ENET2网络PHY的地址
3、使能SMSC公司的PHY驱动

删除uboot中的74LV595的驱动代码

在mx6ull_alientek_emmc.c中找到如下代码

#define IOX_SDI IMX_GPIO_NR(5, 10)
#define IOX_STCP IMX_GPIO_NR(5, 7)
#define IOX_SHCP IMX_GPIO_NR(5, 11)
#define IOX_OE IMX_GPIO_NR(5, 8)

由于正点原子没有使用74LV595,所以删除这些代码,替换为如下代码

#define ENET1_RESET IMX_GPIO_NR(5, 7)
#define ENET2_RESET IMX_GPIO_NR(5, 8)

ENET1的复位引脚连接到SNVS_TAMPER7上,对应GPIO5_IO07,ENET2的复位引脚连接到SNVS_TAMPER7上,对应GPIO5_IO08。

继续在mx6ull_alientek_emmc.h中找到如下代码

static iomux_v3_cfg_t const iox_pads[] = {
 /* IOX_SDI */
 MX6_PAD_BOOT_MODE0__GPIO5_IO10 | MUX_PAD_CTRL(NO_PAD_CTRL),
 /* IOX_SHCP */
 MX6_PAD_BOOT_MODE1__GPIO5_IO11 | MUX_PAD_CTRL(NO_PAD_CTRL),
 /* IOX_STCP */
 MX6_PAD_SNVS_TAMPER7__GPIO5_IO07 | MUX_PAD_CTRL(NO_PAD_CTRL),
 /* IOX_nOE */
 MX6_PAD_SNVS_TAMPER8__GPIO5_IO08 | MUX_PAD_CTRL(NO_PAD_CTRL),
};

继续找到iox74lv_init,iox74lv_set都删除掉,然后删除掉board_init_r的imx_iomux_v3_setup_multiple_pads 和 iox74lv_init 这两行。

接着添加开发板网络复位引脚驱动

uboot移植,uboot,arm开发,嵌入式硬件,Powered by 金山文档
uboot移植,uboot,arm开发,嵌入式硬件,Powered by 金山文档

接着添加网络复位的初始化代码,修改后的setup_iomux_fec函数如下

static void setup_iomux_fec(int fec_id)
{
    if (fec_id == 0)
    {
        imx_iomux_v3_setup_multiple_pads(fec1_pads,
                      ARRAY_SIZE(fec1_pads));

        gpio_direction_output(ENET1_RESET, 1);
        gpio_set_value(ENET1_RESET, 0);
        mdelay(20);
        gpio_set_value(ENET1_RESET, 1);                     
    }
    else 
    {
        imx_iomux_v3_setup_multiple_pads(fec2_pads,
                      ARRAY_SIZE(fec2_pads));
        gpio_direction_output(ENET2_RESET, 1);
        gpio_set_value(ENET2_RESET, 0);
        mdelay(20);
        gpio_set_value(ENET2_RESET, 1);
    }
}

8~11行和17~20行分别对应ENET1和ENET2的复位IO初始化,将这两个IO设置为输出并硬件复位以下LAN8720A,否则可能导致uboot无法导致LAN8720A

修改drivers/net/phy/phy.c文件中的函数genphy_update_link

找到函数genphy_update_link,这个是通用PHY驱动函数,此函数用于更新PHY的连接状态和速度,使用LAN87829A的时候需要再次函数中添加一些代码,修改后的代码如下

int genphy_update_link(struct phy_device *phydev)
{
    unsigned int mii_reg;


#ifdef CONFIG_PHY_SMSC
    static int lan8720_flag = 0;
    int bmcr_reg = 0;
    if (lan8720_flag == 0) {
        bmcr_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR);
        phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, BMCR_RESET);
        while(phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR) & 0X8000) {
            udelay(100);
        }
        phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, bmcr_reg);
        lan8720_flag = 1;
    }
#endif

   
    return 0;
}

第6~18行是新添加的代码,是条件编译代码,只有使用SMSC公司的PHY这段代码才会执行

至此网络的复位引脚驱动修改完成,重新编译uboot,然后将u-boot.bin烧写到SD卡启动

uboot移植,uboot,arm开发,嵌入式硬件,Powered by 金山文档

然后开始设置几个环境变量

setenv ipaddr 192.168.1.55 //开发板 IP 地址
setenv ethaddr b8:ae:1d:01:00:00 //开发板网卡 MAC 地址
setenv gatewayip 192.168.1.1 //开发板默认网关
setenv netmask 255.255.255.0 //开发板子网掩码
setenv serverip 192.168.1.250 //服务器地址,也就是 Ubuntu 地址
saveenv //保存环境变量

设置好环境变量之后就可以在ubot中使用网络,用网线将ENET2与电脑或者路由器连接起来,保证开发板和电脑在同一个网段内,通过Ping命令测试一下网络连接

ping 192.168.1.250
uboot移植,uboot,arm开发,嵌入式硬件,Powered by 金山文档

也可以测试一下ENET1的网络是否正常工作,将CONFIG_FEC_ENET_DEV 改为 0,然后重新编译uboot烧写到SD卡。

  1. 修改板子名字
int checkboard(void)
{
 if (is_mx6ull_9x9_evk())
 puts("Board: MX6ULL 9x9 EVK\n");
 else
 puts("Board: MX6ULL ALIENTEK EMMC\n");
 return 0;
}

四、bootcmd和bootargs环境变量

uboot中有两个重要的环境变量bootcmd和bootargs

1、环境变量bootcmd

bootcmd保存着uboot默认命令,uboot倒计时结束以后就会执行bootcmd中的命令。这些命令一般都是用来启动linux内核的,比如你读取EMMC或者NAND Flash中的linux内核镜像文件和设备树文件到DRAM,然后启动LINUX内核。可以在uboot启动以后进入命令行设置bootcmd环境变量的值。如果EMMC或者NAND中没有博爱村bootcmd的值,那么uboot就会使用默认的值,板子第一次运行uboot的时候都会使用默认值来设置bootcmd环境变量。

从EMMC中读取zImage镜像文件和设备树文件命令

mmc dev 1 //切换到 EMMC
fatload mmc 1:1 0x80800000 zImage //读取 zImage 到 0x80800000 处
fatload mmc 1:1 0x83000000 imx6ull-14x14-evk.dtb //读取设备树到 0x83000000 处
bootz 0x80800000 - 0x83000000 //启动 Linux

当我们知道所使用的板子时,代码可简化

#define CONFIG_BOOTCOMMAND \
 "mmc dev 1;" \
 "fatload mmc 1:1 0x80800000 zImage;" \
 "fatload mmc 1:1 0x83000000 imx6ull-alientek-emmc.dtb;" \
 "bootz 0x80800000 - 0x83000000;"

或者可以直接在uboot中设置bootcmd的值,命令如下

setenv bootcmd 'mmc dev 1; fatload mmc 1:1 80800000 zImage; fatload mmc 1:1 83000000 imx6ull-alientek-emmc.dtb; bootz 80800000 - 83000000;'
2、环境变量bootargs

bootargs保存着uboot传递给linux内核的参数,bootargs环境变量是由mmcargs设置的,mmcargs环境变量如下:

mmcargs=setenv bootargs console=${console},${baudrate} root=${mmcroot}

其中console=ttymxc0,baudrate=115200,mmcroot=/dev/mmcblk1p2 rootwait rw,因此将mmcargs展开以后就是

mmcargs=setenv bootargs console= ttymxc0, 115200 root= /dev/mmcblk1p2 rootwait rw

bootargs就是设置很多参数的值,常用的参数有:

  1. console

console用来设置linux终端(或者叫控制台),也就是通过什么设备来和linux进行交互,时串口还是LCD屏幕?,如果串口,应该是串口几等。一般设置串口作为linux终端,这样我们就可以通过MobaXtem来和linux交互了。这里设置console为ttymxc0

  1. root

root用来设置根文件系统的位置,root=/dev/mmcblk1p2用于指明根文件系统存放在mmcblk1设备的分区2中。EMMC 版本的核心板启动 linux 以后会存在/dev/mmcblk0、

/dev/mmcblk1、/dev/mmcblk0p1、/dev/mmcblk0p2、/dev/mmcblk1p1 和/dev/mmcblk1p2 这样的文件,其中/dev/mmcblkx(x=0~n)表示 mmc 设备,而/dev/mmcblkxpy(x=0n,y=1n)表示 mmc 设备x 的分区 y。在 I.MX6U-ALPHA 开发板中/dev/mmcblk1 表示 EMMC,而/dev/mmcblk1p2 表示EMMC 的分区 2。

root后面rootwait rw,rootwait表示等待mmc设备初始化完成后再挂载,否则会出错。rw表示根文件系统是可以读写的,不加rw可能无法在根文件系统进行写操作,只能进行读操作

五、uboot启动linux系统

1、从emmc启动linux系统

从EMMC启动也就是将编译出来的linux镜像文件zImage和设备树文件保存在EMMC中,uboot从EMMC读取这两个文件并启动,这个是我们产品的最终启动方式。设置环境变量

setenv bootargs 'console=ttymxc0,115200 root=/dev/mmcblk1p2 rootwait rw'
setenv bootcmd 'mmc dev 1; fatload mmc 1:1 80800000 zImage; fatload mmc 1:1 83000000 imx6ull-alientek-emmc.dtb; bootz 80800000 - 83000000;
saveenv

设置好以后输入boot可启动Linux内核

2、从网络启动linux系统

从网络启动linux系统的目的是为了调试。不管是调试Linux系统还是驱动,每次修改系统文件或者驱动以后都要将其烧写到EMMC测试,这样太麻烦。我们可以将linux镜像文件和跟文件系统都放到ubuntu某个文件夹,这样每次编译linux内核或驱动,只需要cp命令拷贝到这个指定的文件夹中即可,不用频繁的烧写EMMC,加快了开发速度。

我们使用tftp从ubuntu下载zImage和设备树文件,然后将这两个文件放到ubuntu的tftp目录下

uboot移植,uboot,arm开发,嵌入式硬件,Powered by 金山文档

设置环境变量以后就可以启动

六、总结:

简单总结uboot移植过程文章来源地址https://www.toymoban.com/news/detail-698966.html

①、不管是购买的开发板还是自己做的开发板,基本都是参考半导体厂商的 dmeo 板,而半导体厂商会在他们自己的开发板上移植好 uboot、linux kernel 和 rootfs 等,最终制作好 BSP包提供给用户。我们可以在官方提供的 BSP 包的基础上添加我们的板子,也就是俗称的移植。
②、我们购买的开发板或者自己做的板子一般都不会原封不动的照抄半导体厂商的 demo
板,都会根据实际的情况来做修改,既然有修改就必然涉及到 uboot 下驱动的移植。
③、一般 uboot 中需要解决串口、NAND、EMMC 或 SD 卡、网络和 LCD 驱动,因为 uboot
的主要目的就是启动 Linux 内核,所以不需要考虑太多的外设驱动。
④、在 uboot 中添加自己的板子信息,根据自己板子的实际情况来修改 uboot 中的驱动。

到了这里,关于U-Boot移植的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 嵌入式开发之linux内核移植

    目录  前言 一、下载内核源码 1.1 下载linux-3.0.1 1.2 解压源码文件 二、 内核添加yaffs2文件系统支持 2.1 下载yaffs2 2.2 内核添加yaffs2文件补丁 三、配置开发板 3.1 修改机器ID 3.2 添加开发板初始化文件 3.3 配置NandFalsh 3.3.1 添加NandFlash设备 3.3.2 添加NandFlash驱动 3.3 修改Kconfig(支持

    2024年02月07日
    浏览(78)
  • 基于RK3588的嵌入式linux系统开发(五)——uboot优化修改(按任意按键停止autoboot)

            我们通常情况下,芯片进入uboot后,会根据设置的bootdelay时间进行倒数计数。这时候在终端按任意键,即可退出autoboot,进入uboot的命令行模式。         官方提供的uboot源码中,为了防止调试串口干扰导致不能进入系统,使用“Ctrl+c”的组合键来退出autoboot。本

    2024年02月10日
    浏览(40)
  • 嵌入式Linux底层系统开发 +系统移植+内核文件系统(基础)

    搭建交叉编译开发环境 bootloader的选择和移植 kernel的配置、编译、移植和调试 根文件系统的制作 前两个要点通常芯片厂家提供。后边两个要点是公司的工作重点。 学习方法:先整体后局部,层层推进 如何编译—如何添加命令和功能—如何定义自己的开发板。 移植的基本步

    2024年02月03日
    浏览(50)
  • 嵌入式开发——ARM介绍

    ARM是一种芯片架构,由英国的ARM Holdings公司开发和授权,被广泛应用于各种嵌入式系统、移动设备和消费电子产品中。ARM架构被设计成低功耗、高性能、可定制化的特点,能够满足各种应用场景下的需求。 ARM架构主要设计了以下几个部分内容: 指令集架构 (Instruction Set Ar

    2024年02月04日
    浏览(40)
  • ARM裸机开发——简易嵌入式游戏开发

    利用LCD屏,实现简易的图片展示,展示个人信息 利用图片显示与按键功能实现简易的游戏设计,需要包含动画连贯展示   本实验主要为具体游戏设计,主要包含游戏架构设计、底层硬件设计、具体代码实现四部分,设计了本项目方案的架构图如图2.1所示。 图2.1 游戏设计整

    2024年02月06日
    浏览(44)
  • 嵌入式Linux开发——解决uboot无法使用nfs服务从ubuntu中下载文件(TTT、cannot mount等错误)

    最近在学习正点原子嵌入式Linux开发板uboot的移植实验,移植完之后想测试网络部分的驱动能否工作正常。最后经过测试发现tftp可以正常下载,nfs却一直报错无法下载文件,最后也是折磨了两天才解决了问题,特写下此博客进行记录、总结。 我的轻薄本没有网口,事先买了一

    2024年01月20日
    浏览(33)
  • 嵌入式linux驱动开发之移远4G模块EC800驱动移植指南

    回顾下移远4G模块移植过程, 还是蛮简单的。一通百通,无论是其他4G模块都是一样的。这里记录下过程,分享给有需要的人。环境使用正点原子的imax6ul开发板,板子默认支持中兴和移远EC20的驱动,这里要移植使用的是移远4G模块EC800。 imax6ul开发板 虚拟机(Ubuntu18.04) 交叉编译

    2024年02月17日
    浏览(48)
  • 嵌入式:ARM常用开发编译软件介绍

    ADS(ARM Developer Suite),是在1993年由Metrowerks公司开发是ARM处理器下最主要的开发工具。 他的前身是SDT,SDT是ARM公司几年前的开发环境软件,目前SDT早已经不再升级。ADS包括了四个模块分别是:SIMULATOR;C 编译器;实时调试器;应用函数库。ADS对汇编、C/C++、java支持的均很好,

    2024年02月06日
    浏览(39)
  • 单片机、ARM、嵌入式开发、Android 底层开发有什么关系?

    从我目前的见识来看: 单片机是个系统(比如:51、AVR、PLC...),其中包含了去除了输入输出之外的运算器、控制器、存储器,我们用程序可以非常直观的控制引脚电平的高低。最近很多小伙伴找我,说想要一些ARM的资料,然后我根据自己从业十年经验,熬夜搞了几个通宵,

    2024年02月02日
    浏览(53)
  • [ARM 汇编]高级部分—ARM汇编编程实战—3.3.2 嵌入式开发环境搭建

    搭建一个嵌入式开发环境主要包括以下几个部分: 安装交叉编译器 配置集成开发环境(IDE) 安装调试工具 下载和烧录程序 接下来,我们将详细介绍每个部分,并提供相应的实例。 安装交叉编译器 交叉编译器是用于将您编写的ARM汇编代码编译成可执行文件的工具。在本教程

    2024年02月11日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包