zynq 通过linux 加载fpga的bit文件 -fpga_manager
zynq通过linux加载fpga的bit流文件
zynq 我们熟知分为pl和ps两个部分,自然代码也就分为这两部分,对于较大的项目来说,必然也是由不同的人员去开发的,例如逻辑工程师搞定pl,嵌入式工程师搞定ps
这是我们很自然的想到,能否将pl的固件作为一个单独部分由内核去管理呢,这样我就可以根据不同的场景,去加载不通bit流文件
xilinx已经提供了这部分功能接下来将记录如何去做
需要说明的是 ps的部分还是在fsbl中的 这一点是无法更改的,否则内核也肯定起不来啊
我这边构建的是一个很简单的vivado框架,就是一个自己hls写的led的小ip
petalinux将bit文件打包到BOOT.bin时可以看到文件大小,是比较大的
zw@zw-pc:~/swap/explore/hls/led_project/petalinux/led/images/linux$ ls -la
total 517232
drwxrwxr-x 2 zw zw 4096 4月 20 14:11 .
drwxrwxr-x 3 zw zw 4096 4月 17 13:10 ..
-rw-rw-r-- 1 zw zw 4604224 4月 20 14:02 BOOT.BIN
-rw-r--r-- 1 zw zw 3954692 4月 17 14:45 image.ub
-rw-r--r-- 1 zw zw 74806272 4月 17 14:45 rootfs.cpio
-rw-r--r-- 1 zw zw 20917537 4月 17 14:45 rootfs.cpio.bz2
-rw-r--r-- 1 zw zw 23337430 4月 17 14:45 rootfs.cpio.gz
-rw-r--r-- 1 zw zw 23337494 4月 17 14:45 rootfs.cpio.gz.u-boot
首先进到image/linux目录
- 拷贝vivado的bit文件到当前目录
位于vivado工程project_1.runs/impl_1/design_1_wrapper.bit .
#创建Full_Bitstream.bif内容如下
zw@zw-pc:~/swap/explore/hls/led_project/petalinux/led/images/linux$ cat Full_Bitstream.bif
all:
{
design_1_wrapper.bit
}
#执行bootgen
zw@zw-pc:~/swap/explore/hls/led_project/petalinux/led/images/linux$bootgen -image Full_Bitstream.bif -arch zynq -process_bitstream bin
#执行生成BOOT.bin,去掉fpga选项
zw@zw-pc:~/swap/explore/hls/led_project/petalinux/led/images/linux$ petalinux-package --boot --fsbl ./images/linux/zynq_fsbl.elf --u-boot --force
#可以看到生成的bit流文件,以及BOOT.bin大大减小
zw@zw-pc:~/swap/explore/hls/led_project/petalinux/led/images/linux$ ls -la
total 521184
drwxrwxr-x 2 zw zw 4096 4月 20 14:19 .
drwxrwxr-x 3 zw zw 4096 4月 17 13:10 ..
-rw-rw-r-- 1 zw zw 558656 4月 20 14:19 BOOT.BIN
-rw-rw-r-- 1 zw zw 4045676 4月 20 14:13 design_1_wrapper.bit
-rw-rw-r-- 1 zw zw 4045568 4月 20 14:17 design_1_wrapper.bit.bin
-rw-rw-r-- 1 zw zw 31 4月 20 13:15 Full_Bitstream.bif
-rw-r--r-- 1 zw zw 3954692 4月 17 14:45 image.ub
-rw-r--r-- 1 zw zw 74806272 4月 17 14:45 rootfs.cpio
上板子
#将固件放到/lib/firmware下!!一定是这个目录
#执行
root@localhost:~# echo 0 > /sys/class/fpga_manager/fpga0/flags
#执行,就可以了
root@localhost:~# echo design_1_wrapper.bit.bin > /sys/class/fpga_manager/fpga0/firmware
- 实现说明
其实看内核的代码,可以看到
#driver/zynq-fpga.c
#对应的config在Kconfig中都可以很容易找到
#ifdef CONFIG_OF
static const struct of_device_id zynq_fpga_of_match[] = {
{ .compatible = "xlnx,zynq-devcfg-1.0", },
{},
};
MODULE_DEVICE_TABLE(of, zynq_fpga_of_match);
#endif
static struct platform_driver zynq_fpga_driver = {
.probe = zynq_fpga_probe,
.remove = zynq_fpga_remove,
.driver = {
.name = "zynq_fpga_manager",
.of_match_table = of_match_ptr(zynq_fpga_of_match),
},
};
#driver/fpga/fpga-mgr.c
#sysgroup的节点生成 store/show的实现都可以看个大概
static DEVICE_ATTR_RO(name);
static DEVICE_ATTR_RO(state);
static DEVICE_ATTR_WO(firmware);
static DEVICE_ATTR_RW(flags);
static DEVICE_ATTR_RW(key);
static DEVICE_ATTR_RW(iv);
static DEVICE_ATTR_RO(status);
static struct attribute *fpga_mgr_attrs[] = {
&dev_attr_name.attr,
&dev_attr_state.attr,
&dev_attr_firmware.attr,
&dev_attr_flags.attr,
&dev_attr_key.attr,
&dev_attr_iv.attr,
&dev_attr_status.attr,
NULL,
};
ATTRIBUTE_GROUPS(fpga_mgr);
#driver/base/firmware_loader/main.c
#基于firmware框架实现,因此要放到/lib/firmware下
/* direct firmware loading support */
static char fw_path_para[256];
static const char * const fw_path[] = {
fw_path_para,
"/lib/firmware/updates/" UTS_RELEASE,
"/lib/firmware/updates",
"/lib/firmware/" UTS_RELEASE,
"/lib/firmware"
};
附图一张
分类:
zynq开发测试积累
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律