
本文整理了嵌入式Linux驱动学习前两日的完整内容从最基础的虚拟机双网卡环境搭建到TFTP/NFS服务配置、交叉编译工具链再到U-Boot编译烧录、内核裁剪、BusyBox根文件系统构建最后梳理驱动核心基础知识点。全程结合实操步骤与核心概念既能跟着步骤复现环境也能快速回顾核心理论适合嵌入式入门学习者参考。文章目录前言一、基础环境搭建嵌入式开发的“基建”部分1.1 双网卡网络配置兼顾上网与开发板通信1.2 apt-get软件源配置1.3 minicom串口终端配置1.4 TFTP服务器配置1.5 NFS服务器配置1.6 交叉编译工具链配置二、开发启动方案SD卡U-Boot TFTP内核 NFS根文件系统2.1 整体流程2.2 U-Boot环境变量配置三、U-Boot 深入理解与实操3.1 U-Boot核心定位3.2 核心功能3.3 U-Boot启动流程两级架构3.4 U-Boot编译实操3.5 常用命令分类3.6 核心环境变量详解四、Linux内核编译与裁剪4.1 内核概述4.2 编译步骤4.3 编译产物与部署五、BusyBox 构建根文件系统5.1 根文件系统的作用5.2 BusyBox方案特点5.3 构建步骤5.4 功能验证六、Linux驱动基础核心知识点6.1 驱动本质与三大分类6.2 内核模块驱动的载体6.3 字符设备驱动核心框架6.4 bus-device-driver驱动模型6.5 设备树Device Tree6.6 中断处理机制6.7 驱动核心设计思想总结一、基础环境搭建嵌入式开发的“基建”部分环境搭建是嵌入式开发的第一步核心目标是让Ubuntu虚拟机同时具备「访问公网下载软件」和「与开发板通信提供服务」的能力同时配齐开发所需的各类工具。1.1 双网卡网络配置兼顾上网与开发板通信为什么需要双网卡嵌入式开发中Ubuntu需要一个网卡直连开发板提供TFTP文件传输、NFS目录共享服务同时还需要另一个网卡访问公网用于下载软件、更新源码。单网卡无法同时满足两个场景因此采用双网卡方案。两种虚拟机网络模式对比模式原理优势局限性适用场景桥接模式Ubuntu作为独立主机存在拥有真实局域网IP可作为服务器被其他设备访问网络独立拨号网络下可能无法获取公网IP与开发板通信、提供服务NAT模式Windows为主机虚拟网卡Ubuntu共享Windows的网络配置简单Windows能上网Ubuntu就能上网虚拟IP无法作为服务器被外部访问Ubuntu访问公网双网卡组网方案网卡1NAT模式负责Ubuntu访问公网网段默认192.168.78.0网卡2桥接模式桥接到电脑有线网卡负责与开发板直连通信静态IP设为192.168.1.100详细配置步骤虚拟机添加双网卡VMware中添加两个网络适配器分别设置为NAT模式、桥接模式桥接到物理有线网卡。Ubuntu内配置IP地址先通过ifconfig查看两个网卡名称如ens33为NAT网卡ens36为桥接网卡编辑网络配置文件sudo vim /etc/network/interfaces配置NAT网卡自动获取IP桥接网卡设置静态IPauto ens33 iface ens33 inet dhcp auto ens36 iface ens36 inet static address 192.168.1.100 netmask 255.255.255.0修复默认路由关键坑点默认路由必须指向NAT网卡才能正常上网桥接网卡仅负责192.168.1.0网段通信sudo route delete default sudo route add default gw 192.168.78.2 ens33路由配置开机自启创建systemd服务实现开机自动配置路由避免每次重启重复操作sudo vim /etc/systemd/system/custom-route.service写入服务配置[Unit] DescriptionCustom Route Configuration Afternetwork.target [Service] Typeoneshot ExecStart/sbin/route delete default ExecStart/sbin/route add default gw 192.168.78.2 ens33 RemainAfterExityes [Install] WantedBymulti-user.target启用服务sudo systemctl daemon-reload sudo systemctl enable custom-route.service sudo systemctl start custom-route.service双网卡转发可选开发板上网如果需要开发板通过Ubuntu访问公网开启IP转发并配置MASQUERADEsudo echo 1 /proc/sys/net/ipv4/ip_forward sudo iptables -t nat -A POSTROUTING -o ens33 -j MASQUERADE同样可以写入上述开机自启服务实现重启生效。验证测试# 测试公网连通性 ping www.baidu.com # 测试开发板连通性 ping 192.168.1.501.2 apt-get软件源配置apt-get是Ubuntu的软件包管理工具能自动解决软件依赖配置国内源可大幅提升下载速度。将软件源替换为阿里云镜像源更新软件源sudo apt-get autoclean sudo apt-get update sudo apt-get install -f常用命令安装软件sudo apt-get install 软件名卸载软件sudo apt-get remove 软件名1.3 minicom串口终端配置嵌入式开发中通过串口与开发板交互、查看启动日志、输入命令minicom是Ubuntu下常用的串口终端工具。安装sudo apt-get install minicom首次配置sudo minicom -s选择Serial port setup设置串口设备、波特率115200、8N1。常用操作启动sudo minicom退出Ctrl A再按Q选择Yes退出1.4 TFTP服务器配置TFTP是嵌入式开发中最常用的网络文件传输工具开发板可以直接通过网络从Ubuntu下载内核、设备树等文件。安装服务端与客户端sudo apt-get install tftpd-hpa tftp编辑配置文件指定共享目录sudo vim /etc/default/tftpd-hpa设置TFTP_DIRECTORY为共享目录路径如/home/linux/tftpboot。创建共享目录并设置权限mkdir /home/linux/tftpboot chmod 0777 /home/linux/tftpboot重启服务sudo service tftpd-hpa restart功能测试分别测试上传、下载功能确认服务正常。1.5 NFS服务器配置NFS是网络文件共享协议将Ubuntu的目录共享给开发板挂载修改代码后编译完成直接放到共享目录开发板就能立即运行无需反复烧录大幅提升开发效率。安装NFS服务sudo apt-get install nfs-kernel-server编辑配置文件/etc/exports添加共享目录配置/home/linux/nfs/rootfs * rw sync no_subtree_check no_root_squash*允许所有客户端访问rw读写权限no_root_squash客户端root用户拥有服务端root权限创建共享目录并设置权限sudo mkdir -p /home/linux/nfs/rootfs sudo chmod 0777 /home/linux/nfs/rootfs重启服务sudo service nfs-kernel-server restart挂载测试# 查看可挂载目录 sudo showmount -e # 本地挂载测试 sudo mount -t nfs -o nolock,rw 192.168.1.100:/home/linux/nfs/rootfs /mnt1.6 交叉编译工具链配置什么是交叉编译在x86架构的Ubuntu上编译出能在ARM架构开发板上运行的程序这个过程叫交叉编译对应的工具就是交叉编译工具链。配置步骤解压工具链到指定目录如/home/linux/tools/opt/添加环境变量到~/.bashrcexport PATH$PATH:/home/linux/tools/opt/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/bin重启终端或重新加载配置验证安装arm-linux-gnueabihf-gcc -v输出版本号即为配置成功其中hf表示支持硬件浮点指令。二、开发启动方案SD卡U-Boot TFTP内核 NFS根文件系统这是嵌入式开发阶段的标准启动方案优势在于修改内核、驱动、应用后无需烧录到开发板存储直接在Ubuntu更新文件开发板重启就能加载最新版本调试效率极高。2.1 整体流程开发板从SD卡启动U-Boot完成硬件初始化U-Boot通过TFTP从Ubuntu下载内核镜像zImage和设备树.dtb到内存U-Boot向内核传递启动参数跳转执行内核内核启动后通过NFS挂载Ubuntu上的根文件系统进入Linux命令行完成系统启动2.2 U-Boot环境变量配置在U-Boot串口终端依次配置以下参数saveenv保存到SD卡持久化# 网络基础参数 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 自动启动命令倒计时结束自动下载内核设备树并启动 setenv bootcmd tftp 80800000 zImage;tftp 83000000 imx6ull-alientek-emmc.dtb;bootz 80800000 - 83000000 saveenv 内核启动参数指定控制台、根文件系统为NFS、IP配置 setenv bootargs consolettymxc0,115200 root/dev/nfs nfsroot192.168.1.100:/home/linux/nfs/rootfs,prototcp,nfsvers3 rw ip192.168.1.50:192.168.1.100:192.168.1.1:255.255.255.0::eth0:off saveenv配置完成后输入boot或重启开发板即可自动完成从TFTP下载、NFS挂载的完整启动流程。三、U-Boot 深入理解与实操3.1 U-Boot核心定位U-BootUniversal Boot Loader是嵌入式领域最主流的开源引导加载程序是开发板上电后第一个运行的程序地位等同于PC的「BIOS启动引导器」。本质裸机程序直接运行在硬件之上不依赖操作系统核心使命硬件初始化、加载并启动Linux内核、提供底层调试工具3.2 核心功能硬件底层初始化初始化CPU时钟、DDR内存、串口、以太网、SD/EMMC控制器等核心外设引导Linux内核读取内核镜像与设备树到内存传递启动参数跳转执行内核环境变量管理支持配置参数持久化存储掉电不丢失调试工具集提供内存读写、网络调试、存储烧录等丰富的串口命令多启动介质支持支持SD卡、EMMC、网络、USB等多种启动方式3.3 U-Boot启动流程两级架构BL1ROM Boot芯片出厂固化在ROM中上电自动执行加载第二阶段程序到片内RAMSPLBL2U-Boot精简版负责初始化DDR内存再加载完整U-Boot到DDR运行U-Boot正文完整功能版本完成外设初始化、倒计时等待、命令行交互、引导内核3.4 U-Boot编译实操安装依赖库sudo apt-get install libncurses5-dev解压源码并进入目录执行编译# 清理旧编译 make ARCHarm CROSS_COMPILEarm-linux-gnueabihf- distclean # 加载板级配置 make ARCHarm CROSS_COMPILEarm-linux-gnueabihf- mx6ull_alientek_emmc_defconfig # 编译 make ARCHarm CROSS_COMPILEarm-linux-gnueabihf- -j16编译产物顶层目录生成u-boot.imx镜像文件可烧录到SD卡或EMMC。3.5 常用命令分类类别常用命令功能环境变量printenv/setenv/saveenv查看、修改、保存环境变量内存操作md/mw/cp/cmp内存读取、写入、拷贝、比较网络操作ping/tftp/nfs网络连通测试、TFTP下载、NFS加载MMC操作mmc dev/mmc read/mmc write/mmc part切换设备、读写、查看分区启动命令bootz/bootm/boot/go启动zImage/uImage、执行bootcmd、跳转地址3.6 核心环境变量详解bootcmd自动启动命令U-Boot倒计时结束后自动执行定义了内核加载与启动的完整流程bootargs传递给Linux内核的启动参数包含控制台配置、根文件系统类型与路径、网络配置等是内核启动的关键参数四、Linux内核编译与裁剪4.1 内核概述Linux内核是操作系统的核心负责进程调度、内存管理、硬件驱动、文件系统、网络协议等核心功能。嵌入式开发中需要根据硬件平台裁剪配置内核生成适配的镜像文件。4.2 编译步骤安装依赖工具sudo apt-get install lzop解压内核源码并进入目录# 清理旧编译 make ARCHarm CROSS_COMPILEarm-linux-gnueabihf- distclean # 加载板级默认配置 make ARCHarm CROSS_COMPILEarm-linux-gnueabihf- imx_alientek_emmc_defconfig # 图形化配置可选裁剪功能 make ARCHarm CROSS_COMPILEarm-linux-gnueabihf- menuconfig # 全量编译 make ARCHarm CROSS_COMPILEarm-linux-gnueabihf- all -j164.3 编译产物与部署编译完成后生成两个关键文件内核镜像arch/arm/boot/zImage设备树文件arch/arm/boot/dts/imx6ull-alientek-emmc.dtb将两个文件拷贝到TFTP共享目录开发板启动时就会自动下载最新版本cp arch/arm/boot/zImage ~/tftpboot/ cp arch/arm/boot/dts/imx6ull-alientek-emmc.dtb ~/tftpboot/五、BusyBox 构建根文件系统5.1 根文件系统的作用根文件系统是Linux内核启动后挂载的第一个文件系统包含系统命令、库文件、配置文件、设备节点等是用户空间运行的基础。嵌入式常用BusyBox构建轻量根文件系统体积小、易定制。5.2 BusyBox方案特点BusyBox被称为“嵌入式Linux的瑞士军刀”将大量Linux命令和工具整合到一个二进制文件中支持静态编译占用空间极小非常适合嵌入式场景。5.3 构建步骤解压BusyBox源码修改Makefile指定交叉编译器CROSS_COMPILE ? arm-linux-gnueabihf- ARCH ? arm配置BusyBoxmake defconfig make menuconfig关键配置开启Build static binary静态编译避免依赖动态库。编译并安装到指定目录make make install CONFIG_PREFIX/home/linux/nfs/rootfs拷贝依赖库文件将交叉工具链中的libc库、动态库拷贝到根文件系统的lib和usr/lib目录确保程序能正常运行。创建必要目录mkdir dev proc mnt sys tmp root lib/modules完善系统配置文件/etc/init.d/rcS系统启动脚本配置环境变量、挂载文件系统、启动mdev/etc/fstab文件系统挂载表定义proc、tmpfs、sysfs等特殊文件系统/etc/inittabinit进程配置定义系统启动、重启、关机对应的动作5.4 功能验证将构建好的根文件系统放到NFS共享目录开发板通过NFS挂载启动能正常进入命令行、运行程序即为构建成功。六、Linux驱动基础核心知识点6.1 驱动本质与三大分类驱动是运行在内核态的代码是硬件与用户程序之间的桥梁向下管理硬件向上提供标准操作接口。字符设备按字节流顺序访问如串口、LED、按键是最基础的驱动类型块设备以数据块为单位随机访问如SD卡、硬盘用于存储场景网络设备面向数据包收发不对应普通文件节点如网卡6.2 内核模块驱动的载体内核模块是可以动态加载卸载的代码段无需重新编译内核是Linux驱动的标准开发形式。四大要素module_init入口、module_exit出口、MODULE_LICENSE许可证、辅助描述信息操作命令insmod加载、rmmod卸载、lsmod查看已加载模块进阶特性模块参数动态传参、EXPORT_SYMBOL符号导出跨模块调用6.3 字符设备驱动核心框架两个核心结构体struct cdev内核抽象字符设备的结构体struct file_operations操作函数表封装open、read、write、ioctl等接口设备号主设备号标识驱动类型 次设备号标识不同设备实例支持静态申请和动态分配核心流程分配设备号 → 初始化cdev并绑定操作函数 → 注册到内核空间交互通过copy_from_user和copy_to_user完成内核与用户空间的数据拷贝6.4 bus-device-driver驱动模型核心思想是硬件描述与驱动逻辑分离通过总线统一管理匹配实现一个驱动适配多个同类硬件。总线bus管理者负责设备与驱动的匹配绑定设备device描述硬件资源信息驱动driver实现通用驱动逻辑Platform平台总线专为SoC片上外设设计的虚拟总线是嵌入式最常用的驱动框架6.5 设备树Device Tree将硬件配置信息从驱动代码中剥离用独立的.dts树形文件描述硬件驱动只实现通用逻辑通过解析设备树获取硬件参数实现驱动通用化、跨板适配。核心属性compatible匹配标识、reg寄存器地址、interrupts中断配置、status设备状态驱动通过of_系列函数解析设备树节点属性6.6 中断处理机制采用顶半部底半部分层设计平衡中断响应速度与处理耗时顶半部中断触发后立即执行只做紧急操作运行在中断上下文不可睡眠底半部延后执行耗时逻辑主流实现有tasklet软中断不可睡眠和工作队列内核线程可睡眠6.7 驱动核心设计思想分层思想通用逻辑向上抽取复用硬件差异向下适配分离思想硬件信息与驱动代码分离一套驱动适配多硬件面向对象思想用结构体封装属性与方法模拟面向对象编程以上就是嵌入式驱动前两日的全部学习内容从底层环境搭建到系统启动全流程再到驱动核心理论形成了完整的入门知识体系。后续会继续深入字符设备驱动、platform总线、设备树驱动等内容的学习与实操。