Skip to content

Nạp bitstream FPGA từ Linux trên Zynq

Zynq gồm hai phần: hệ thống xử lý (processing system, PS) chạy Linux và phần logic lập trình được (programmable logic, PL) là FPGA. PS luôn khởi động trước. PL chỉ hoạt động sau khi được nạp bitstream, tức file cấu hình sinh ra từ Vivado. Với kỹ sư tích hợp hệ thống, câu hỏi là nạp ở giai đoạn nào của chuỗi boot, bằng công cụ nào, và làm sao để driver của các IP trong PL chạy được sau khi nạp. Trang này trình bày các thời điểm nạp, các định dạng file, cách nạp từ Linux bằng sysfs, fpgautil và device tree overlay, cách đưa vào image bằng Yocto và PetaLinux, và các lưu ý về partial reconfiguration. Cấu trúc bên trong framework kernel nằm ở trang FPGA Manager framework.

Thời điểm nạp PL

Theo wiki của Xilinx, PL của Zynq UltraScale+ MPSoC được nạp bởi First Stage Boot Loader (FSBL), bởi U-Boot hoặc từ Linux. Wiki Zynq-7000 nêu cùng ba lựa chọn.

Ba thời điểm nạp bitstream vào PL

Ba thời điểm nạp PL trên chuỗi boot của PS.
Thời điểm Cách làm Khi nào chọn
FSBL Đưa bitstream vào BOOT.BIN như một partition, FSBL nạp trước khi chuyển sang U-Boot PL cần hoạt động ngay từ đầu chuỗi boot, trước cả U-Boot. Chi tiết BOOT.BIN xem U-Boot on Zynq
U-Boot Nạp file vào RAM rồi dùng lệnh fpga PL cần sẵn sàng trước khi kernel chạy nhưng không muốn đóng gói vào BOOT.BIN
Linux FPGA Manager Thay đổi thiết kế PL mà không reboot, nạp một phần PL (partial reconfiguration), hoặc bitstream được tải sau

Ví dụ trong wiki Zynq-7000 cho U-Boot:

U-Boot> fatload mmc 0 0x4000000 bitstream.bit
U-Boot> fpga loadb 0 0x4000000 <kích-thước-file-bitstream>

Định dạng file

Bitstream có hai dạng thường gặp: .bit do Vivado sinh ra và .bin do công cụ bootgen chuyển đổi. Theo wiki ZynqMP, từ bản 2018.3 FPGA Manager nạp được cả hai. Các bản trước chỉ nạp được .bin.

Tạo .bin bằng bootgen với file .bif khai báo bit file đi vào PL:

all:
{
    [destination_device = pl] design_1_wrapper.bit
}
bootgen -image Bitstream.bif -arch zynqmp -o ./Bitstream.bin -w

Đối số -arch thay đổi theo họ chip (zynqmp cho UltraScale+ MPSoC, zynq cho Zynq-7000). Wiki ghi nhận file chưa căn theo word (4 byte) làm thời gian cấu hình PL dài hơn.

Nạp từ Linux

Kernel của AMD/Xilinx hiển thị FPGA Manager trong /sys/class/fpga_manager/fpga0/. Theo wiki ZynqMP, các thuộc tính gồm flags (0 là bitstream đầy đủ, 1 là một phần), firmware (tên file bitstream trong đường dẫn firmware, ví dụ /lib/firmware), state và name. Nạp bitstream đầy đủ:

cp design_1_wrapper.bit.bin /lib/firmware/
echo 0 > /sys/class/fpga_manager/fpga0/flags
echo design_1_wrapper.bit.bin > /sys/class/fpga_manager/fpga0/firmware
cat /sys/class/fpga_manager/fpga0/state

Nếu rootfs chỉ đọc, file bitstream phải nằm sẵn trong image, hoặc đặt trong vùng ghi được và khai báo vào đường dẫn firmware, xem Root filesystem cho thiết bị nhúng.

Todo

Thuộc tính flags và firmware thuộc tree kernel của AMD/Xilinx (linux-xlnx) theo wiki. Chưa đối chiếu với kernel mainline, nơi giao diện sysfs của FPGA Manager có thể khác. Cần kiểm tra trên kernel đang dùng của dự án.

