|
|
# A minimal GNU/Linux distribution for the ZedBoard
|
|
|
|
|
|
This page explains how to create a minimal GNU/Linux distribution for the ZedBoard (Linux kernel, U-Boot, device tree, root file system).
|
|
|
|
|
|
## Create a directory for all downloads and builds
|
|
|
|
|
|
Example with `/opt/build`:
|
|
|
|
|
|
```bash
|
|
|
export BUILDDIR=/opt/build
|
|
|
rm -rf $BUILDDIR
|
|
|
mkdir -p $BUILDDIR
|
|
|
```
|
|
|
|
|
|
## Get all git repositories
|
|
|
|
|
|
```bash
|
|
|
cd $BUILDDIR
|
|
|
git clone https://github.com/Xilinx/device-tree-xlnx.git
|
|
|
git clone http://github.com/Xilinx/u-boot-xlnx.git
|
|
|
git clone https://github.com/Xilinx/linux-xlnx.git
|
|
|
git clone http://git.buildroot.net/git/buildroot.git
|
|
|
```
|
|
|
|
|
|
## Set environment variables
|
|
|
|
|
|
```bash
|
|
|
export CROSS_COMPILE=arm-xilinx-linux-gnueabi-
|
|
|
export PATH=$PATH:path-to-Xilinx-tools/SDK/<version>/gnu/arm/lin/bin
|
|
|
${CROSS_COMPILE}gcc --version
|
|
|
```
|
|
|
|
|
|
Note the result of the last command, we will need it later.
|
|
|
|
|
|
## Compile the Linux kernel
|
|
|
|
|
|
```bash
|
|
|
cd $BUILDDIR/linux-xlnx
|
|
|
make mrproper
|
|
|
make ARCH=arm O=build xilinx_zynq_defconfig
|
|
|
make ARCH=arm O=build
|
|
|
export PATH=$PATH:$BUILDDIR/linux-xlnx/build/scripts/dtc
|
|
|
```
|
|
|
|
|
|
## Compile U-Boot
|
|
|
|
|
|
```bash
|
|
|
cd $BUILDDIR/u-boot-xlnx
|
|
|
make mrproper
|
|
|
make O=build zynq_zed_config
|
|
|
make O=build
|
|
|
cp build/u-boot $BUILDDIR/u-boot.elf
|
|
|
export PATH=$PATH:$BUILDDIR/u-boot-xlnx/build/tools
|
|
|
```
|
|
|
|
|
|
## Generate the U-Boot image of the Linux kernel
|
|
|
|
|
|
```bash
|
|
|
cd $BUILDDIR
|
|
|
mkimage -A arm -O linux -C none -T kernel -a 0x8000 -e 0x8000 -d linux-xlnx/build/arch/arm/boot/zImage uImage
|
|
|
```
|
|
|
|
|
|
Adapt the load address (`-a 0x8000`) and entry point (`-e 0x8000`) to your memory configuration.
|
|
|
|
|
|
## Configure and build a root file system
|
|
|
|
|
|
Use `buildroot` to configure your root file system, starting from the default. We will first configure `busybox`:
|
|
|
|
|
|
```bash
|
|
|
cd $BUILDDIR/buildroot
|
|
|
make O=$BUILDDIR/initramfs zedboard_defconfig
|
|
|
make O=$BUILDDIR/initramfs busybox-menuconfig
|
|
|
```
|
|
|
|
|
|
In the `busybox` configuration menu you may want to change:
|
|
|
|
|
|
```
|
|
|
Busybox Settings -> General Configuration -> Enable options for full-blown desktop systems -> no
|
|
|
Busybox Settings -> General Configuration -> Enable locale support (system needs locale for this to work) -> yes
|
|
|
Busybox Settings -> General Configuration -> Support Unicode -> yes
|
|
|
Busybox Settings -> General Configuration -> Use libc routines for Unicode (else uses internal ones) -> yes
|
|
|
Busybox Settings -> General Configuration -> Runtime SUID/SGID configuration via /etc/busybox.conf -> yes
|
|
|
```
|
|
|
|
|
|
Quit with saving and start configuring `buildroot`:
|
|
|
|
|
|
```bash
|
|
|
make O=$BUILDDIR/initramfs menuconfig
|
|
|
```
|
|
|
|
|
|
In the `buildroot` configuration menus you may want to change a few things:
|
|
|
|
|
|
```
|
|
|
Build options -> Location to save buildroot config -> <BUILDDIR>/buildroot.config
|
|
|
Build options -> Enable compiler cache -> yes (faster build)
|
|
|
Build options -> gcc optimization level -> 3 (optimize for speed)
|
|
|
Toolchain -> Toolchain type -> External toolchain
|
|
|
Toolchain -> Toolchain -> Custom toolchain
|
|
|
Toolchain -> Toolchain path -> <path-to-Xilinx-tools>/SDK/<version>/gnu/arm/lin
|
|
|
Toolchain -> Toolchain prefix -> arm-xilinx-linux-gnueabi (no "-" at the end)
|
|
|
Toolchain -> External toolchain gcc version -> <the-toolchain-version-you-noted>
|
|
|
Toolchain -> External toolchain C library -> glibc/eglibc
|
|
|
Toolchain -> Toolchain has RPC support? -> yes
|
|
|
Toolchain -> Toolchain has C++ support? -> yes
|
|
|
Toolchain -> Purge unwanted locales -> yes
|
|
|
Toolchain -> Locales to keep -> C en_US
|
|
|
Toolchain -> Generate locale data -> en_US.UTF-8
|
|
|
System configuration -> System hostname -> secbus
|
|
|
System configuration -> System banner -> Welcome to SecBus (c) Telecom ParisTech. Root password: secbus
|
|
|
System configuration -> Root password -> secbus
|
|
|
Kernel -> Linux Kernel -> no
|
|
|
Target packages -> BusyBox configuration file to use? -> <BUILDDIR>/busybox.config
|
|
|
Bootloaders -> U-Boot -> no
|
|
|
```
|
|
|
|
|
|
Note: do not use the `$BUILDDIR` environment variable. Replace <BUILDDIR> by the absolute path (`/opt/build` in our example) in the examples above. Quit with saving. We are almost done. Save the `buildroot` and `busybox` configurations and build the root file system:
|
|
|
|
|
|
```bash
|
|
|
make O=$BUILDDIR/initramfs savedefconfig
|
|
|
make O=$BUILDDIR/initramfs busybox-update-config
|
|
|
make O=$BUILDDIR/initramfs
|
|
|
```
|
|
|
|
|
|
If you get an error:
|
|
|
|
|
|
```
|
|
|
Incorrect selection of kernel headers: expected x.x.x, got y.y.y
|
|
|
```
|
|
|
note the `y.y.y` run again the `buildroot` configuration:
|
|
|
|
|
|
```bash
|
|
|
make O=$BUILDDIR/initramfs menuconfig
|
|
|
```
|
|
|
change:
|
|
|
|
|
|
```
|
|
|
Toolchain -> External toolchain kernel headers series -> the-kernel-version-you-noted
|
|
|
```
|
|
|
quit with saving, save again the configuration and build:
|
|
|
|
|
|
```bash
|
|
|
make O=$BUILDDIR/initramfs savedefconfig
|
|
|
make O=$BUILDDIR/initramfs
|
|
|
```
|
|
|
|
|
|
## Generate the U-Boot image of the root file system image
|
|
|
|
|
|
```bash
|
|
|
cd $BUILDDIR
|
|
|
mkimage -A arm -T ramdisk -C gzip -d initramfs/images/rootfs.cpio.gz rootfs.cpio.uboot
|
|
|
```
|
|
|
|
|
|
## Generate the Device Tree Sources (DTS) for your system
|
|
|
|
|
|
We assume that you used Vivado to create a Zynq design and that you synthesized it. You should find its Hardware Description File (HDF) in the Vivado output results. Its name is something like `xxx.sysdef`. We also assume that you have the Xilinx tools in your `PATH`. Download the provided [dts.hsi.tcl](zedboard-linux-uboot-dtb-buildroot/dts.hsi.tcl) TCL script and save it in `$BUILDDIR`. Use it to generate the DTS using the `hsi` utility from the Xilinx SDK:
|
|
|
|
|
|
```bash
|
|
|
mkdir $BUILDDIR/hw
|
|
|
cd $BUILDDIR/hw
|
|
|
hsi -mode batch -quiet -notrace -source ../dts.hsi.tcl -tclargs <some-path>/xxx.sysdef $BUILDDIR/device-tree-xlnx ../dts
|
|
|
```
|
|
|
|
|
|
The Device Tree Sources are in `$BUILDDIR/dts`.
|
|
|
|
|
|
## Edit the Device Tree Sources (DTS)
|
|
|
|
|
|
Edit the DTS files if needed. Examples of things you may want to change:
|
|
|
|
|
|
In `$BUILDDIR/dts/system.dts` (top level) you may want to change the definition of the physical memory base address and size:
|
|
|
|
|
|
```
|
|
|
memory {
|
|
|
device_type = "memory";
|
|
|
reg = <0x0 0x20000000>;
|
|
|
};
|
|
|
```
|
|
|
|
|
|
For instance, if you want to use the `[0x4800_0000...0x6000_0000[` range instead, replace the above lines by:
|
|
|
|
|
|
```
|
|
|
memory {
|
|
|
device_type = "memory";
|
|
|
linux,usable-memory = <0x48000000 0x18000000>;
|
|
|
};
|
|
|
```
|
|
|
|
|
|
In the same `$BUILDDIR/dts/system.dts` you may want to enable some of the 4 PS-to-PL clocks. To enable clocks FPGA1 and FPGA3, for instance, replace:
|
|
|
|
|
|
```
|
|
|
&clkc {
|
|
|
fclk-enable = <some-value>;
|
|
|
ps-clk-frequency = <33333333>;
|
|
|
};
|
|
|
```
|
|
|
by:
|
|
|
|
|
|
```
|
|
|
&clkc {
|
|
|
fclk-enable = <0xa>;
|
|
|
ps-clk-frequency = <33333333>;
|
|
|
};
|
|
|
```
|
|
|
|
|
|
If you decided to disable the CPU caches, in the`$BUILDDIR/dts/zynq-7000.dtsi` included DTS file, you may want to comment out the L2 cache controller:
|
|
|
|
|
|
```
|
|
|
/*
|
|
|
L2: cache-controller@f8f02000 {
|
|
|
compatible = "arm,pl310-cache";
|
|
|
...
|
|
|
};
|
|
|
*/
|
|
|
```
|
|
|
|
|
|
## Compile the Device Tree Blob (DTB)
|
|
|
|
|
|
Once your DTS files are adapted to your needs, compile the device tree blob:
|
|
|
|
|
|
```bash
|
|
|
cd $BUILDDIR
|
|
|
dtc -I dts -O dtb -o devicetree.dtb dts/system.dts
|
|
|
```
|
|
|
|
|
|
## Generate the First Stage Boot Loader (FSBL) for your system
|
|
|
|
|
|
Download the provided [fsbl.hsi.tcl](zedboard-linux-uboot-dtb-buildroot/fsbl.hsi.tcl) TCL script and save it in `$BUILDDIR`. Use it to generate the FSBL using the `hsi` utility from the Xilinx SDK:
|
|
|
|
|
|
```bash
|
|
|
cd $BUILDDIR/hw
|
|
|
hsi -mode batch -quiet -notrace -source ../fsbl.hsi.tcl -tclargs <some-path>/xxx.sysdef ../fsbl
|
|
|
```
|
|
|
|
|
|
The FSBL ELF is `$BUILDDIR/fsbl/executable.elf`.
|
|
|
|
|
|
## Generate the boot image
|
|
|
|
|
|
Pack the FSBL ELF, the bitstream (if any) for the programmable logic and the U-Boot ELF. First Download the provided [boot.bif](zedboard-linux-uboot-dtb-buildroot/boot.bif) boot image specification file and save it in `$BUILDDIR`. If you do not have a bitstream for the programmable logic edit `boot.bif` and comment out the line corresponding to the bitstream:
|
|
|
|
|
|
```
|
|
|
// bitstream.bit
|
|
|
```
|
|
|
|
|
|
Else, copy the bitstream (which should be in the same directory where you found the `xxx.sysdef` Hardware Description File) in `$BUILDDIR`:
|
|
|
|
|
|
```bash
|
|
|
cd $BUILDDIR
|
|
|
cp <some-path>/xxx.bit bitstream.bit
|
|
|
```
|
|
|
|
|
|
Generate the boot image:
|
|
|
|
|
|
```bash
|
|
|
cd $BUILDDIR
|
|
|
bootgen -w -image boot.bif -o boot.bin
|
|
|
```
|
|
|
|
|
|
## Copy on a SD card and boot
|
|
|
|
|
|
Copy all the elements on a SD card:
|
|
|
|
|
|
```bash
|
|
|
cp boot.bin devicetree.dtb rootfs.cpio.uboot uImage /media/SDCard
|
|
|
```
|
|
|
|
|
|
Unmount and eject the SD card, plug it to the ZedBoard, connect the USB UART cable, launch a serial console (minicom, cu, putty, screen...) and finally power up the ZedBoard. The first time you boot, the U-Boot environment variables are probably not what they should be. Stop the U-Boot count-down, restore the default environment variables (print and save the previous configuration if needed):
|
|
|
|
|
|
```
|
|
|
zynq-uboot> env default -a -f
|
|
|
```
|
|
|
|
|
|
Modify the following U-Boot environment variable to reflect the name of our root file system:
|
|
|
|
|
|
```
|
|
|
zynq-uboot> setenv ramdisk_image rootfs.cpio.uboot
|
|
|
```
|
|
|
|
|
|
This should be sufficient to boot our GNU/Linux distribution. To avoid typing this each time, save the variable definition on the on-board flash:
|
|
|
|
|
|
```
|
|
|
zynq-uboot> saveenv
|
|
|
```
|
|
|
<!-- vim: set tabstop=4 softtabstop=4 shiftwidth=4 noexpandtab textwidth=0: --> |