今日主要内容
1.windows主机和开发环境文件整理
正点原子的源码分为配置好的和学习用的路径在电脑中的位置分别如下
Q:\ZDYZLinux\01、例程源码\01、例程源码\03、正点原子Uboot和Linux出厂源码,和Q:\ZDYZLinux\01、例程源码\01、例程源码\10、开发板教程对应的uboot和linux源码
在windows主机中我在如下位置分别进行文件的存放

windows主机主要任务有结合Claude code进行代码的编写,如果后续使用vscode在SSH中对Linux驱动文件进行远程控制的话,这个可能就不需要了,目前先把开发环境搭建起来。
/home/eh/linux,这是在Linux主机中文件的位置。
接下来先将两个主机中的文件进行解压,这里补充一下Linux中文件解压缩命令
| 格式 | 解压命令 |
|---|---|
.tar | tar -xvf 文件名.tar |
.tar.gz / .tgz | tar -zxvf 文件名.tar.gz |
.tar.bz2 | tar -jxvf 文件名.tar.bz2 |
.tar.xz | tar -Jxvf 文件名.tar.xz |
.gz | gunzip 文件名.gz |
.bz2 | bunzip2 文件名.bz2 |
.zip | unzip 文件名.zip |
.rar | unrar x 文件名.rar |
.7z | 7z x 文件名.7z |
| 参数 | 含义 |
|---|---|
-x | 解压(extract) |
-c | 压缩(create) |
-v | 显示过程(verbose) |
-f | 指定文件名(必须放最后) |
-z | 处理 gzip 格式 |
-j | 处理 bzip2 格式 |
-J | 处理 xz 格式 |
-C | 指定解压目录 |
执行tar -jxvf来解压文件
记下来需要使用filezilla实现虚拟机和主机文件互传,vscode本地工程搭建,Linux系统上内核文件编译
先做第一件事:filezilla实现文件互传
ens33 Link encap:以太网 硬件地址 00:0c:29:8e:05:29
inet 地址:192.168.10.100 广播:192.168.10.255 掩码:255.255.255.0
ens38 Link encap:以太网 硬件地址 00:0c:29:8e:05:33
inet 地址:192.168.78.128 广播:192.168.78.255 掩码:255.255.255.0
其中192.168.10.100 这个IP地址用来与开发板连接,192.168.78.128 这个IP地址用来和windows主机连接从而实现文件传输。

上述图片即为windows主机与虚拟机进行文件传输的界面设置
接下来实现第二个目标:本地搭建vscode工程包括uboot和Linux,并可以使用VS中的Claude code进行代码帮助,主要参考文章:【正点原子】I.MX6U嵌入式Linux驱动开发指南V1.71,小插曲,PDF阅读器不能用了,我需要先安装一个PDF阅读器
接下来创建本地vscode开发环境,并创建一个my_driver文件夹用来存放后续的驱动文件

接下来实现交叉编译
实现两个事情,一个将交叉编译器复制到/usr/local/arm目录下并解压,另一件事情,修改/etc/profile文件导出环境变量:usr目录作用存放大部分用户空间程序、库文件、头文件、文档和共享资源。系统中大量应用程序和共享资源所在的位置,Unix System Resources或者User System Resources

