文章目录

  • Linux系统移植:官板 uboot 修改(下)
    • 一、LCD 驱动修改
    • 二、网口驱动修改
      • 2.1 PHY 地址修改
      • 2.2 删除 uboot 中 74LV595 的驱动代码
      • 2.3 添加 I.MX6U-ALPHA 开发板网络复位引脚驱动
      • 2.4 修改驱动函数
    • 三、其他修改
    • 四、bootcmd 和 bootargs 修改
      • 4.1 bootcmd 修改
      • 4.2 bootargs 修改

Linux系统移植:官板 uboot 修改(下)

上一节我们将官板的 uboot 修改后适配正点原子开发板,可以编译成功下载运行,但其中还有不少驱动没有移植完成,本节完成部分驱动和环境变量配置,适配开发板

修改驱动主要在我们上一章移植的 mx6ull_alientek_emmc.hboard/freescake/mx6ull_alientek_emmc/mx6ull_alientek_emmc.c 文件中进行修改

一、LCD 驱动修改

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

  • LCD 所使用的 GPIO,查看 uboot 中 LCD 的 IO 配置是否正确
  • LCD 背光引脚 GPIO 的配置
  • LCD 配置参数是否正确

原子的开发板和官板的 LCD 接口一致,所以不用修改,IO参数可以在 mx6ull_alientek_emmc.c 中的 lcd_pads 变量查看到

所以我们主要修改软件参数,在文件 mx6ull_alientek_emmc.c 中找到如下所示内容:

这段代码定义了一个 display_info_t 结构体,包含了 LCD 的分辨率,像素格式以及其他参数信息

display_info_t 定义在文件 arch/arm/include/asm/imx-common/video.h 中,详细可以去看一看

其中参数如下:

  • bus:LCD 寄存器基地址

  • pixfmt:像素格式,此处使用 RGB888 就是 24 位

  • mode 是 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,也就是不使用隔行扫描

具体屏幕参数参考如下:

按照上面参数计算,时钟计算方式如下:

pixclock=(1/屏幕主频)*10^12

屏幕移植后要将 mx6ull_alientek_emmc.h 中的 panel 参数名称和 fb_videomode 结构体的 name 相同,挂载成功后如下:

按道理屏幕会显示 NXP 的 LOGO 但是我移植完并没有显示,直接下载原子的代码也不能正常显示,原子提供代码和硬件肯定存在问题,查看的参考源码和我上面提供的参数,出处很大,后面需要再研究研究,但大致思路没有问题

二、网口驱动修改

IMX 有两个网口接口 ENET1 和 ENET2;

ENET1 的网络 PHY 芯片为 LAN8720A,通过 RMII 接口与 I.MX6ULL 相连,I.MX6U-ALPHA 开发板 ENET1 的网络原理图如图:

开发板的 ENET1 引脚与 NXP 官方的 I.MX6ULL EVK 开发板基本一样,只有复位引脚不同

I.MX6ULL 通过 MDIO接口来读取 PHY 芯片的内部寄存器,来判断当前的物理链接状态、连接速度 (10M 还是 100M) 和双工状态 (半双工还是全双工)

MDIO 接口有两个引脚,ENET_MDC 和 ENET_MDIO,ENET_MDC 提供时钟,ENET_MDIO 进行数据传输。一个 MDIO 接口可以管理 32 个 PHY 芯片,同一个 MDIO 接口下的这些 PHY 使用不同的器件地址来做区分,MIDO 接口通过不同的器件地址即可访问到相应的 PHY 芯片

ENET1 上连接的 LAN8720A器件地址为 0X0,要修改 ENET1 网络驱动的话重点就三点:

  • ENET1 复位引脚初始化
  • LAN8720A 的器件 ID
  • LAN8720 驱动

ENET2 驱动和 1 基本相同,但 ENET2 的复位引脚 ENET2_RST 接到了 I.MX6ULL 的 SNVS_TAMPER8 上,ENET2 所使用的 PHY 芯片器件地址为 0X1,所以修改 uboot 驱动分为以下的步骤:

2.1 PHY 地址修改

打开 mx6ull_alientek_emmc.h,看到如下宏定义:

宏 CONFIG_FEC_ENET_DEV 用于选择使用哪个网口,默认为 1,也就是选择 ENET2

CONFIG_FEC_MXC_PHYADDR 为 PHY 地址

