1. 程式人生 > >Xilinx FPGA 嵌入式系統程式引導和啟動的流程分析設計

Xilinx FPGA 嵌入式系統程式引導和啟動的流程分析設計

Xilinx FPGA 嵌入式系統程式引導和啟動的流程

北京華環電子        任曉亮

                            2016年1月15日

在參考文獻1中,有這樣一句話,SystemACE解決方案是通過JTAG將程式下載到debug(對於MicroBlaze也就是,MicroBlaze debug module)。看到這句話,一時沒反應過來。要知道SystemACE解決方案是將用於配置FPGA的bitsteams檔案和程式可執行二進位制檔案融 合生成一個*.ace。在看了genace.tcl這個用於生成ace檔案的指令碼後,終於明白了,剛才提到的那句話。

首先說明一下SystemACE檔案是如何生成的?

1. 通過iMPACT工具將bitstream檔案轉為SVF檔案

該SVF檔案包含了配置FPGA的JTAG指令序列

2.通過XMD將elf可執行檔案轉為SVF檔案

該SVF檔案包含了通過XMD將ELF檔案下載帶記憶體或許片上BRAM的JTAG指令序列

3.通過XMD將資料/二進位制程式碼轉為SVF檔案

4.連結第一步和第二步中生成的SVF檔案

5.通過iMPACT工具利用結合的SVF檔案生成systemACE檔案

整個生成過程一目瞭然了,SystemACE解決替代了這樣一個線上除錯的流程:通過iMPACT將含有bootloop的程式的bitstream檔案通過JTAG下載到FPGA中,這個時候FPGA在空轉,等待執行程式的載入。接下來通過XMD先跟debug和CPU通訊,然後將程式下載到指定的記憶體或者BRAM中,然後執行CPU。

總結,SystemACE配置方案,需要硬體的支援,即SystemACE控制器和CF卡,當然在嵌入式系統中還需要新增Debug模組。優點顯而易見,不用編寫bootload類似的載入程式,也不用關心程式映象的大小,因為CF卡的容量很大,滿足了絕大多數的嵌入式應用的要求。

還有一種情況就是通過PROM/FLASH儲存程式映象和bitstream檔案配置FPGA,並載入程式啟動。具體的流程如下:


圖2 Spartan6的配置和啟動的過程

這裡不關心如何去配置FPGA,而關心的是系統是如何引導的。以在FPGA執行Linux為例作說明。如圖3所示,具體步驟如下:

第一步,CPU從0x0地址(BRAM)執行Loader1 (注意,Loader1放在BRAM中,在配置FPGA過程中就加在進去)

第二步,Loader1讀取SPI Flash中Loader2程式,然後複製到記憶體中。

第三步,Loader1程式跳至在記憶體中執行Loader2

第四步,Loader2讀取SPI Flash中壓縮的核心映象

第五步,Loader2程式解壓縮核心到另一塊記憶體空間

第六步,Loader2程式跳至解壓縮的核心映象

第七步,Linux核心啟動


圖3 Linux引導流程

由上面的流程可知,通過PROM或者Flash進行配置的話,需要Bootload作支援,即需要完成將程式映象從Flash或者PROM中讀取至記憶體上。當然嵌入式系統中需要新增PROM或者Flash控制器。

這節介紹以下如何生成基於zynq晶片的linux核心,使用Digilent公司的linux核心編譯工具。

首先需要做一下準備工作:

1. 在Linux環境中建立交叉編譯環境ARMGNU,具體方法在《基於zynq的交叉編譯平臺》有說明;

2. 下載Digilent Linuxkernel環境,筆者在ubuntu11.04使用git下載,輸入以下指令碼:

git clonehttps://github.com/Digilent/linux-digilent.git

Linux核心編譯

準備工作完成之後,開始核心編譯

1. 進入linux-digilent目錄,進行目標板(ZedBoard)配置:

cd linux-digilent

make ARCH=arm digilent_zed_defconfig

2. 核心配置:

make ARCH=arm menuconfig

製作uramdisk.gz

Modifying the root filesystem

Initrd

To modify an initialramdisk:
1. Extract the initrd image from the gziparchive.

