嵌入式学习 day61-62:IMX6ULL驱动——系统移植

一、环境搭建

1. 双网卡配置

嵌入式开发中,Ubuntu 需要同时满足两个需求:

  • 上外网:用 apt-get 下载软件。

  • 和开发板通信:用 tftp 传文件、nfs 挂载根文件系统。

所以需要双网卡:

网卡 模式 用途
ens33 NAT 上外网
ens37 桥接 连接开发板

配置要点:

  • 桥接模式必须桥接到有线网卡,不能选"自动"。

  • Windows 端有线网卡 IP 设为 192.168.1.200,子网掩码 255.255.255.0,网关留空。

  • 关闭 Windows 防火墙。

  • Ubuntu 端 ens37 设为 192.168.1.100。

2. tftp 服务器

tftp 用于从 Ubuntu 下载内核镜像和设备树到开发板。

bash

复制代码
sudo apt-get install tftpd-hpa tftp
sudo mkdir -p /home/linux/tftpboot
sudo chmod 0777 /home/linux/tftpboot
sudo vim /etc/default/tftpd-hpa

配置文件:

text

复制代码
TFTP_USERNAME="tftp"
TFTP_DIRECTORY="/home/linux/tftpboot"
TFTP_ADDRESS=":69"
TFTP_OPTIONS="--secure -l -c"

重启服务:

bash

复制代码
sudo systemctl restart tftpd-hpa

3. nfs 服务器

nfs 用于开发板挂载 Ubuntu 的根文件系统。

bash

复制代码
sudo apt-get install nfs-kernel-server
sudo vim /etc/exports

添加:

text

复制代码
/home/linux/nfs/rootfs *(rw,sync,no_subtree_check,no_root_squash)

重启服务:

bash

复制代码
sudo systemctl restart nfs-kernel-server
sudo showmount -e

4. 交叉工具链

PDF 指定的是 gcc-linaro-4.9.4-2017.01 ,不能用 Ubuntu 自带的 11.4.0(会导致 GLIBC_2.34 not found)。

bash

复制代码
sudo mkdir -p /home/linux/tools/opt
sudo tar -xvf gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf.tar.xz -C /home/linux/tools/opt
vim ~/.bashrc

添加(放在 $PATH 前面):

bash

复制代码
export PATH=/home/linux/tools/opt/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/bin:$PATH

生效并验证:

bash

复制代码
source ~/.bashrc
arm-linux-gnueabihf-gcc -v   # 应显示 4.9.4

二、模式三:U-Boot + tftp + nfs

模式三是开发阶段最常用的方式:

  1. U-Boot 烧写到 SD 卡。

  2. zImage 和 dtb 通过 tftp 下载。

  3. rootfs 通过 nfs 挂载。

U-Boot 配置

bash

复制代码
setenv ipaddr 192.168.1.50
setenv ethaddr 00:04:9f:04:d2:35
setenv gatewayip 192.168.1.1
setenv netmask 255.255.255.0
setenv serverip 192.168.1.100
saveenv

# 分段设置 bootcmd,避免单条命令过长被截断
setenv bootcmd1 'tftp 80800000 zImage'
setenv bootcmd2 'tftp 83000000 imx6ull-alientek-emmc.dtb'
setenv bootcmd3 'bootz 80800000 - 83000000'
setenv bootcmd 'run bootcmd1; run bootcmd2; run bootcmd3'

setenv bootargs 'console=ttymxc0,115200 root=/dev/nfs nfsroot=192.168.1.100:/home/linux/nfs/rootfs rw ip=192.168.1.50:192.168.1.100:192.168.1.1:255.255.255.0::eth0:off'
saveenv

启动成功

text

复制代码
VFS: Mounted root (nfs filesystem) on device 0:14.
Please press Enter to activate this console. 
/ # 

三、四个核心文件

模式三启动依赖四个关键文件,各自作用不同:

1. U-Boot(u-boot.imx)

  • 作用:引导加载程序,负责硬件初始化、加载内核镜像、传递参数。

  • 烧写位置:SD 卡。

  • 启动流程:芯片上电 → bootROM → SPL → U-Boot → 内核。

  • 核心功能:

    • 初始化 DDR、时钟、串口、网卡。

    • 提供命令行交互(=> 提示符)。

    • 通过 tftp 下载内核和设备树。

    • 通过 bootz 启动内核。

2. zImage(zImage)

  • 作用:Linux 内核镜像,操作系统的核心。

  • 加载方式 :通过 tftp 下载到内存地址 80800000。

  • 功能:进程调度、内存管理、虚拟文件系统、网络接口、进程间通信。

  • 启动后 :根据 bootargs 挂载根文件系统。

3. 设备树(imx6ull-alientek-emmc.dtb)

  • 作用:描述硬件平台的资源信息(寄存器地址、中断、时钟、GPIO 等)。

  • 加载方式 :通过 tftp 下载到内存地址 83000000。

  • 来源 :由 .dts 文件编译生成。

  • 意义 :Linux 3.x 以后,硬件信息从内核独立出来,驱动通过设备树获取硬件信息,实现设备与驱动分离。