宏 CONFIG_PHY_MICREL 用于使能 uboot 中的 PHY 驱动,修改为 CONFIG_PHY_SMSC

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

芯片地址修改完成以后就是网络复位引脚的驱动修改,NXP 官方 I.MX6ULL EVK 开发板使用 74LV595 来扩展 IO,两个网络的复位引脚就是由 74LV595 来控制的。正点原子的 I.MX6U-ALPHA 开发板并没有使用 74LV595,因此打开 mx6ull_alientek_emmc.c,删除如下代码:

替换为如下:

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

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

ENET2 的复位引脚连接到 SNVS_TAMPER8 上,对应 GPIO5_IO08

然后 在 mx6ull_alientek_emmc.c 中找到如下 IO 配置代码结构体,然后删除掉:

然后找到 iox74lv_set 和 iox74lv_init 函数,将他们删除

找到 board_init 函数调用的 iox74lv_init 和 imx_iomux_v3_setup_multiple_pads,然后删除:

2.3 添加 I.MX6U-ALPHA 开发板网络复位引脚驱动

2.2 中我们删除了引脚的初始化代码,2.3 小节需要添加初始化代码:

找到 iomux_v3_cfg_t const fec1_pads[] 和 iomux_v3_cfg_t const fec2_pads[],这两个结构体数组 fec1_pads 和 fec2_pads 是 ENET1 和 ENET2 这两个网口的 IO 配置参数,我么添加两个网口的复位 IO 配置参数

MX6_PAD_SNVS_TAMPER7__GPIO5_IO07 | MUX_PAD_CTRL(NO_PAD_CTRL),
MX6_PAD_SNVS_TAMPER8__GPIO5_IO08 | MUX_PAD_CTRL(NO_PAD_CTRL),

添加后如下:

找到网口初始化函数 setup_iomux_fec:

添加网口芯片复位代码:

硬件复位很重要,必须添加

2.4 修改驱动函数

打开文件 drivers/net/phy/phy.c,找到函数 genphy_update_link,这是个通用 PHY 驱动函数此函数用于更
新 PHY 的连接状态和速度。使用 LAN8720A 的时候需要在此函数中添加一些代码,修改后的函数 genphy_update_link 如下

这段代码的宏,我们在一开始已经添加了,只有使用 SMSC 公司的 PHY 这段代码才会执行,读取LAN8720A 的 BMCR 寄存器,然后向寄存器 BMCR 寄存器写入 BMCR_RESET,软件复位 LAN8720A,然后等待 LAN8720A 软件复位完成,最后重新向 BMCR 寄存器写入以前的值

到此网口修改完成,编译下载,运行观察

检测 NET 使用 FEC1成功,下面我们把开发板连接到电脑,设置电脑的网口和开发板在同一个 IP 下,用开发板 Ping Windows 和 ubuntu 的 IP 地址,结果如下,网口 Ping 通

三、其他修改

修改 uboot 启动后的板子名称,打开文件 mx6ull_alientek_emmc.c,找到函数 checkboard:

修改名称:

puts("Board: MX6ULL ALIENTEK EMMC\n");

编译下载,观察现象:

四、bootcmd 和 bootargs 修改

uboot 中有两个非常重要的环境变量 bootcmd 和 bootargs,这两个变量采用类似 shell 脚本语言编写的,里面有很多的变量引用,这些变量都是环境变量,很多是 NXP 定义的,文 件 mx6ull_alientek_emmc.h 中的宏
CONFIG_EXTRA_ENV_SETTINGS 保存着这些环境变量的默认值

CONFIG_EXTRA_ENV_SETTINGS 是个条件编译语句,通过宏定义在使用 NAND 和 EMMC 的时候宏CONFIG_EXTRA_ENV_SETTINGS 的值是不同

4.1 bootcmd 修改

bootcmd 保存着 uboot 默认命令,uboot 倒计时结束以后就会执行 bootcmd 中的命令,这些命令一般都是用来启动 Linux 内核的,比如读取 EMMC 或者 NAND Flash 中的 Linux 内核镜像文件和设备树文件到 DRAM 中,然后启动 Linux 内核,板子第一次运行 uboot 的时候都会使用默认值来设置 bootcmd 环境变量,在文件 include/env_default.h 中代码如下:

可以看到 uchar default_environment[] 数组保存了环境变量,我们可以在这个位置设置 bootcmd 的默认值!