gunzip ramdisk.image.gz

2. Mount the initrdimage.

chmod u+rwx ramdisk.image

mkdir tmp_mnt/

sudo mount -o loopramdisk.image tmp_mnt/

cd tmp_mnt/

3. Make changes in themounted filesystem.
4. Unmount the initrd image and compress theimage.

sudo umount tmp_mnt/

gzip ramdisk.image
To create an initrd from scratch, tools such asBuildroot or Yocto may be used to populate the filesystem (with BusyBox, tools,etc.).
Alternatively, an empty initrd may be createdand then populated with the desired filesystem contents as specified above. Tocreate an empty (8MB) initrd:

dd if=/dev/zeroof=ramdisk.image bs=1024 count=8192

mke2fs -F ramdisk.image -L"ramdisk" -b 1024 -m 0

tune2fs ramdisk.image -i 0

chmod a+rwx ramdisk.image

Initramfs

To modify an initramfs:
1. Extract the contents of the cpio.gz archive.

2. Make changes to thefilesystem.
3. Repack the filesystem into a cpio.gz archive.

sh -c 'cd tmp_mnt/ &&sudo find . | sudo cpio -H newc -o' | gzip -9 > new_initramfs.cpio.gz


To create an initramfs from scratch, tools suchas Buildroot or Yocto may be used to populate the filesystem (with BusyBox,tools, etc.).
Alternatively, initramfs image may be created bypopulating a directory with the desired filesystem contents and packing thesecontents into a cpio.gz archive as mentioned above.

Wrapping the image with a U-Boot header

For Zynq AP SoC only, theramdisk.image.gz needs to be wrapped with a U-Boot header in order for U-Bootto boot with it:

mkimage -A arm -T ramdisk -Cgzip -d ramdisk.image.gz uramdisk.image.gz

mkimage -A microblaze -O linux -T ramdisk -C gzip -d ramdisk.image.gz uramdisk.image.gz

sudoapt-get installuuid-dev

sudo apt-get install openssl
sudo apt-get install libssl-dev
sudo apt-get install libssl0.9.8
sudo apt-get install libgtk2.0-dev

apt-get install device-tree-compiler

搭建好的交叉編譯環境編譯嵌入式Linux所需的檔案,包括u-bootuImage(核心)、uramdisk.image.gz(檔案系統)和devicetree.dtb(裝置樹)。

原料:

編譯

1. U-Boot

~$ mkdir ZYNQ
~$ cd ZYNQ/ 

~/ZYNQ$ mkdir buildxil2014.4 
~/ZYNQ$ cd buildxil2014.4/ 
~/ZYNQ/buildxil2014.4$ git clonehttps://github.com/Xilinx/u-boot-xlnx.git //或者先下載好,直接copy、解壓
cd u-boot-xlnx
在編譯之前,先進行配置,配置檔案在u-boot-xlnx/include/configs下,開啟zynq_common.h可檢視資訊。包括所需要的幾個檔案的名稱等make zynq_zed_config
make 

cp u-boot u-boot.elf如果需要安裝python
sudo apt-get --reinstallinstall python-minimalu-boot-xlnx/include/configs下,檢視zynq_common.hzynq_zed.h(優先),決定了核心等檔案的名稱。本例使用zynq_zed_config
“ethaddr=00:0a:35:00:01:22\0”   \ 

“kernel_image=uImage\0”\ 
“kernel_load_address=0x2080000\0” \ 
“ramdisk_image=uramdisk.image.gz\0”\ 
“ramdisk_load_address=0x4000000\0”  \ 
“devicetree_image=devicetree.dtb\0”\ 
“devicetree_load_address=0x2000000\0”   \ 
“bitstream_image=system.bit.bin\0”  \ 
“boot_image=BOOT.bin\0” \

2. uImage

使用配置檔案:xilinx_zynq_defconfig(arch/arm/configs)

