米聯客(MSXBO)osrc-lab LINUX開發包使用說明
使用XILINX ZYNQ FPGA開發LINUX使用petalinux大行其道,沒錯使用petalinux是比較簡潔和高效的辦法,但是,米聯客使用一種更加通用的方法,編寫了一些簡單的shell指令碼去編譯uboot,kernel,dts最終產生需要的uboot.bin,uimage,dtb檔案。米聯客給了大家一種比較通用的開發嵌入式硬體平臺的方法,掌握這個方法,不管是你XILINX的平臺,還是使用Intel的平臺或者其他廠家的ARM平臺,都可以很快的切換過去。
米聯客提供了3套常用的系統方案給大家選擇使用,這些系統方案全部可以自己定義或者裁剪,方案完全受控。接下來先來認識下,osrc-lab的檔案結構:
首先,開啟osrc-lab,其中有6個資料夾
我們先看下Boards下的書結構
Boards
└── MZ7X
├── buildroot
│ ├── dts
│ │ ├── skeleton.dtsi
│ │ ├── system-top.dts
│ │ ├── zynq-7000.dtsi
│ │ ├── zynq-zed.dts
│ │ └── zynq-zybo.dts
│ ├── fpga
│ ├── images
│ │ ├── boot
│ │ │ ├── BOOT.bin
│ │ │ ├── devicetree.dtb
│ │ │ ├── uEnv.txt
│ │ │ └── uImage
│ │ ├── common.sh
│ │ ├── deploy_image.sh
│ │ ├── make_parted.sh
│ │ ├── qspi_image
│ │ │ └── qspi_image.bin
│ │ └── rootfs
│ │ └── uramdisk.image.gz
│ └── output
│ ├── rootfs
│ ├── sdcard
│ │ ├── boot
│ │ └── rootfs
│ └── target
│ ├── boot.bin
│ ├── devicetree.dtb
│ ├── qspi_image.bif
│ ├── ramdisk.image.gz
│ ├── rootfs.tar.gz
│ ├── sd_image.bif
│ ├── system.bit
│ ├── u-boot.elf
│ ├── u-boot.img
│ ├── uImage
│ ├── uImage.bin
│ ├── uramdisk.image.gz
│ ├── zImage
│ └── zynq_fsbl.elf
├── debian
│ ├── dts
│ │ ├── skeleton.dtsi
│ │ ├── system-top.dts
│ │ ├── zynq-7000.dtsi
│ │ ├── zynq-zed.dts
│ │ └── zynq-zybo.dts
│ ├── fpga
│ ├── images
│ │ ├── boot
│ │ │ ├── BOOT.bin
│ │ │ ├── devicetree.dtb
│ │ │ ├── uEnv.txt
│ │ │ └── uImage
│ │ ├── common.sh
│ │ ├── deploy_image.sh
│ │ ├── make_parted.sh
│ │ └── rootfs
│ │ └── rootfs.tar.gz
│ └── output
│ ├── rootfs
│ ├── sdcard
│ │ ├── boot
│ │ └── rootfs
│ └── target
│ ├── boot.bin
│ ├── devicetree.dtb
│ ├── rootfs.tar.gz
│ ├── sd_image.bif
│ ├── system.bit
│ ├── u-boot.elf
│ ├── u-boot.img
│ ├── uImage
│ ├── uImage.bin
│ ├── zImage
│ └── zynq_fsbl.elf
└── ubuntu
├── dts
│ ├── skeleton.dtsi
│ ├── system-top.dts
│ ├── zynq-7000.dtsi
│ ├── zynq-zed.dts
│ └── zynq-zybo.dts
├── fpga
├── images
│ ├── boot
│ │ ├── BOOT.bin
│ │ ├── devicetree.dtb
│ │ ├── uEnv.txt
│ │ └── uImage
│ ├── common.sh
│ ├── deploy_image.sh
│ ├── make_parted.sh
│ └── rootfs
│ └── rootfs.tar.gz
└── output
├── rootfs
├── sdcard
│ ├── boot
│ └── rootfs
└── target
├── boot.bin
├── devicetree.dtb
├── rootfs.tar.gz
├── sd_image.bif
├── system.bit
├── u-boot.elf
├── u-boot.img
├── uImage
├── uImage.bin
├── zImage
└── zynq_fsbl.elf
可以看到以上樹結構中,包含了3套系統,每套系統裡面的檔案都差不多,我們這裡以buildroot系統為例:
├── buildroot
│ ├── dts
│ │ ├── skeleton.dtsi
│ │ ├── system-top.dts
│ │ ├── zynq-7000.dtsi
│ │ ├── zynq-zed.dts
│ │ └── zynq-zybo.dts
│ ├── fpga
│ ├── images
│ │ ├── boot
│ │ │ ├── BOOT.bin
│ │ │ ├── devicetree.dtb
│ │ │ ├── uEnv.txt
│ │ │ └── uImage
│ │ ├── common.sh
│ │ ├── deploy_image.sh
│ │ ├── make_parted.sh
│ │ ├── qspi_image
│ │ │ └── qspi_image.bin
│ │ └── rootfs
│ │ └── uramdisk.image.gz
│ └── output
│ ├── rootfs
│ ├── sdcard
│ │ ├── boot
│ │ └── rootfs
│ └── target
│ ├── boot.bin
│ ├── devicetree.dtb
│ ├── qspi_image.bif
│ ├── ramdisk.image.gz
│ ├── rootfs.tar.gz
│ ├── sd_image.bif
│ ├── system.bit
│ ├── u-boot.elf
│ ├── u-boot.img
│ ├── uImage
│ ├── uImage.bin
│ ├── uramdisk.image.gz
│ ├── zImage
│ └── zynq_fsbl.elf
Dts路徑下包含了system-top.dts,zynq-7000.dtsi是我們要用到的檔案,其他的可以刪除,其他的只是為了支援其他一些型號開發板而保留的板級dts
fpga路徑下是放我們的FPGA工程
Images路徑下
>boot路徑是放編譯好的uboot.bin,dtb,uimage
>qspi_image路徑存放編譯好的qpsi_image.bin,這個qpsi_image.bin是把包括uboot.bin,dtb,uimage合成到一個檔案來燒錄系統到qspi FLASH的。
> rootfs路徑為檔案系統uramdisk.image.gz
Output路徑下
>rootfs/sdcard路徑都不需要分析,是空的,預留使用
>target路徑下幾個檔案很關鍵
1) u-boot.elf這個編譯uboot核心的時候產生的,zynq_fsbl.elf是first bootloader,zynq晶片如果需要啟動, system.bit是FPGA編譯完成後的檔案。利用這三個檔案合成了簽名的uboot.bin。
2) uImage為編譯好的kernel檔案
3) devicetree.dtb 就是編譯好的裝置樹檔案
4) rootfs.tar.gz檔案是編譯好系統檔案,其首先改名為ramdisk.image.gz然後壓縮為uramdisk.image.gz。
瞭解了以上檔案後來分析buildroot系統部分的編譯指令碼
scripts
├── common.sh
├── kernel
│ ├── cfg_kernel.sh
│ ├── make_kernel.sh
│ └── save_kernel_defconfig.sh
├── rootfs
│ ├── buildroot
│ │ ├── cfg_rootfs.sh
│ │ ├── create_image.sh
│ │ ├── create_qspi_image.sh
│ │ ├── deploy_image.sh
│ │ ├── interfaces
│ │ ├── make_parted.sh
│ │ ├── make_rootfs.sh
│ │ ├── mount_rootfs.sh
│ │ ├── save_rootfs_defconfig.sh
│ │ ├── umount_rootfs.sh
│ │ └── ustart.sh
│ ├── debian
│ │ ├── cfg_rootfs.sh
│ │ ├── create_image.sh
│ │ ├── deploy_image.sh
│ │ ├── make_parted.sh
│ │ ├── make_qspi_image.sh
│ │ ├── make_rootfs.sh
│ │ └── save_rootfs_defconfig.sh
│ └── ubuntu
│ ├── cfg_rootfs.sh
│ ├── create_image.sh
│ ├── deploy_image.sh
│ ├── make_parted.sh
│ ├── make_rootfs.sh
│ └── save_rootfs_defconfig.sh
├── settings64.sh
├── uboot
│ ├── cfg_uboot.sh
│ ├── make_uboot.sh
│ └── save_uboot_defconfig.sh
└── xilinx
├── export_xilinx_env.sh
├── get_hw_description.sh
├── install_cable_drivers.sh
└── run_vivado.sh
可以看到以上樹結構中包含的指令碼,我們繼續以和buildroot系統為列講解這些指令碼的使用。
- Settings64.sh為配置osrc-lab的路徑,所以這個指令碼是最先執行的,而common.sh定義一些關於腳本里面需要高亮,標紅等的資訊輸出模版。我們這部分截圖settings64.sh裡面的程式碼
2、當執行完Settings64.sh後,後面的檔案都是可以根據需要執行,比如當我們的ZYNQ FPGA工程開發完後,需要把bit匯入到SDK 並且產生zynq_fsbl.elf檔案,之後需要通過執行get_hw_description.sh把bit檔案和zynq_fsbl.elf檔案複製到boards/MZ7X/buildroot/output/target/路徑,為後面編譯做好準備工作。如果FPGA工程沒有修改自然也不需要執行這個指令碼。
|
3、當我們修改了uboot原始碼就緒執行make_uboot.sh
############################################################################### # => Setting The Development Environment Variables if [ ! "${ZN_CONFIG_DONE}" ];then echo "[ERROR] Please source the settings64.sh script first" && exit 1 fi
# => Filename of the running script. ZN_SCRIPT_NAME="$(basename ${BASH_SOURCE})"
############################################################################### # => The beginning echo_info "[ $(date "+%Y/%m/%d %H:%M:%S") ] Starting ${ZN_SCRIPT_NAME}"
# => Make sure the source is there if [ "`ls -A ${ZN_UBOOT_DIR}`" = "" ]; then error_exit "Can't find the source code of u-boot" else cd ${ZN_UBOOT_DIR} fi
# => Building the U-Boot bootloader is a part of the Xilinx design flow. echo_info "Build U-Boot on the ${ZN_UBOOT_DIR}" make ${MAKE_JOBS} if [ $? -eq 0 ]; then ### # 1. U-Boot normally ### cp ${ZN_UBOOT_DIR}/u-boot ${ZN_TARGET_DIR}/u-boot.elf
### # 2. U-Boot SPL ### if [ -f "${ZN_UBOOT_DIR}/u-boot.img" ]; then cp ${ZN_UBOOT_DIR}/u-boot.img ${ZN_TARGET_DIR} cp ${ZN_UBOOT_DIR}/spl/boot.bin ${ZN_TARGET_DIR} fi
echo_info "U-Boot - Build OK" else error_exit "U-Boot - Build Failed" fi
# => The end echo_info "[ $(date "+%Y/%m/%d %H:%M:%S") ] Finished ${ZN_SCRIPT_NAME}" ############################################################################### |
4、當我們修改了system.dts或者修改了核心配置,或者核心原始碼也需要重新編譯核心
############################################################################### # => Setting The Development Environment Variables if [ ! "${ZN_CONFIG_DONE}" ];then echo "[ERROR] Please source the settings64.sh script first" && exit 1 fi
# => Filename of the running script. ZN_SCRIPT_NAME="$(basename ${BASH_SOURCE})"
############################################################################### # => The beginning echo_info "[ $(date "+%Y/%m/%d %H:%M:%S") ] Starting ${ZN_SCRIPT_NAME}"
# => Make sure the source is there if [ "`ls -A ${ZN_KERNEL_DIR}`" = "" ]; then error_exit "Can't find the source code of kernel" else cd ${ZN_KERNEL_DIR} fi
# => Make sure the target directory is there [[ ! "${ZN_TARGET_DIR}" ]] && error_exit "Can't find the target directory"
# => 1. Compiling the Kernel echo_info "Building the kernel image on the ${ZN_KERNEL_DIR}" make ${MAKE_JOBS} UIMAGE_LOADADDR=0x8000 uImage if [ $? -eq 0 ]; then echo_info "Installing the Kernel Image" cp -a ${ZN_KERNEL_DIR}/arch/arm/boot/zImage ${ZN_TARGET_DIR} cp -a ${ZN_KERNEL_DIR}/arch/arm/boot/uImage ${ZN_TARGET_DIR} cp -a ${ZN_KERNEL_DIR}/arch/arm/boot/uImage ${ZN_TARGET_DIR}/uImage.bin else error_exit "Kernel Image - Build Failed" fi
# => 2. Compiling the Device Tree Binaries echo_info "Building the Device Tree Binaries on the ${ZN_DTS_DIR}"
${ZN_DTC_DIR}/dtc -I dts -O dtb -o ${ZN_DTB_DIR}/${ZN_DTB_NAME} ${ZN_DTS_DIR}/${ZN_DTS_NAME} if [ $? -eq 0 ]; then echo_info "The Device Tree - Build OK" else error_exit "The Device Tree - Build Failed" fi
# => 3. Compiling the Kernel Modules echo_info "Building the Kernel Modules on the ${ZN_KERNEL_DIR}"
make ${MAKE_JOBS} modules if [ $? -eq 0 ]; then echo_info "Installing the Kernel Modules"
sudo rm -rf ${ZN_ROOTFS_MOUNT_POINT}/* sudo tar zxf ${ZN_TARGET_DIR}/rootfs.tar.gz -C ${ZN_ROOTFS_MOUNT_POINT} sudo rm -rf ${ZN_ROOTFS_MOUNT_POINT}/lib/modules/
sudo make ${MAKE_JOBS} ARCH=arm INSTALL_MOD_PATH=${ZN_ROOTFS_MOUNT_POINT} modules_install if [ $? -eq 0 ]; then sudo rm ${ZN_TARGET_DIR}/rootfs.tar.gz sudo tar zcf ${ZN_TARGET_DIR}/rootfs.tar.gz -C ${ZN_ROOTFS_MOUNT_POINT} . sudo rm -rf ${ZN_ROOTFS_MOUNT_POINT}/* echo_info "The Kernel Modules - Install OK" else sudo rm -rf ${ZN_ROOTFS_MOUNT_POINT}/* error_exit "The Kernel Modules - Install Failed" fi
else error_exit "Kernel Modules - Build Failed" fi
# => The end echo_info "[ $(date "+%Y/%m/%d %H:%M:%S") ] Finished ${ZN_SCRIPT_NAME}" ############################################################################### |
5、如果修改了檔案系統我們還要編譯檔案系統
執行make_rootfs.sh
上面都是準備工作,把修改編譯後的東西都放到,boards/MZ7X/buildroot/output/target/路徑
6、執行create_qspi_image.sh
其中產生boot.bin的程式碼如下
以下程式碼產生uramdisk.image.gz
另外對於核心和裝置樹的檔案是已經全部編譯核心的時候就好了,所以簡單複製就可以
7、有的時候我們需要修改uramdisk.image.gz 那麼可以執行make_rootfs.sh,可以看到我們這裡複製了interfaces檔案到/etc/network/interfaces中。而在interfaces檔案中我們有這麼一段程式碼,沒錯就是配置預設的IP地址,這樣可以實現在開機後網路就能正常工作,方便我們用網路除錯和傳輸資料。
auto eth0 iface eth0 inet static address 10.1.2.33 netmask 255.255.255.0 |
# => The beginning echo_info "$(date "+%Y.%m.%d-%H.%M.%S") : Starting $ZN_SCRIPT_NAME"
# => 確定uramdisk.image.gz檔案是否存在 if [ ! -f "${ZN_TARGET_DIR}/uramdisk.image.gz" ]; then error_exit "找不到uramdisk.image.gz" fi
# 預處理。。。 gunzip ${ZN_TARGET_DIR}/ramdisk.image.gz chmod u+rwx ${ZN_TARGET_DIR}/ramdisk.image sudo mount -o loop ${ZN_TARGET_DIR}/ramdisk.image ${ZN_ROOTFS_MOUNT_POINT} if [ $? -eq 0 ]; then echo_info "根檔案系統已經掛載在${ZN_ROOTFS_MOUNT_POINT}" #sudo cp ${ZN_SCRIPTS_DIR}/rootfs/buildroot//ustart.sh /${ZN_ROOTFS_MOUNT_POINT}/etc/init.d/ustart.sh sudo cp ${ZN_SCRIPTS_DIR}/rootfs/buildroot//interfaces /${ZN_ROOTFS_MOUNT_POINT}/etc/network/interfaces else error_exit "根檔案系統掛載失敗..." fi
# => The end echo_info "$(date "+%Y.%m.%d-%H.%M.%S") : Finished $ZN_SCRIPT_NAME" ############################################################################### |
8、修改完成後,執行umount_rootfs.sh 檔案,這樣修改後的uramdisk.image.gz就好了,這個時候他在boards/MZ7X/buildroot/output/target/路徑下,如果是SD卡啟動一定用這個檔案替換原來的uramdisk.image.gz。
9、執行 create_qspi_image.sh製作qpsi啟動檔案,而且是帶系統,核心,裝置樹的啟動檔案
####################################################################################################################### # Create a new bif files... ####################################################################################################################### BIF_FILE=${ZN_TARGET_DIR}/qspi_image.bif # # 每次都重新生成qspi_image.bif檔案,這樣,就可以解決手動修改路徑的問題。 echo "//arch = zynq; split = false; format = BIN" > ${BIF_FILE} echo "the_ROM_image:" >>${BIF_FILE} echo "{" >>${BIF_FILE} # The files we need are: # 1. the first stage boot loader echo " [bootloader]${ZN_TARGET_DIR}/zynq_fsbl.elf" >>${BIF_FILE} # 2. FPGA bit stream if [ -f "${ZN_TARGET_DIR}/system.bit" ]; then echo " ${ZN_TARGET_DIR}/system.bit" >>${BIF_FILE} fi # 3. Das U-Boot boot loader echo " ${ZN_TARGET_DIR}/u-boot.elf" >>${BIF_FILE} # 4. Linux kernel with modified header for U-Boot echo " [offset = 0x1300000]${ZN_TARGET_DIR}/uImage.bin" >>${BIF_FILE} # 5. Device tree blob echo " [offset = 0x1800000]${ZN_TARGET_DIR}/devicetree.dtb" >>${BIF_FILE} # 6. Root filesystem echo " [offset = 0x1820000]${ZN_TARGET_DIR}/uramdisk.image.gz" >>${BIF_FILE} echo "}" >>${BIF_FILE}
####################################################################################################################### # ####################################################################################################################### QSPI_IMAGE_BIN=${ZN_QSPI_IMG_DIR}/qspi_image.bin QSPI_IMAGE_MCS=${ZN_QSPI_IMG_DIR}/qspi_image.mcs
QSPI_IMAGE=${QSPI_IMAGE_BIN}
############################################################################### # Starting Vivado ############################################################################### # => The beginning echo_info "$(date "+%Y.%m.%d-%H.%M.%S") : Starting $ZN_SCRIPT_NAME"
# => Setting Zynq-7000 Development Environment Variables if [ -f "${ZN_SCRIPTS_DIR}/xilinx/export_xilinx_env.sh" ]; then source ${ZN_SCRIPTS_DIR}/xilinx/export_xilinx_env.sh else error_exit "Could not find file ${ZN_SCRIPTS_DIR}/xilinx/export_xilinx_env.sh !!!" fi
bootgen -image ${BIF_FILE} -o ${QSPI_IMAGE} -w on
# cd ${ZN_TARGET_DIR} # bootgen -image ${BIF_FILE} -o ${QSPI_IMAGE} -w on -split bin # cd -
# => The end echo_info "$(date "+%Y.%m.%d-%H.%M.%S") : Finished $ZN_SCRIPT_NAME" ############################################################################### |
對於buildroot系統請注意以上紅色的部分,在uboot原始碼中需要這樣設定,並且把#include <configs/zynq-common.h>放到前面。
還得開啟zynq-common.h修改uboot.bin uimage dts uramdisk.image.gz的載入偏移地址
9、好了以上就完成了一個簡單的閉環了。
以上的情況是基於你直接拿到我們的osrc-lab沒做大的修改的情況下使用的。
10、那麼如果你自己搭建的一個LINUX系統,VIVADO安裝的路徑和我們不一樣,就要修改export_xilinx_env.sh檔案
11、如果我們修改了uboot的menuconfig 那麼需要執行save_uboot_defconfig.sh,執行後把配置儲存到zynq_mz7x_defconfig
############################################################################### # => The beginning echo_info "[ $(date "+%Y/%m/%d %H:%M:%S") ] Starting ${ZN_SCRIPT_NAME}"
# => Make sure the source is there if [ "`ls -A ${ZN_UBOOT_DIR}`" = "" ]; then error_exit "Can't find the source code of u-boot" fi
# => To save bootloader config use the command : echo_info "To save bootloader config" make -C ${ZN_UBOOT_DIR} savedefconfig if [ $? != 0 ]; then error_exit "Failed to save defconfig" else cp ${ZN_UBOOT_DIR}/defconfig ${ZN_UBOOT_DIR}/configs/${ZN_UBOOOT_DEFCONFIG} fi
# => The end echo_info "[ $(date "+%Y/%m/%d %H:%M:%S") ] Finished ${ZN_SCRIPT_NAME}" ############################################################################### |
至於cfg_uboot.sh,這個會做一些清理工作
############################################################################### # => The beginning echo_info "[ $(date "+%Y/%m/%d %H:%M:%S") ] Starting ${ZN_SCRIPT_NAME}"
# => Make sure the source is there if [ "`ls -A ${ZN_UBOOT_DIR}`" = "" ]; then error_exit "Can't find the source code of u-boot" else cd ${ZN_UBOOT_DIR} fi
# => 1. Cleaning the Sources echo_info "To delete all build products as well as the configuration" make distclean || error_exit "Failed to make distclean"
# => 2. To configure the sources for the intended target. echo_info "Configure u-boot on the ${ZN_UBOOT_DIR}" make ${ZN_UBOOOT_DEFCONFIG} || error_exit "Failed to make ${ZN_UBOOOT_DEFCONFIG}"
# => 3. Prepare for compiling the source code echo_info "Prepare for compiling the source code" make tools || error_exit "Failed to make tools"
# => The end echo_info "[ $(date "+%Y/%m/%d %H:%M:%S") ] Finished ${ZN_SCRIPT_NAME}" ############################################################################### |
12、scripts/kernel路徑下一樣也有類似的指令碼 cfg_kernel.sh和save_kernel_defconfig.sh他們的使用方法一樣。
13、本文對osrc-lab應用做一個簡單的介紹,希望大家學習後,對於開發LINUX