这里解释一下导出各种环境变量的作用
环境变量本质上是一组键=值的配置,告诉当前 shell 以及它启动出来的子进程,应该在什么环境下运行。
PATH=/usr/bin:/bin:/opt/gcc-arm/bin
HOME=/home/erhu
LANG=zh_CN.UTF-8
比如:export PATH=/opt/gcc-arm/bin:$PATH
作用:
- 当你输入
arm-linux-gnueabihf-gcc时 - shell 会去
PATH里的目录依次查找 - 找到
/opt/gcc-arm/bin/arm-linux-gnueabihf-gcc就执行
所以安装交叉编译器后,最常做的就是把工具链的 bin/ 加到 PATH 中
环境变量的主要作用有:告诉系统“命令去哪里找”、告诉构建系统“用哪个工具链”——CROSS_COMPILE、ARCH、告诉程序“库和头文件在哪”——LD_LIBRARY_PATH、PKG_CONFIG_PATH 等、
修改环境变量的方法:临时 / 永久 / 当前用户 / 全局
临时修改环境变量:命令行临时设置,仅当前 shell 有效,当前 shell 启动的子进程可见,对当前终端会话有效
只对某一条命令生效:PATH=/opt/gcc-arm/bin:$PATH make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf-,只影响这一次命令
写入用户自己的 ~/.bashrc:export PATH=/opt/gcc-arm/bin:$PATH
export ARCH=arm
export CROSS_COMPILE=arm-linux-gnueabihf-
只对当前用户生效、一般对交互式 bash shell 有效、新开终端后自动生效
写入 ~/.profile 或 ~/.bash_profile:用户登录时生效、~/.bash_profile` 比 `~/.profile` 更偏“登录时初始化”
写入 /etc/profile:export PATH=/opt/gcc-arm/bin:$PATH,系统全局
– 对所有用户的登录 shell 生效
– 需要 root 权限
在安装完交叉编译器之后就可以编译一下内核了:注意编译驱动模块是一定要先编译内核的,原因如下:是因为模块编译需要:
与目标内核完全一致的编译环境
内核配置结果
内核头文件和自动生成头文件
Kbuild 构建系统
符号版本信息(Module.symvers)
是你让内核在帮你编译一个模块,内核模块是“依附于某个特定内核”的二进制扩展,不是独立程序;所以它必须基于该内核已经准备好的构建环境来编译。
接下来就是编译内核模块,正点原子推荐了这样一个脚本

该脚本的作用就是:先清空、启动默认配置、在启动图形配置、再进行编译
这里补充一下各种config之间的关系:defconfig 文件在内核源码的arch/$(ARCH)/configs 目录下,是Linux 系统默认的配置文件比如说瑞芯微平台Linux 源码默认的配置文件为:kernel/arch/arm64/configs/rockchip_linux_defconfig。
.config 文件位于Linux 内核源码的顶层目录下,编译Linux 内核时会使用.config 文件里面的
配置来编译内核镜像。
如果.config 文件存在,make menuconfig 界面的默认配置也就是当前.config 文件的配置,
如果修改了图形化配置界面的设置并保存,那么.config 文件会被更新
如果.config 文件不存在,使用命令“make XXX_defconfig”用默认配置文件生成.config 文件。
即该命令会根据arch/$(ARCH)/configs 目录下的XXX_defconfig 自动生成.config。
编译完成之后会生成一个系统镜像文件:arch/arm/boot这个目录下生成一个叫做 zImage的文件, zImage就是我们要用的 Linux镜像文件。另外也会有很多设备树文件,至此内核的交叉编译就完成了。

接下来要做的是使用uboot动态加载内核和根文件系统
2.uboot可以和主机连同,并加载内核和根文件系统
在加载内核和根文件系统之前,需要先了解一下uboot的编译、烧写、以及源码工程搭建、相关文章可以阅读https://erhudiy.cn/2026/04/20/uboot%e7%9a%84%e7%bc%96%e8%af%91%e7%83%a7%e5%86%99%e4%bb%a5%e5%8f%8a%e6%ba%90%e7%a0%81%e5%b7%a5%e7%a8%8b%e5%88%86%e6%9e%90/
在这里使用烧录好的uboot进行内核和根文件系统的加载
我的uboot是烧写到emmc上的

在使用网络挂载根文件系统之前需要在虚拟机上搭建NFS环境
sudo apt-get install nfs-kernel-server安装NFS
sudo vim /etc/export修改该文件,并增加共享文件所在位置

下图为我的开发环境中共享文件所在的位置

知识点补充:export文件的作用、chmod 777有什么作用
/etc/exports 是 NFS 服务器配置“哪些目录共享给哪些客户端” 的文件,NFS 的“共享清单”,哪个目录可以通过 NFS 共享出去、允许哪些客户端访问客户端、是只读还是读写、是否允许客户端 root 拥有 root 权限、是否开启同步写入等选项
chmod 的作用是:修改文件或目录的访问权限,
Linux 把权限分成三组:
- owner:文件拥有者
- group:文件所属组
- others:其他人
0666也是数字权限表示法、通常前面的0是为了强调、这是八进制数。
tftp环境搭建
mkdir -p /home/alientek/linux/tftp sudo chmod 777 /home/alientek/linux/tftp/,创建tftp文件目录
sudo apt-get install tftp-hpa tftpd-hpa安装服务程序

需要修改一下文件
把 /home/eh/linux/tftp 作为 TFTP 的根目录,FTP 服务监听 69 端口,-l以独立守护进程(standalone/listen)方式运行,不依赖 xinetd,自己直接监听 69 端口

让 xinetd 来管理 TFTP 服务,disable = no启用这个服务。
xinetd 是一个超级守护进程,统一管理和调度多个不常驻内存的小服务,而不是让每个服务都自己独立监听端口。很多服务平时用的人很少,不需要一直独立占用内存运行。让 xinetd 统一监听这些服务的端口,有请求来的时候再临时拉起对应的服务。
客户端请求 TFTP
|
v
xinetd 监听 69 端口(一直运行)
|
v
xinetd 检测到请求 -> 临时拉起 tftpd
|
v
tftpd 处理请求(处理完就退出)
uboot要做如下设置
env default -a;saveenv setenv ipaddr 192.168.10.50 setenv ethaddr 00:04:9f:04:d2:35 setenv gatewayip 192.168.10.1 setenv netmask 255.255.255.0 setenv serverip 192.168.10.100 saveenv
setenv bootargs 'console=ttymxc0,115200 root=/dev/nfs nfsroot=192.168.10.100:/home/alientek/linux/nfs/rootfs,proto=tcp rw ip=192.168.10.50:192.168.10.100:192.168.10.1:255.255.255.0::eth0:off' saveenv
bootargs=console=ttymxc0,115200 root=/dev/nfs nfsroot=192.168.10.100:/home/eh/linux/nfs/xuexi/rootfs,proto=tcp rw ip=192.168.10.50:192.168.10.100:192.168.10.1:255.255.255.0::eth0:off
bootcmd=tftp 80800000 zImage;tftp 83000000 imx6ull-alientek-emmc.dtb;bootz 80800000 – 83000000


3.编写驱动模块验证开发环境搭建情况
模块测试
#include <linux/module.h>
#include <linux/kernel.h>
static int __init hello_init(void)
{
printk(KERN_INFO "Hello, world!\n");
return 0;
}
static void __exit hello_exit(void)
{
printk(KERN_INFO "Goodbye, world!\n");
}
module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("ErHu");
MODULE_DESCRIPTION("A simple Hello, World! module");
makefile文件
这个makefile文件在编译好之后会自动将文件复制到my_drivers目录下
export ARCH=arm
export CROSS_COMPILE=arm-linux-gnueabihf-
obj-m +=moudle.o
KDIR := /home/eh/linux/xuexi1/linux-imx-rel_imx_4.1.15_2.1.0_ga_alientek
PWD := $(shell pwd)
NFS_DIR := /home/eh/linux/nfs/xuexi/rootfs/my_driver
# 模块列表,添加新模块时只需在这里追加模块名
# 每个模块对应一个同名的 .c 文件和 obj-m +=xxx.o
MODULE_NAMES := moudle
all: modules install
modules:
$(MAKE) -C $(KDIR) M=$(PWD) modules
install: modules
@if [ ! -d “$(NFS_DIR)” ]; then mkdir -p “$(NFS_DIR)”; fi
@for mod in $(MODULE_NAMES); do \
echo “Installing $$mod…”; \
cp -f $(PWD)/$$mod.ko $(NFS_DIR)/; \
done
@echo “Install done (modules: $(MODULE_NAMES))”
clean:
$(MAKE) -C $(KDIR) M=$(PWD) clean
@rm -f $(NFS_DIR)/*.ko
@echo “Clean done”
加载后的效果如下

如果想要使用modprob命令需要满足下面这个条件

否则modprobe命令会无法使用
至此驱动开发环境的搭建和测试就完成了