cd ~/ZYNQ/buildxil2014.4
git clone https://github.com/Xilinx/linux-xlnx.git    //
或直接copy下載好的linux-xlnx-xilinx-v2014.4.tar.gz
cd~/ZYNQ/buildxil2014.4/u-boot-xlnx-xilinx-v2014.4/       //
需要先安裝u-boot-tools
cd ~/ZYNQ/buildxil2014.4/linux-xlnx-xilinx-v2014.4 
make ARCH=arm xilinx_zynq_defconfig 
make ARCH=arm UIMAGE_LOADADDR=0x8000 uImage 
cp arch/arm/boot/uImage

3. uramdisk.image.gz檔案系統

這裡不進行編譯了,直接使用官網的:http://www.wiki.xilinx.com/Build+and+Modify+a+Rootfs或:wgethttp://www.wiki.xilinx.com/file/view/arm_ramdisk.image.gz/41943558/arm_ramdisk.image.gz修改根檔案系統cp arm_ramdisk.image.gzramdisk.image.gz
gunzip ramdisk.image.gz 

mkdir file_tmp 
sudo mount ramdisk.image -o loop ./file_tmp/這樣可以在file_tmp目錄中對檔案系統進行修改,修改完成之後umount並重新壓縮即可sudo umount file_tmp/
gzip ramdisk.image 

//新增u-boot頭部
sudo apt-get install u-boot-tools 

mkimage -A arm -T ramdisk -C gzip -d ramdisk.image.gz uramdisk.image.gz如果需要進行修改,可以先將uramdisk.image.gz解壓為uramdisk.image,再掛載到指定目錄

4. devicetree.dtb

建議:建立一個devicetree目錄,將/scripts/dtc/dtc工具copy過來,每次使用時在其下建立工程目錄;將所需要的dts,dtsi檔案copy到其下的工程目錄下;然後對工程目錄開啟終端:../dtc-I dts -O dtb -o devicetree.dtb system.dts即可;

如果只有ARM,沒有使用PL部分:linux-xlnx/arch/arm/boot/dts/下,找到zynq-zed.dts及相關dtsi檔案,copy到上述devicetree/xil2014.4/下:../dtc -I dts -O dtb -odevicetree.dtb zynq-zed.dts

PL配置devicetree自己寫的PL程式對於ARM來說相當於是新的外設,在xil提供的Linux核心中的dts是沒有的,需要自己製作匹配的dts檔案。SDK提供了根據在vivado中的硬體設計檔案來生成裝置樹的工具。也可以自己手工編寫或作出調整。使用SDK製作和PL相匹配的devicetree
SDK
設定下載device-tree-xlnx-xilinx-v2014.4.tar.gz,解壓將device-tree-xlnx-xilinx-v2014.4資料夾。新增至:bsprepo=D:\Xilinx\SDK\2014.1\data\embeddedsw\lib\bsp下,使用SDK新增下載好的目錄:SDKMenu: Xilinx Tools > Repositories > New… (bsp repo) > OK

注:由於device-tree-xlnx-xilinx-v2014.4.tar.gz,但是有win下路徑\的問題;重新在https://github.com/Xilinx/device-tree-xlnx下載,device-tree-xlnx-xilinx-v2014.4.zipclonein desktop),解決

SDK使用新建SDKMenu: File > New > Board Support Package > Board Support Package OS:device-tree > Finish 
在彈出的的對話方塊中修改引數;比如bootargs核心的命令列引數,核心啟動時傳給核心,可設定為:console=ttyPS0,115200root=/dev/ram rw earlyprintk編譯完成後在工程的\HW\Lab2-LedIP\Lab2-LedIP.sdk\device_tree_bsp_0下可以找到system.dts檔案將所有的dts,dtsi檔案copy到虛擬機器下的buildxil2014.4/linux-xlnx-xilinx-v2014.4下,使用dtc工具生成devicetree.dtb 
../dtc -I dts -O dtb -odevicetree.dtb system.dts

U-boot,設定uboot預設引數檔案

1.      在u-boot的include/configs/zynq_common.h檔案中決定了核心、檔案系統和裝置樹編譯後的檔名。如Kernel_image決定了u-boot引導zImage還是uImage。

2.      製作boot-image 順序

(1).fsbl.elf + system.bitstream.bit + uboot.elf啟動載入fpga

(2). fsbl.elf + uboot.elf 啟動不載入fpga