fpgautil

fpgautil là tiện ích của Xilinx gói gọn các thao tác trên. Các tùy chọn theo wiki:

Tùy chọn Ý nghĩa
-b <file> File bitstream
-o <file> File device tree overlay (DTBO)
-f Full\|Partial Nạp toàn bộ hoặc một phần
-s, -k Cờ bảo mật (ví dụ AuthDDR, EnUsrKey) và khóa AES cho bitstream mã hóa
-r, -t Đọc lại (readback) cấu hình
-R Gỡ overlay
# nạp bitstream đầy đủ kèm overlay
fpgautil -b top.bin -o can.dtbo
# nạp một phần, không cần overlay
fpgautil -b top.bin -f Partial

Device tree overlay cho IP trong PL

IP trong PL (GPIO, DMA, bộ xử lý tín hiệu) cần node trong device tree để driver kernel nhận ra, nhưng các node này chỉ hợp lệ sau khi PL được nạp đúng thiết kế. Cách xử lý là nạp bitstream cùng một overlay chứa các node của IP: kernel nạp PL trước, sau đó mới thêm node vào cây thiết bị chạy và kích hoạt driver. Trình tự chi tiết trong kernel nằm ở trang FPGA Manager framework.

Ngoài fpgautil -o, có thể nạp overlay qua configfs. Theo wiki ZynqMP: mount configfs, tạo thư mục con trong /configfs/device-tree/overlays/, ghi đường dẫn DTBO vào thuộc tính path. Gỡ bằng rmdir, theo thứ tự ngược với thứ tự nạp:

mkdir -p /configfs && mount -t configfs configfs /configfs
mkdir /configfs/device-tree/overlays/pl
echo -n design_1_wrapper.dtbo > /configfs/device-tree/overlays/pl/path
# gỡ
rmdir /configfs/device-tree/overlays/pl

Hai giới hạn của overlay theo wiki: overlay thêm được node hoặc cập nhật thuộc tính, nhưng không thay thế được node đã có trong cây chạy; và fpgautil -R chỉ gỡ overlay khỏi cây, không xóa logic đã nạp trong PL.

Tích hợp vào image

Các công cụ build đóng gói bitstream và DTBO vào rootfs để nạp lúc chạy:

  • Yocto: theo wiki ZynqMP, thêm fpga-manager vào EXTRA_IMAGE_FEATURES và đặt EXTRA_HDF là đường dẫn tới file XSA. Bitstream và DTBO cơ sở được đặt trong /lib/firmware/base của rootfs.
  • PetaLinux: bật mục FPGA MANAGER trong petalinux-config. Template fpgamanager_dtg đóng gói DTBO và file cấu hình PL vào /lib/firmware/xilinx/:
petalinux-config                  # chọn FPGA MANAGER
petalinux-create -t apps --template fpgamanager_dtg -n <tên-app> --enable --srcuri "<file.xsa>"
petalinux-build

Todo

Các lệnh trên lấy từ wiki của bản phát hành cũ. PetaLinux đang được thay bằng AMD Embedded Development Framework (EDF) và tên công cụ, template có thể khác. Chưa đối chiếu với bản EDF đang dùng.

Partial reconfiguration

Partial reconfiguration (PR, AMD gọi là Dynamic Function eXchange, DFX) cho phép thay một phần PL trong khi phần còn lại vẫn chạy. Nạp bitstream một phần bằng flags bằng 1 hoặc fpgautil -f Partial. Theo wiki, muốn nạp một bitstream khác vào cùng một vùng thì phải gỡ overlay hiện có trước. Phần PS và các vùng PL khác tiếp tục hoạt động, nhưng traffic từ PS tới vùng đang cấu hình phải được chặn bằng bridge, xem trang kernel.

Truy cập PL sau khi nạp

Sau khi PL được nạp và overlay đã tạo node, IP có driver kernel (GPIO, I2C, SPI) xuất hiện như thiết bị thông thường. IP không có driver thường được truy cập qua UIO hoặc mmap từ user space.

Liên quan

Tài liệu tham khảo