在制作Linux系统时,需要准备如下文件:
其中前三个文件由vits导出,而设备树文件zynqmp-mzux.dts由米联客提供。
vits导出步骤如下:将准备好的.xsa硬件文件导入到vits中,编译完成后即可在下图路径中找到相应文件。

这里需要将system_wrapper.bit和fsbl.elf两个文件改为system.bit,zynqmp_fsbl.elf文件,否则编译内核的脚本会无法识别。
在准备完所需要的文件后,我们需要在已经配置好的开发环境中制作kernel。具体开发环境部署详见https://www.limfx.pro/ReadArticle/4409/ps-duan-kai-fa-huan-jing-bu-shu 。这里不做赘述。
将vits导出的三个文件(system.bit,zynqmp_fsbl.elf,pmufw.elf)拷贝进./uisrc-labxlnx/boards/mzux/ubuntu/output/target;将设备树文件zynqmp-mzux.dts分别拷贝进./uisrc-lab-xlnx/sources/uboot/arch/arm/dts和./uisrc-lab-xlnx/sources/kernel/arch/arm64/boot/dts/Xilinx。
之后在./uisrc-lab-xlnx中打开的终端,一次运行以下指令:
source scripts/mzuxcfg.sh //加载工程配置和环境变量
make_uboot.sh //制作 U-Boot 引导程序
make_kernel.sh //编译 Linux 内核
create_image.sh //把前面生成的启动文件、内核、设备树等内容打包成系统镜像
在制作完系统镜像后,插入SD卡。
make_parted.sh //格式化并分区 SD 卡
deploy_image.sh //把前面制作好的系统内容,真正拷贝到 SD 卡里
这样,就制作好了一个Linux系统,将SD卡插入到FPGA板卡上,上电启动即可。
这里以例程hello world进行了字符设备驱动的学习。一般进行开发时,需要准备以下三个文件:
对于字符设备的驱动,大都围绕着四个函数:open,read,write和release。
//驱动文件描述集合
static struct file_operations drive_fops = {
.owner = THIS_MODULE,
.open = KernelPrint_open,
.read = KernelPrint_read,
.write = KernelPrint_write,
.release = KernelPrint_release,
};
同时,在驱动中,必须有init函数和exit函数。这两个函数就相当于应用程序中的main函数,在驱动装载时执行init函数,驱动卸载时执行exit函数。一般会声明装载和卸载接口,然后再去编写装载入口函数和卸载入口函数。
//申明装载入口函数和卸载入口函数
module_init(KernelPrint_init);
module_exit(KernelPrint_exit);
在init函数中,一般有以下几个步骤:注册字符设备register_chrdev、创建设备类class_create和创建设备节点device_create。然后在exit函数中,对应的也是依次删除设备device_destroy、删除类class_destroy、注销主设备号unregister_chrdev。
在应用程序部分就是通过 open、read、write、close 调用到驱动内部对应的函数,从而实现具体功能的实现。
makefile文件就是自动编译脚本,只需一个make指令就可以进行编译,最终通过编译可以得到KernelPrint.ko和KernelPrintApp可执行文件。具体内容如下:
KERNEL_DIR = /home/uisrc/uisrc-lab-xlnx/sources/kernel #Linux 内核源码目录位置
export ARCH=arm64 #编译给 ARM64 平台使用,这里是进行了交叉编译
export CROSS_COMPILE=aarch64-linux-gnu- #使用 ARM64 的交叉编译工具链
#当前路径
CURRENT_DIR = $(shell pwd)
MODULE = KernelPrint #驱动模块
APP = KernelPrintApp #驱动模块
all :
#进入并调用内核源码目录中Makefile的规则, 将当前的目录中的源码编译成模块
make -C $(KERNEL_DIR) M=$(CURRENT_DIR) modules
rm -rf *.symvers *.order *.o *.mod.o *.mod.c
ifneq ($(APP), )
$(CROSS_COMPILE)gcc $(APP).c -o $(APP)
endif
clean :
make -C $(KERNEL_DIR) M=$(CURRENT_DIR) clean
rm $(APP)
#指定编译哪个文件
obj-m += $(MODULE).o
在准备好了驱动、应用以及makefile文件后,可以将其拷贝到已经配置好的开发环境中(装有Ubuntu系统的虚拟机),然后输入make指令进行编译。得到KernelPrint.ko和KernelPrintApp可执行文件后,可以将其拷贝到windows电脑上,以便后续串口或者ssh将该文件传输到板卡上。
这里我选择使用putty进行传输。
putty并不支持rz和sz命令,需要手动去添加。具体可参考https://blog.csdn.net/TragueZw/article/details/127727882
![]()
然后可以通过串口,去输入一些指令,就类似终端一样。
ls #查看文件是否传输成功
su #进入root模式
insmod KernelPrint.ko #安装驱动
lsmod #查看当前安装的驱动
ls /dev #找到对应的设备
chmod 777 KernelPrintApp #改变 “KernelPrintApp”的权限。这里的777分别代表owner/group/others的权限,7=4(r)+2)(w)+1(x),也就是说owner/group/others三者的权限都是可读可写可执行。
./KernelPrintApp /dev/KernelPrint_0 r #测试read
./KernelPrintApp /dev/KernelPrint_0 w "Just do it!" #测试write
dmesg | tail #查看是否成功写入
本文章使用limfx的vscode插件快速发布