(3).vivado綜合的時候,生產bitstream時必須選擇bin格式的,uboot載入fpga有兩種格式:

一是:system.bit用fpga loadb 0 $ramaddr $size

二是:system.bin用 fpga load 0 $ramaddr $size

3.修改ramdisk

對於zImage用的ramdisk不需要新增uboot頭,即mkimage 操作如下:

[email protected]:~/work/nios-kernel/arm_linux/xilinx/roofs$gunzip ramdisk8M.image.gz

[email protected]: ~/xilinx/roofs# mount -o loopramdisk8M.image uramdisk/ (root許可權

修改完成:

[email protected]:/home/renxl/work/nios-kernel/arm_linux/xilinx/roofs#umount uramdisk

[email protected]:/home/renxl/work/nios-kernel/arm_linux/xilinx/roofs#gzip ramdisk8M.image

對於uImage用的uramdisk ,需要前進uboot頭,操作如下:

         cparm_ramdisk.image.gz ramdisk.image.gz

gunzip ramdisk.image.gz

mkdir file_tmp

sudo mount ramdisk.image -o loop ./file_tmp/

這樣可以在file_tmp目錄中對檔案系統進行修改,修改完成之後umount並重新壓縮即可

sudo umount file_tmp/

gzip ramdisk.image

//新增u-boot頭部

sudo apt-get install u-boot-tools

mkimage -A arm -T ramdisk -C gzip -d ramdisk.image.gzuramdisk.image.gz

修改machine ID:

uboot機器碼路徑:arch/arm/include/asm/mach-types.h

kernel機器碼路徑:arch/arm /tools/mach-types

相關推薦

Xilinx FPGA 嵌入式系統程式引導啟動流程分析設計