也有一些环境变量调用了其他宏定义,比如 CONFIG_BOOTCOMMAND 这个宏定义,在 mx6ull_alientek_emmc.h 文件中可以找到:

这段代码使用类似 shell 语言代码编写:

  • run findfdt:使用的是 uboot 的 run 命令来运行 findfdt,用来查找开发板对应的设备树文件(.dtb)

findfdt 内容如下:

"findfdt="\
"if test $fdt_file = undefined; then " \
"if test $board_name = EVK && test $board_rev = 9X9; then " \
"setenv fdt_file imx6ull-9x9-evk.dtb; fi; " \
"if test $board_name = EVK && test $board_rev = 14X14; then " \
"setenv fdt_file imx6ull-14x14-evk.dtb; fi; " \
"if test $fdt_file = undefined; then " \
"echo WARNING: Could not determine dtb to use; fi; " \
"fi;\0" \

如果 fdt_file 为 undefined 的话,那 uboot 就会根据板子信息得出所需的.dtb 文件名

  • mmc dev ${mmcdev} 用于切换 mmc 设备,mmcdev 为 1,因此这行代码就是:mmcdev 1,也就是切换到 EMMC 上
  • 后面的代码先执行 mmc dev ${mmcdev}切换到 EMMC 上,然后使用命令 mmc rescan 扫描看有没有 SD 卡或者 EMMC 存在,若没有执行 run netboot,netboot 是一个自定义的环境变量,从网络启动 Linux
  • 如果有 EMMC 存在,先运行 loadbootscript 环境变量,该变量如下:
loadbootscript=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${script};

其中 mmcdev=1,mmcpart=1,loadaddr=0x80800000,script= boot.scr,这段代码 loadbootscript 就是从 mmc1 的分区 1 中读取文件 boot.src 到 DRAM 的 0X80800000 处

如果加载 boot.src 文件成功就运行 bootscript 环境变量,变量如下:

bootscript=echo Running bootscript from mmc ...;
source

如果 loadbootscript 没有执行成功,就会运行环境变量 loadimage,内容如下:

loadimage=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${image}

其中 mmcdev=1,mmcpart=1,loadaddr=0x80800000,image = zImage,这段代码就是从 mmc1 的分区中读取 zImage 到内存的 0X80800000 处,当加载 linux 镜像文件 zImage 成功以后就运行环境变量 mmcboot,mmcboot 环境变量如下:

输出信息,然后运行环境变量 mmcargs(mmcargs 用来设置 bootargs),然后判断boot_fdt是否为yes或者try,进而是否加载设备树,如果读取.dtb 文件成功的话那就调用命令 bootz 启动 linux,然后 Linux 内核启动

总结一下该命令执行过程:

  • 切换到 EMMC
  • 读取 zImage 镜像文件到 0x80800000
  • 读取设备树文件到 0x83000000
  • 启动 Linux

4.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 就是设置 bootargs 的值为 “console= ttymxc0, 115200 root=/dev/mmcblk1p2 rootwait rw”,bootargs 就是设置了很多的参数的值,这些参数 Linux 内核会使用到,主要用到的参数如下:

4.2.1 console

console 用来设置 linux 终端(或者叫控制台),一般设置串口作为 Linux 终端,I.MX6ULL 的串口 1 在 linux 下的设备文件就是/dev/ttymxc0,刚刚代码中的 console= ttymxc0, 115200 就是设置串口波特率

4.2.2 root

root 用来设置根文件系统的位置,root=/dev/mmcblk1p2 用于指明根文件系统存放在 mmcblk1 设备的分区 2 中

/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

4.2.3 rootfstype

此选项一般配置 root 一起使用,rootfstype 用于指定根文件系统类型,如果根文件系统为 ext 格式保持默认就行,如果根文件系统是 yaffs、jffs 或 ubifs 的话就需要设置此项

到此 uboot 的修改基本完成,下一节就是启动 Linux 内核了