4. 根文件系统(rootfs.tar.bz2)

  • 作用:Linux 系统运行的基础,提供文件资源管理、用户交互等功能。

  • 挂载方式 :通过 nfs 挂载 Ubuntu 的 /home/linux/nfs/rootfs。

  • 内容 :/bin、/dev、/etc、/lib、/usr 等目录。

  • 制作方式:用 BusyBox 构建(后续章节会讲)。

四个文件的关系

text

复制代码
U-Boot (SD卡)
    ↓ 初始化硬件,提供命令行
    ↓ tftp 下载
zImage (内存 80800000) + 设备树 (内存 83000000)
    ↓ bootz 启动
内核启动
    ↓ 根据 bootargs
根文件系统 (nfs 挂载 /home/linux/nfs/rootfs)
    ↓
进入 Linux 系统

简单理解:

  • U-Boot:搬运工,负责把内核和设备树搬到内存。

  • zImage:操作系统核心,负责管理硬件和进程。

  • 设备树:硬件说明书,告诉内核硬件长什么样。

  • 根文件系统:用户空间,提供命令、库、配置文件。

四、内核编译及裁剪

内核编译是驱动开发的基础,重点搞懂:

1. 编译流程

bash

复制代码
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- distclean
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- imx_alientek_emmc_defconfig
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- menuconfig
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- all -j16

生成:

  • arch/arm/boot/zImage:内核镜像。

  • arch/arm/boot/dts/imx6ull-alientek-emmc.dtb:设备树。

2. 内核源码结构

目录 内容
arch 架构相关代码
drivers 设备驱动(重点)
fs 文件系统
kernel 内核核心
mm 内存管理
net 网络协议栈

3. 设备树

Linux 3.x 以后,硬件信息从内核独立出来,称为设备树:

  • .dts:设备树源码。

  • .dtb:编译后的二进制。

  • 驱动通过设备树获取寄存器地址、中断、GPIO 等信息。

4. 内核里的汇编

内核里 95% 以上是 C 语言,汇编只在:

  • 架构相关启动代码(head.S)。

  • 上下文切换。

  • 原子操作。

写驱动不需要汇编,用 C 语言就行。

五、总结

嵌入式开发环境搭建是驱动开发的基础,核心要点如下:

  1. 双网卡配置:Ubuntu 需要同时满足上外网和与开发板通信两个需求。NAT 模式负责上外网,桥接模式负责与开发板连接,桥接必须桥接到有线网卡。

  2. tftp 服务器 :用于开发板从 Ubuntu 下载内核镜像和设备树文件,管理目录为 /home/linux/tftpboot。

  3. nfs 服务器 :用于开发板挂载 Ubuntu 的根文件系统,共享目录为 /home/linux/nfs/rootfs,实现 Ubuntu 与开发板之间的文件实时同步。

  4. 交叉工具链:PDF 指定的是 gcc-linaro-4.9.4,用于在 x86 平台上编译能在 ARM 平台运行的代码,是驱动开发和应用程序编译的基础。

  5. 四个核心文件:

    • U-Boot:引导加载程序,负责硬件初始化和加载内核。

    • zImage:Linux 内核镜像,操作系统的核心。

    • dtb:设备树,描述硬件资源信息,实现设备与驱动分离。

    • rootfs:根文件系统,提供文件资源和用户交互。

  6. 内核编译及裁剪:内核里 95% 以上是 C 语言,汇编只涉及启动代码、上下文切换、原子操作。写驱动不需要汇编,用 C 语言即可。设备树是重点,驱动通过设备树获取硬件信息。

  7. 模式三:U-Boot 烧写到 SD 卡,zImage 和 dtb 通过 tftp 下载,rootfs 通过 nfs 挂载。这是开发阶段最常用的方式,修改内核或文件系统后无需重新烧录,重启即可加载最新版本。

相关推荐
一隅论数智2 小时前
OWL(Web Ontology Language)介绍与使用举例(二)
大数据·经验分享·笔记·学习·自然语言处理·学习方法·政务
我命由我123452 小时前
Photoshop - Photoshop 使用内容识别填充移除对象
学习·职场和发展·产品运营·求职招聘·职场发展·学习方法·photoshop
梓雨枔2 小时前
JavaScript+快速学习,简单好用~
javascript·学习
老王爱玩车3 小时前
自定义类型:结构体
c语言·开发语言·学习
JWASX4 小时前
Java 转 go 学习 - GRPC(1)
学习·golang
鬼手点金4 小时前
opencode-全能开发者配置
java·linux·服务器·前端·javascript·学习·前向传播
代码山河5 小时前
Java学习路线图:2026年最新版,从入门到架构师
java·学习·架构·教程·面向对象·项目
sunoo-2295 小时前
【嵌入式Linux驱动学习】Day1-Day2 全流程梳理:环境搭建→U-Boot→内核→根文件系统→驱动基础
linux·运维·驱动开发·笔记·学习·阿里云·恩智浦
我命由我123455 小时前
Photoshop - Photoshop 使用简单的选择工具
学习·职场和发展·产品运营·求职招聘·职场发展·学习方法·photoshop