Xilinx FPGA 嵌入式系統程式引導和啟動的流程 北京華環電子        任曉亮                             2016年1月15日 在參考文獻1中,有這樣一句話,SystemACE解決方案是通過JTAG將程式下載到debug(對於M

關於S3C2440儲存器地址分配啟動流程分析

學習嵌入式,最開始應該瞭解就是地址空間的分配,真正搞清楚每個地址代表的位置,才有了入門的基礎。 1、地址分配(27根線如何尋找1G空間) S3C2440集成了豐富了外設控制器(LCD控制器、USB Device控制器、USB Host控制器、NAND FLASH控制器、I2

深入理解計算機系統——程式結構執行

前言   第一部分 程式結構和執行    正文   1.資訊儲存   虛擬記憶體:是一個非常大的位元組陣列   記憶體的地址:記憶體的每個位元組都由一個唯一的數字來標識   虛擬地址空間:所有可能地址的集合      2.十六進位制的表示法    插播一下 進位制的轉化,(數學渣)會進位制

把scrapyd設定為系統後臺服務啟動

一、設定為系統後臺服務 1、新建檔案/etc/init.d/scrapyd,名稱為scrapyd #!/bin/bash PORT=6800 HOME="/var/scrapyd" BIN="/usr/local/bin/scrapyd" pid=`netstat -l

Linux 開機引導啟動過程詳解(2)

理解作業系統開機引導和啟動過程對於配置作業系統和解決相關啟動問題是至關重要的。該文章陳述了 GRUB2 引導裝載程式開機引導裝載核心的過程和 systemd 初始化系統執行開機啟動作業系統的過程。   事實上,作業系統的啟動分為兩個階段:引導boot和啟動startup。引導

Linux 開機引導啟動過程詳解

你是否曾經對作業系統為何能夠執行應用程式而感到疑惑?那麼本文將為你揭開作業系統引導與啟動的面紗。   理解作業系統開機引導和啟動過程對於配置作業系統和解決相關啟動問題是至關重要的。該文章陳述了 GRUB2 引導裝載程式開機引導裝載核心的過程和 sy

嵌入式系統中RAMROM的疑惑澄清

而嵌入式系統中的RAM,一般也就是和PC上的(DDR)SDRAM一樣,掉電丟失。 嵌入式系統特別是手機中ROM的構成,可能是NorFlash也可能是NandFlash,速度較快,但是掉電不丟失。 而之所以之前疑惑地方在於, 一、現在很多時候手機都標榜自己的

1.1 嵌入式系統的定義組成

1.1 嵌入式系統的定義和組成 1.1.1 嵌入式系統的定義 以應用為中心,以計算機技術為基礎,軟硬體可裁剪,適應應用系統對功能、可靠性、成本、體積、功耗嚴格要求的專用計算機系統。 1.1.2 嵌入式系統發展概述 1、嵌入式系統發展的4個階段:無作業系統階段、簡單

嵌入式系統、linux嵌入式linux的區別

這幾個東西比較容易混淆 嵌入式系統: IEEE(國際電氣和電子工程師協會)對嵌入式系統的定義:“用於控制、監視或者輔助操作機器和裝置的裝置”。原文為:Devices Used to Control,Monitor or Assist the Operation of Equ

(三)android升級--系統升級方法啟動模式

1、系統更新的兩種方法 (1)從文件一我們知道了怎麼去製作android升級所需要的升級包,當然升級包做好後,我們怎麼去拿到這個升級包,這裡有兩種方法能拿到。第一,就是通過離線升級,也就是把製作好的升級包放到TF卡或SD卡中,然後選擇它即可;第二,就是通過線上升級,也就是我

FPGA組成、工作原理開發流程

1.5 embed nec 基礎 查找 clear 配置 系統性能 發現 FPGA組成、工作原理和開發流程 原創 2012年01月07日 09:11:52 9402 0 4 ********************************LoongEmbedd

MFC 程式入口執行流程

一 MFC程式執行過程剖析 1)我們知道在WIN32API程式當中,程式的入口為WinMain函式,在這個函式當中我們完成註冊視窗類,建立視窗,進入訊息迴圈,最後由作業系統根據傳送到程式視窗的訊息呼叫程式的視窗函式。而在MFC程式當中我們不在能找到類似WinMain這樣的程式入口,取而代之的是一

Spring 簡介啟動資訊分析

Spring Boot 優點 輕量化 提供 Spring 框架各種預設配置來簡化專案配置 內嵌 Web 容器 沒有冗餘程式碼生成和XML配置要求 Maven

Android 7.0系統啟動流程分析

隨著Android版本的升級,aosp專案中的程式碼也有了些變化,本文基於Android 7.0分析Android系統啟動流程.當我們按下電源鍵後,整個Android裝置大體經過了一下過程: 今天我們只想來分析init程序及其後的過程,也就是下圖所示部分:

Android6.0系統啟動流程分析三:SystemServer程序

在上一篇部落格 Android6.0系統啟動流程分析二:zygote程序一文中,我們隊Zygote程序的有了一定的瞭解。我們知道Zygote程序會啟動SystemServer程序,但我們並沒有在上篇文章中分析SystemServer程序的相關內容。這篇部落格,我

Android6.0系統啟動流程分析一:init程序

到了Android6.0,Init程序使用c++來寫了,不過沒有關係,它和c寫的init沒有太大的區別。 Init程序的入口程式碼是:system\core\init\init.cpp main函式: int main(int argc, char*

Android啟動流程分析(十) action的執行service的啟動

void service_start(struct service *svc, const char *dynamic_args) { /// ****************************** start service 的第一個階段 struct stat s; pid_t

istio組件介紹啟動流程

only 分發 獲得 default binary eap 5-0 mes 藍色 Istio各個Deployment包含的容器組件 Deployment 名稱 Container和Port Container和Port istio-pilot pilot: 8

TiKV 原始碼解析系列文章(七)gRPC Server 的初始化啟動流程

作者:屈鵬 本篇 TiKV 原始碼解析將為大家介紹 TiKV 的另一週邊元件—— grpc-rs。grpc-rs 是 PingCA

[ASP.NET Core 3框架揭祕]服務承載系統[5]: 承載服務啟動流程[上篇]

我們在《總體設計[上篇]》和《總體設計[下篇]》中通過對IHostedService、IHost和IHostBuider這三個介面的介紹讓讀者朋友們對服務承載模型有了大致的瞭解。接下來我們從抽象轉向具體,看看承載系統針對該模型的實現是如何落地的。要了解承載模型的預設實現,只需要瞭解IHost介面和IHostB