Linux系统移植:官板 uboot 修改(下)相关推荐

  1. 嵌入式Linux(5):驱动开发网络调试驱动设备的Linux系统移植

    驱动开发之网络调试驱动设备的Linux系统移植 1.Uboot移植到开发板 uboot移植 2.开发板网络通讯 nfs命令 tftp命令 3.Linux移植到开发板 4.BusyBox 构建根文件系统 ...

  2. Linux系统移植:NXP 官板 uboot 移植

    文章目录 Linux系统移植:NXP 官板 uboot 移植 一.获取官板 U-Boot 二.编译下载 U-Boot 源码 三.官方驱动验证 Linux系统移植:NXP 官板 uboot 移植 移植 ...

  3. linux系统移植篇(二)—— Uboot使用介绍

    linux系列目录: linux基础篇(一)--GCC和Makefile编译过程 linux基础篇(二)--静态和动态链接 ARM裸机篇(一)--i.MX6ULL介绍 ARM裸机篇(二)--i.MX6 ...

  4. 基于全志A33开发板linux系统移植学习记录(Boot0)

    基于全志A33开发板linux系统移植学习记录 第一章 Boot0基于ARMGCC的编译与修改 文章目录 基于全志A33开发板linux系统移植学习记录 前言 一.全志A33简介以及上电引导流程 二. ...

  5. STM32MP157 Linux系统移植开发篇4: BootLoader(Uboot)移植

    本文章为<STM32MP157 Linux系统移植开发篇>系列中的一篇,笔者使用的开发平台为华清远见FS-MP1A开发板(STM32MP157开发板).stm32mp157是ARM双核,2 ...

  6. Linux系统移植:原厂 Kernel 移植到开发板

    文章目录 Linux系统移植:原厂 Kernel 移植到开发板 一.获取原厂内核并编译 二.内核启动测试 三.添加自己板子文件 3.1 板子配置文件 3.2 板子设备树 3.3 编译 四.重要配置修改 ...

  7. Linux系统移植:图形化配置 U-Boot

    文章目录 Linux系统移植:图形化配置 U-Boot 一.打开图形化配置 二.图形化配置操作 三.编译配置结果 Linux系统移植:图形化配置 U-Boot 较新的 uboot 支持图形化配置,本小 ...

  8. zynq linux环境移植,ZYNQ 7030 Linux 系统移植

    ZYNQ 7030 Linux系统移植 手上有一块 ZYNQ-7030的演示板,是仿照Xilinx Zedboard设计的,但是与Zedboard又有所不同,因此花时间移植一下Linux系统.记录下这 ...

  9. 嵌入式Linux系统移植的四大步骤

    最近在学习系统移植的相关知识,在学习和调试过程中,发现了很多问题,也解决了很多问题,但总是对于我们的开发结果有一种莫名其妙的感觉,纠其原因,主要对于我们的开发环境没有一个深刻的认识,有时候几个简单的命 ...

最新文章

  1. 豪赌 ARM 梦碎:63 岁孙正义的「花甲历险记」
  2. ubuntu软件安装(个人PC)
  3. shop++商品搜索出现乱码的解决方法
  4. 【Java源码分析】Android-LruCache源码分析
  5. 利用反射动态调用类成员C#
  6. 刚从阿里面试回来已拿到offer想和大家分享一下(阿里面试经验)
  7. 第十届蓝桥杯java B组—试题F 特别数的和
  8. python中协程与函数的区别_深入浅析python 协程与go协程的区别
  9. oracle遇null赋默认值,使用hibernate annotation 为非空列加上默认值
  10. 【机器学习】漫谈特征缩放
  11. linux gradle解压后, 执行gradle error13: Permission denied
  12. ACM/ICPC 之 四道MST-Prim解法(POJ1258-POJ1751-POJ2349-POJ3026)
  13. python Chrome + selenium自动化测试与python爬虫获取网页数据
  14. 计算机网络四个阶段的发展特点,计算机网络的发展分哪四个阶段,特点?
  15. 05 - @property 后面所加的关键词
  16. 基于JAVA+SpringBoot+Vue+Mybatis+MYSQL的图书馆管理系统
  17. Python学习之==接口开发
  18. java集合框架小结
  19. linux维文字体如何下载,uyghurfont
  20. Linux 安装 RMVB,rm,ape文件 解码器

热门文章

  1. gcc 4.9.4 编译
  2. antdv 日期选择框date-picker中英文混显问题解决
  3. MySQL query rewrite插件简单测试
  4. 如何学好Java,掌握三大点
  5. shell数组和变量的应用
  6. C#——String.IndexOf方法与Array.IndexOf方法的异同
  7. matlab数字时钟作业,Matlab动态时钟范例.docx
  8. 达梦数据库关键字屏蔽
  9. Luogu 3645 [APIO 2015] 雅加达的摩天楼
  10. python 字符串string 开头r b u f 含义 str bytes 转换 format