본문 바로가기
Xilinx SoC/Zybo Z7 10

[Linux+HDMI](2)부트 이미지(FSBL, U-boot) 만들기, Vitis 2020.2

by 코딩스미스 2022. 7. 3.

1. Vivado에서 만든 XSA파일로 플랫폼 프로젝트를 만든다. platform.spr에서 standalone on ps7_cortexa9_0>>Board Support Package선택 후, Board Support Package>>Modify BSP Settings..을 선택한다.xilffs에 체크를 추구한다.

 

2. 어플리케이션 프로젝트로 Zynq FSBL을 만든다. 아까 만든 플랫폼 어플리케이션을 선택하여 Zynq FSBL 프로젝트를 설정/생성한다. linux-digilent를 사용하기 때문에 FSBL 수정하지 않는다. (설명 1. 참고)

 

3. BOOT.bin을 생성한다.

4. 리눅스를 위한 디바이스 트리를 만든다.

Vivado에서 만든 XSA파일로 디바이스 트리 파일을 Vitis에서 만들 수 있다. Vitis 메뉴바>>Xilinx>>Repositories>>Local Repositories에 device-tree-xlnx-xilinx-v2020.2 를 추가한다.

Vitis 메뉴바>>Xilinx>>Generate Device Tree>>XSA파일 선택 후 생성

 

digilent IP를 사용한 Vivado 하드웨어 설계(base-linux)를 리눅스에서 사용하기 위해 특수한 디바이스트리가 필요하다.

Digilent Github에서 관련 내용을 확인할 수 있다.

https://github.com/Digilent/Petalinux-Zybo-Z7-10/blob/master/Zybo-Z7-10/project-spec/meta-user/recipes-bsp/device-tree/files/system-user.dtsi

 

이 중, flash0은 지우도록 한다.

 

system-user.dtsi를 Vitis에서 생성한 디바이스 트리 폴더에 넣는다.

그리고 system-top.dts의 마지막 줄에 아래 내용을 추가한다.

#include "system-user.dtsi"

dtb(device tree blob)파일을 만드는 방법을 소개한다.

system-top.dts를 system.dts로 변환한다. system-user.dtsi에 리눅스 커널의 헤더 파일을 포함하기 때문에 리눅스 커널 헤더파일 경로를 포함시켜햐 한다.

gcc -I ~/Git_Xilinx/linux-digilent/include -E -nostdinc -undef -D__DTS__ -x assembler-with-cpp -o system.dts system-top.dts

 

system.dts를 dtb 파일로 변환하기 전에, system.dts에서 /include/ "system-conf.dtsi" 를 지운다.

dtc -i ~/Git_Xilinx/linux-digilent/include/ -I dts -O dtb -o system.dtb system.dts

를 실행하면 system.dtb파일을 생성된다.

 

BOOT.bin과 system.dtb를 SD카드에 붙여넣는다.

 

설명 1.

하드웨어 설계 과정에서 HDMI 해상도를 소프트웨어에서 가변하기 위하여 Dynclk을 사용하였다.

dynclk은 Digilent에서 만든 IP로서 Xilinx API를 사용하여 소프트웨어에서 설정을  해야 한다.

리눅스 없이 베어메탈로 zybo보드 HDMI 출력할 수 있다. VDMA, Video Timing Clock, Dynamic Clock을 설정하면 Vitis에서 작성한 어플리케이션으로 HDMI 화면 출력 가능하다. 간단한 화면 정도하면 OS없이 구현하는 가장 간단한 방법일 것이다.

버퍼에 RGB를 직접 그려줘야 하므로, 복잡한 GUI 구성을 위해 라이브러리(QT, Python 등)를 활용하는 것이 좋다.

FSBL에서 Xilinx API를 사용하여 PL에서 구현한 VDMA, VTC, Dynclk를 직접 설정한 후, Linux 커널의 Simple Framebuffer등을 사용하여 화면을 표시할 수 있을 것이다.

PL과 리눅스 커널이 동시에 접근 가능한 RAM 메모리 영역을 확보하여야 하며, 리눅스 어플리케이션에서 해당 메모리를 사용할 수 없도록 제한해야 한다.

Zybo Z7-10의 경우, 1GB의 메모리를 탑재하였다. 프레임버퍼를 0x3F000000에 지정하고, 리눅스 사용 메모리 영역을 0x3F000000보다 작게 제한한다. 리눅스 메모리를 제한하는 방법은 디바이스트리에서 메모리 노드의 메모리 사이즈를 제한하는 장법이 있으나, 나의 경우 이렇게 설정해도 메모리 용량이 줄어들지 않았다. 때문에 리눅스 부팅 스크립트에서 메모리 사이즈를 지정하여 대처하였다.

vdma, vtc, clock wizard를 사용하여 만든 하드웨어에서 simple framebuffer를 써서 HDMI 표시에 성공하였다. 관련 내용은 추후 공유하겠다.이 방법은 linux-xlnx로 진행하였다.

 

linux-digilent를 사용하면 이미 커널에서 dynclk, vdma, vtc를 설정할 수 있도록 소스가 작성되어 있다. 커널을 빌드할 때, Configuration에서 관련 기능을 유효화하면 FSBL에서 설정작업을 따로 하지 않아도 된다. 대신 디바이스 트리에서 PL모듈에 대한 정보를 기술해야 커널에서 이를 설정할 수 있다.