├── README.md └── src ├── Makefile └── helloworld.c /README.md: -------------------------------------------------------------------------------- 1 | 4 | 5 | # QEMU Zynq Petalinux setup on Linux Hosts 6 | 7 | ## Install QEMU 8 | 9 | Download the QEMU source: 10 | ``` 11 | git clone git://git.qemu-project.org/qemu.git 12 | ``` 13 | 14 | Get the `pixman` and `dtc` submodules: 15 | ``` 16 | cd qemu 17 | git submodule update --init pixman dtc 18 | ``` 19 | 20 | Compile with: 21 | ``` 22 | ./configure --target-list="aarch64-softmmu,microblazeel-softmmu" --enable-fdt --disable-kvm --disable-xen 23 | make -j4 24 | ``` 25 | 26 | ## Boot Petalinux 27 | 28 | In order to boot petalinux you have to download the devicetree and the Petalinux images from Xilinx. Open the following URL: [http://www.wiki.xilinx.com/Zynq+Releases](http://www.wiki.xilinx.com/Zynq+Releases) 29 | 30 | Download the latest release (here _Zynq 2016.4 Release_) for _zc702_ or download via command line with: 31 | ``` 32 | wget http://www.wiki.xilinx.com/file/view/2016.4-zc702-release.tar.xz/603943822/2016.4-zc702-release.tar.xz 33 | ``` 34 | 35 | Extract the archive: 36 | ``` 37 | tar xf 2016.4-zc702-release.tar.xz 38 | ``` 39 | 40 | You will find the following files in the extracted directory `zc702`: 41 | ``` 42 | BOOT.bin 43 | devicetree.dtb 44 | fsbl-zc702-zynq7.elf 45 | u-boot.elf 46 | uImage 47 | uramdisk.image.gz 48 | ``` 49 | 50 | To boot Petalinux with QEMU execute the following command: 51 | ``` 52 | /aarch64-softmmu/qemu-system-aarch64 \ 53 | -M xilinx-zynq-a9 \ 54 | -serial /dev/null \ 55 | -serial mon:stdio \ 56 | -display none \ 57 | -kernel /zc702/uImage \ 58 | -dtb /zc702/devicetree.dtb \ 59 | --initrd /zc702/uramdisk.image.gz \ 60 | -net nic -net user,hostfwd=tcp:127.0.0.1:10022-10.0.2.15:22,tftp= 61 | ``` 62 | 63 | This will boot Petalinux on the _zc702_ you can either login directly in the QEMU terminal as user `root` or you can login via ssh with the following command: 64 | 65 | ``` 66 | ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -p 10022 root@localhost 67 | ``` 68 | 69 | Since the Petalinux guest generates a new SSH key each time it boots the options `-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no` are used which disable the key check. 70 | 71 | You can terminate qemu by pressing [CTRL+A] [X] in the qemu terminal. 72 | 73 | ## Filesharing 74 | 75 | Petalinux was booted with the `-net` option `tftp=` which started a ftp server on the host with the root directory ``. 76 | 77 | You can retrieve files from this directory on the guest with the following command: 78 | ``` 79 | tftp -r -g 10.0.2.2 80 | ``` 81 | 82 | Unfortunately the server is read only. 83 | 84 | ## Compile for Petalinux 85 | 86 | To compile a C program on your host you need the `arm-linux-gnueabihf-gcc` compiler either you have a recent version of Xilinx Vivado SDx which provides this compiler or you have to install it manually for your host: 87 | 88 | * Ubuntu 89 | ``` 90 | sudo apt-get install gcc-4.8-arm-linux-gnueabihf 91 | ``` 92 | 93 | * TODO: Other Linux distros 94 | 95 | You can find a [Hello World C program](./src/helloworld.c) in [src](./src) and a [Makefile](./src/Makefile) to compile it for Petalinux. Compile it with: 96 | ``` 97 | make 98 | ``` 99 | 100 | Copy the binary to your directory for `tftp`: 101 | ``` 102 | cp helloworld 103 | ``` 104 | 105 | On the guest system execute the following commands to run the Hello World program: 106 | ``` 107 | tftp -r helloworld -g 10.0.2.2 108 | chmod +x helloworld 109 | ./helloworld 110 | ``` 111 | 112 | ## Mounting a Virtual SD Card on the Host Computer and in Petalinux running on QEMU 113 | 114 | To mount a virtual SD card on the host computer you have to install `nbd-client` (network block device client) and load its kernel module. 115 | 116 | * Ubuntu 117 | ``` 118 | sudo apt-get install nbd-client 119 | sudo modprobe nbd 120 | ``` 121 | * CentOS 122 | ``` 123 | sudo yum install nbd 124 | #TODO load kernel module 125 | ``` 126 | 127 | Check if the kernel module was sucessfully loaded with: 128 | ``` 129 | lsmod | grep nbd 130 | ``` 131 | 132 | In the next step you have to create a `qcow2` image with `qemu-img`: 133 | ``` 134 | /qemu-img create -f qcow2 /sdcard.qcow2 1000M 135 | ``` 136 | 137 | This will create a `qcow2` image with the size of 1GB. To mount the `sdcard.qcow2` on the host computer execute the following command to connect the `qcow2` to a network block device: 138 | ``` 139 | sudo /qemu-nbd --connect=/dev/nbd0 /sdcard.qcow2 140 | ``` 141 | 142 | Check if the `qcow2` image was mounted correctly with: 143 | ``` 144 | sudo fdisk /dev/nbd0 -l 145 | ``` 146 | 147 | You should see something like this: 148 | ``` 149 | Disk /dev/nbd0: 1000 MiB, 1048576000 bytes, 2048000 sectors 150 | Units: sectors of 1 * 512 = 512 bytes 151 | Sector size (logical/physical): 512 bytes / 512 bytes 152 | I/O size (minimum/optimal): 512 bytes / 512 bytes 153 | ``` 154 | 155 | Now you can format the SD card image with `fdisk` executing: 156 | ``` 157 | sudo fdisk /dev/nbd0 158 | ``` 159 | 160 | 1. Press [n] to create a new partition. 161 | 2. Choose [p] to make the new partition primary. 162 | 3. Press [Enter] to accept the default `1`. 163 | 4. Press [Enter] to accept the default `2048`. 164 | 5. Press [Enter] to accept the default `2047999`. 165 | 6. Press [w] to write the new partition table to the SD card image and leave `fdisk`. 166 | 167 | Check if the partition table is correct with: 168 | ``` 169 | sudo fdisk /dev/nbd0 -l 170 | ``` 171 | 172 | You should see something like this: 173 | ``` 174 | Disk /dev/nbd0: 1000 MiB, 1048576000 bytes, 2048000 sectors 175 | Units: sectors of 1 * 512 = 512 bytes 176 | Sector size (logical/physical): 512 bytes / 512 bytes 177 | I/O size (minimum/optimal): 512 bytes / 512 bytes 178 | Disklabel type: dos 179 | Disk identifier: 0x6dde57fa 180 | 181 | Device Boot Start End Sectors Size Id Type 182 | /dev/nbd0p1 2048 2047999 2045952 999M 83 Linux 183 | ``` 184 | 185 | After the partition table is written you can format the SD card image with vfat.: 186 | ``` 187 | sudo mkfs.vfat /dev/nbd0p1 188 | ``` 189 | 190 | Now you can mount the `/dev/nbd0p1` partition: 191 | ``` 192 | mkdir 193 | sudo mount -t vfat /dev/nbd0p1 194 | sudo chmod 775 -R 195 | ``` 196 | 197 | Now you can copy files to the SD card image. If you are done copying files unmount and disconnect it with: 198 | ``` 199 | sudo umount 200 | /qemu-nbd --disconnect /sdcard.qcow2 201 | ``` 202 | 203 | Start QEMU with the following command: 204 | 205 | ``` 206 | /aarch64-softmmu/qemu-system-aarch64 \ 207 | -M xilinx-zynq-a9 \ 208 | -serial /dev/null \ 209 | -serial mon:stdio \ 210 | -display none \ 211 | -kernel /zc702/uImage \ 212 | -dtb /zc702/devicetree.dtb \ 213 | --initrd /zc702/uramdisk.image.gz \ 214 | -net nic -net user,hostfwd=tcp:127.0.0.1:10022-10.0.2.15:22,tftp= 215 | -drive file=/sdcard.qcow2,if=sd,index=0,media=disk 216 | ``` 217 | 218 | Login into Petalinux as `root` and check if the SD card is visible with: 219 | ``` 220 | fdisk -l 221 | ``` 222 | 223 | You should see something like this: 224 | ``` 225 | Disk /dev/mmcblk0: 1048 MB, 1048576000 bytes 226 | 123 heads, 59 sectors/track, 282 cylinders 227 | Units = cylinders of 7257 * 512 = 3715584 bytes 228 | 229 | Device Boot Start End Blocks Id System 230 | /dev/mmcblk0p1 1 283 1022976 83 Linux 231 | Partition 1 has different physical/logical beginnings (non-Linux?): 232 | phys=(0, 32, 33) logical=(0, 34, 43) 233 | Partition 1 has different physical/logical endings: 234 | phys=(127, 122, 59) logical=(282, 25, 51) 235 | ``` 236 | 237 | Mount the SD card under Petalinux with: 238 | ``` 239 | mkdir 240 | mount -t vfat /dev/mmcblk0p1 241 | ``` 242 | -------------------------------------------------------------------------------- /src/Makefile: -------------------------------------------------------------------------------- 1 | CC=arm-linux-gnueabihf-gcc 2 | CFLAGS=-mcpu=cortex-a9 3 | 4 | all: helloworld 5 | 6 | helloworld: helloworld.c 7 | $(CC) $(CFLAGS) helloworld.c -o helloworld 8 | 9 | .PHONY clean: 10 | -rm helloworld 11 | -------------------------------------------------------------------------------- /src/helloworld.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() { 4 | 5 | float a = 3.14; 6 | float b = 42.23; 7 | 8 | printf("Hello World! %f\n", a+b); 9 | return 0; 10 | } 11 | --------------------------------------------------------------------------------