Petalinux のカスタマイズ

(1835d) 更新


電気回路/zynq

概要

電気回路/zynq/Petalinux のビルド の続きです。

z-turn ボード用に Petalinux から起動 SD カードを作ったのですが、

  • シリアルポート番号の問題でメインコンソールが正常起動しない
  • BOOT.bin と image.ub だけ、という構成では部分的な差し替えができず開発用には向かない
  • その他諸々

いろいろ不満があるので解決しようと思います。

解決した結果の手順をまとめたものはこのページの最後にあります >> 全体のまとめ

フォルダ構成

開発用に作った VirtualBox (Ubuntu 16.04) のフォルダ構成は、

  • ~/z-turn/

    • petalinux/ : petalinux SDK のルートフォルダ
    • zturn-v2016.4/ : プロジェクトのルートフォルダ
    • design_1_wrapper_hw_platform_1/ : vivado から export したフォルダ

主にプロジェクトのルートフォルダである ~/z-turn/zturn-v2016.4/ で作業します。

環境設定スクリプト

  • petalinux-setup というコマンドで petalinux 環境を整えられるようにした
  • petalinux のコマンドは LANG=C でないと動かないので、 忘れずに LANG=C するために alias を設定した
LANG:console
$ alias petalinux-setup='source ~/z-turn/petalinux/settings.sh'
$ petalinux-setup
 PetaLinux environment set to '/home/osamu/z-turn/petalinux'
 WARNING: /bin/sh is not bash!
 bash is PetaLinux recommended shell. Please set your default shell to bash.
 INFO: Checking free disk space
 INFO: Checking installed tools
 INFO: Checking installed development libraries
 INFO: Checking network and other services
$ set | grep PETA
 PETALINUX=/home/osamu/z-turn/petalinux
 PETALINUX_VER=2016.4
$ petalinux-^T
 petalinux-boot      petalinux-config    petalinux-package   petalinux-util
 petalinux-build     petalinux-create    petalinux-setup
$ petalinux-^C
$ cat >> ~/.bashrc  # 自動実行スクリプトに登録する
alias petalinux-setup='source ~/z-turn/petalinux/settings.sh'
alias petalinux-boot='LANG=C petalinux-boot'
alias petalinux-build='LANG=C petalinux-build'
alias petalinux-config='LANG=C petalinux-config'
alias petalinux-create='LANG=C petalinux-create'
alias petalinux-package='LANG=C petalinux-package'
alias petalinux-util='LANG=C petalinux-util'
^D

パッケージング方法の変更

Petalinux のデフォルト設定では、

  • BOOT.BIN
    • fsbl.elf = First Stage Boot Loader
    • u-boot.elf = Second Stage Boot Loader
    • design.bit = ロジック設定
  • image.ub
    • system.dtb = デバイスツリー設定
    • uImage = カーネル
    • rootfs = ルートファイルシステム

の2つのファイルに起動に必要なすべてのファイルをまとめるようになっています。

しかし開発においては BOOT.BIN の中の design.bit や、 image.ub の中の dtb, uImage, rootfs は頻繁に変更したくなるため、 すべて別々のファイルにしておいた方が、 個別にビルド&デプロイできて便利です。

ということで、設定を変更してみます。

petalinux-config & build

  • fsbl は vivado で作ったものを使えばいいようなので、 petalinux では生成しない
  • dtb を SD カードから読ませる
  • rootfs を SD カードから読ませる
  • console=ttyPS1

としました。

/dev/sdf に SD カードが見えている状況で、
(参考: [VirtualBox へ SD カードをマウントする])

LANG:console
$ petalinux-setup
$ petalinux-config
 Linux Components Selection --->
   [Uncheck] First Stage Bootloader
 Auto Config Settings --->
   [Uncheck] fsbl autoconfig
 Subsystem AUTO Hardware Settings --->
   Advanced bootable images storage Settings --->
     dtb image settings --->
       image storage media --->
         primary sd
 Kernel Bootargs --->
   [Uncheck] generate boot args automatically
   user set kernel bootargs = console=ttyPS1,115200 root=/dev/mmcblk0p2 rw earlyprintk
 Image Packing Configuration --->
   Root filesystem type = SD Card
$ petalinux-build
$ petalinux-package --boot --fsbl ../design_1_wrapper_hw_platform_1/fsbl.elf --fpga  images/linux/design_1_wrapper.bit --u-boot --force
$ rm BOOT.BIN  # なぜかカレントフォルダにもできてしまうので
$ ls -l images/linux/
 -rw-rw-r-- 1   4545920  BOOT.BIN
 -rw-r--r-- 1   2077787  System.map.linux
 -rw-r--r-- 1   4045676  design_1_wrapper.bit
 -rw-r--r-- 1   9055012  image.ub
 -rw-r--r-- 1  67108864  rootfs.ext3
 -rw-r--r-- 1  67108864  rootfs.ext4
 -rw-r--r-- 1   5280887  rootfs.ext4.gz
 -rw-r--r-- 1     13702  system.dtb
 -rwxr-xr-x 1    396096  u-boot.bin
 -rwxr-xr-x 1   2507500  u-boot.elf
 -rw-r--r-- 1  11615732  vmlinux
 -rw-r--r-- 1   3827624  zImage
$ sudo fdisk /dev/sdf
コマンド (m でヘルプ): p
 Disk /dev/sdf: 7.4 GiB, 7962886144 bytes, 15552512 sectors
 Units: sectors of 1 * 512 = 512 bytes
 Sector size (logical/physical): 512 bytes / 512 bytes
 I/O size (minimum/optimal): 512 bytes / 512 bytes
 Disklabel type: dos
 Disk identifier: 0xd720fb16
 
 デバイス   起動 Start 最後から セクタ Size Id タイプ
 /dev/sdf1  *     2048   133119 131072  64M  e W95 FAT16 (LBA)
コマンド (m でヘルプ): d
 Selected partition 1
 Partition 1 has been deleted.
コマンド (m でヘルプ): n
 Partition type
    p   primary (0 primary, 0 extended, 4 free)
    e   extended (container for logical partitions)
 Select (default p): p
パーティション番号 (1-4, default 1): 
First sector (2048-15552511, default 2048):
Last sector, +sectors or +size{K,M,G,T,P} (2048-15552511, default 15552511): +128M
 
 Created a new partition 1 of type 'Linux' and of size 128 MiB.
コマンド (m でヘルプ): t
 Selected partition 1
Partition type (type L to list all types): b
 Changed type of partition 'Linux' to 'W95 FAT32'.
コマンド (m でヘルプ): n
 Partition type
    p   primary (1 primary, 0 extended, 3 free)
    e   extended (container for logical partitions)
Select (default p): p
パーティション番号 (2-4, default 2):
First sector (264192-15552511, default 264192):
Last sector, +sectors or +size{K,M,G,T,P} (264192-15552511, default 15552511):

 Created a new partition 2 of type 'Linux' and of size 7.3 GiB.
コマンド (m でヘルプ): p
 Disk /dev/sdf: 7.4 GiB, 7962886144 bytes, 15552512 sectors
 Geometry: 74 heads, 1 sectors/track, 1023 cylinders
 Units: sectors of 1 * 512 = 512 bytes
 Sector size (logical/physical): 512 bytes / 512 bytes
 I/O size (minimum/optimal): 512 bytes / 512 bytes
 Disklabel type: dos
 Disk identifier: 0xd720fb16
 
 デバイス   起動  Start 最後から セクタ  Size Id タイプ
 /dev/sdf1         2048   264191   262144  128M  b W95 FAT32
 /dev/sdf2       264192 15552511 15288320  7.3G 83 Linux
コマンド (m でヘルプ): w
 The partition table has been altered.
 Calling ioctl() to re-read partition table.
 Syncing disks.
$ sudo mkfs.vfat -F32 /dev/sdf1
 mkfs.fat 3.0.28 (2015-05-16)
$ sudo mkfs.ext4 /dev/sdf2
 mke2fs 1.42.13 (17-May-2015)
 Creating filesystem with 1911040 4k blocks and 478608 inodes
 Filesystem UUID: 71a66d67-ba3e-4ee2-bc7a-33a87f8611b9
 Superblock backups stored on blocks:
         32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632
 
 Allocating group tables: done
 Writing inode tables: done
 Creating journal (32768 blocks): done
 Writing superblocks and filesystem accounting information: done
$ sudo mkdir /mnt/sdcard1
$ sudo mkdir /mnt/sdcard2
$ sudo mount /dev/sdf1 /mnt/sdcard1
$ sudo cp images/linux/BOOT.BIN   /mnt/sdcard1
$ sudo cp images/linux/image.ub   /mnt/sdcard1
$ sudo cp images/linux/system.dtb /mnt/sdcard1
$ sudo umount /mnt/sdcard1
$ sudo mount /dev/sdf2 /mnt/sdcard2
$ sudo tar fxz images/linux/rootfs.tar.gz -C /mnt/sdcard2
$ sudo umount /mnt/sdcard2

起動してみる

オプションで bootargs を設定したおかげで、起動時に手動で入力しなくても ttyPS1 への出力を読めるようになっている。

ちゃんと SD カードをルートとしてマウントしており、起動直後は

LANG:console
$ df
 Filesystem           1K-blocks      Used Available Use% Mounted on
 /dev/root              7392892     29248   6965052   0% /
 devtmpfs                    64         0        64   0% /dev
 tmpfs                   515880        32    515848   0% /run
 tmpfs                   515880        40    515840   0% /var/volatile
 tmpfs                       64         0        64   0% /dev
 /dev/mmcblk0p1          129039     13298    115741  10% /run/media/mmcblk0p1
 /dev/mmcblk0p2         7392892     29248   6965052   0% /run/media/mmcblk0p2

のようになっていた。

これで、

  • mmcblk0p1
    • BOOT.BIN
    • image.ub
    • system.dtb
  • mmcblk0p2
    • /

という構成にできた。

image.ub をやめたい

image.ub は U-Boot fitImage だそうで、
http://mizupc8.bio.mie-u.ac.jp/pukiwiki/index.php?LinkStation%2FTeraStation%2F%E7%8E%84%E7%AE%B1%2FPPC%2FKURO-BOX%2FT4%2FU-Boot%2FFIT
によれば、

  • FIT - Flattened uImage Tree
  • dtb のような構造を持っており、
    • .its - image tree source
    • .itb - image tree blob
    • .dtb - device tree blob

its というファイルから作られるっぽい。

kernel と ramdisk を一度にメモリに上げるには良いけれど、 今はもうカーネルしか入っていないと思われるので、 uImage をそのまま読んでくれた方がカーネルのリコンパイル時などに手間が省ける。

LANG:console
$ find -name "*.its"
 ./build/tmp/deploy/images/plnx_arm/fitimage.its
 ./build/tmp/work/plnx_arm-xilinx-linux-gnueabi/petalinux-user-image/1.0-r0/petalinux-user-image-1.0/fit-image.its
$ cat ./build/tmp/deploy/images/plnx_arm/fitimage.its
 ...
         images {
                 kernel@0 {
                         description = "Linux Kernel";
                         data = /incbin/("/home/osamu/z-turn/zturn-v2016.4/build/tmp/deploy/images/plnx_arm/zImage");
                         ...
                         load = <0x8000>;
                         entry = <0x8000>;
                         ...
                 fdt@0 {
                         description = "Flattened Device Tree blob";
                         data = /incbin/("/home/osamu/z-turn/zturn-v2016.4/build/tmp/deploy/images/plnx_arm/plnx_arm-system.dtb");
                         ...
                 ramdisk@0 {
                         description = "ramdisk";
                         data = /incbin/("/home/osamu/z-turn/zturn-v2016.4/build/tmp/deploy/images/plnx_arm/petalinux-user-image-plnx_arm.cpio.gz");
                         ...
       configurations {
               default = "conf@1";
               conf@1 {
                       description = "Boot Linux kernel with FDT blob + ramdisk";
                       kernel = "kernel@0";
                       fdt = "fdt@0";
                       ramdisk = "ramdisk@0";
                       hash@1 {
                               algo = "sha1";
                       };
               };
               conf@2 {
                       description = "Boot Linux kernel with FDT blob";
                       kernel = "kernel@0";
                       fdt = "fdt@0";
                       hash@1 {
                               algo = "sha1";
                       };
               };
 ...

あれ? ramdisk と dtb も含まれてる?

確かにファイルサイズも、zImage + rootfs くらいになってる。。。

 3827624  zImage
   13726  system.dtb
 5211912  rootfs.cpio.gz
========================
 9054900  image.ub

petalinux-config -c u-boot

これは多分 u-boot の設定に違いない?ということで、

LANG:console
$ petalinux-config -c u-boot
 Boot Images --->
   [uncheck] Support Flattened Image Tree
 Boot media --->
   [check] Support for booting from SD/EMMC
 Networking support --->
   [uncheck] Random ethaddr if unset  
   [uncheck] Control TFTP timeout and count through environment
 Device Drivers --->
   [uncheck] Ethernet PHY (physical media interface) support
$ petalinux-config
 u-boot Configuration --->
   U-boot config --->  
     other
 WARNING: /home/osamu/z-turn/petalinux/components/yocto/source/arm/layers/meta-xilinx/recipes-bsp/u-boot/u-boot-xlnx_2016.07.bb.do_compile is tainted from a forced run
$ petalinux-build
 WARNING: /home/osamu/z-turn/petalinux/components/yocto/source/arm/layers/meta-xilinx/recipes-bsp/u-boot/u-boot-xlnx_2016.07.bb.do_compile is tainted from a forced run
$ petalinux-package --boot --fsbl ../design_1_wrapper_hw_platform_1/fsbl.elf --fpga  images/linux/design_1_wrapper.bit --u-boot --force
$ ls -l images/linux/
 -rw-rw-r-- 1 osamu osamu  4515888  2月 23 16:31 BOOT.BIN
 -rw-r--r-- 1 osamu osamu  2077787  2月 23 16:21 System.map.linux
 -rw-r--r-- 1 osamu osamu  4045676  2月 23 15:59 design_1_wrapper.bit
 -rw-r--r-- 1 osamu osamu  9054896  2月 23 16:23 image.ub
 -rw-r--r-- 1 osamu osamu 67108864  2月 23 16:22 rootfs.ext3
 -rw-r--r-- 1 osamu osamu 67108864  2月 23 16:22 rootfs.ext4
 -rw-r--r-- 1 osamu osamu  5280834  2月 23 16:22 rootfs.ext4.gz
 -rw-r--r-- 1 osamu osamu    13726  2月 23 16:21 system.dtb
 -rwxr-xr-x 1 osamu osamu   366064  2月 23 16:22 u-boot.bin
 -rwxr-xr-x 1 osamu osamu  2368752  2月 23 16:22 u-boot.elf
 -rw-r--r-- 1 osamu osamu 11615732  2月 23 16:21 vmlinux
 -rw-r--r-- 1 osamu osamu  3827616  2月 23 16:21 zImage
 -rw-r--r-- 1 osamu osamu   396001  2月 23 16:31 zynq_fsbl.elf

まず、u-boot の設定を自分でして、その後 petalinux-config すると WARNING が出るのは、上書きされてるってことなのかどうか???

個別の config を動かした後は petalinux-config しちゃだめなのかも?
でもじゃあどうしろと・・・

あと、U-Boot の設定で FIT support を off にしたのに image.ub が作成されている。

fsbl の生成も off にしたつもりだったのに生成されている。

zImage も作成されているのでこれを置けば良いのかどうか?

ブートパーティションの中身を BOOT.BIN と zImage, system.dtb だけにしてみたところ、

LANG:console
reading uEnv.txt
** Unable to read file uEnv.txt **
Copying Linux from SD to RAM...
reading uImage
** Unable to read file uImage **

違ったみたい。

uImage を生成

LANG:console
$ petalinux-package --image -c kernel --format uImage
$ touch uEnv.txt  # 空のファイル

としてこれらをコピーしたところ、
(なぜかカーネルを再コンパイルしてるみたいでものすごく時間がかかる orz)

LANG:console
reading devicetree.dtb
** Unable to read file devicetree.dtb **

ありゃ。

uEnv.txt の設定

LANG:console
echo "devicetree_image=system.dtb" > image/linux/uEnv.txt

としたら dtb はちゃんと読まれたのだけれど、

今度は、ramdisk を読めないと言われた。

LANG:console
reading uEnv.txt
28 bytes read in 8 ms (2.9 KiB/s)
Importing environment from SD ...
Hit any key to stop autoboot:  0
Device: sdhci@e0100000
Manufacturer ID: 13
OEM: 4b47
Name: SD08G
Tran Speed: 50000000
Rd Block Len: 512
SD version 3.0
High Capacity: Yes
Capacity: 7.4 GiB
Bus Width: 4-bit
Erase Group Size: 512 Bytes
reading uEnv.txt
28 bytes read in 8 ms (2.9 KiB/s)
Loaded environment from uEnv.txt
Importing environment from SD ...
Copying Linux from SD to RAM...
reading uImage
3827680 bytes read in 256 ms (14.3 MiB/s)
reading system.dtb
13726 bytes read in 17 ms (788.1 KiB/s)
reading uramdisk.image.gz
** Unable to read file uramdisk.image.gz **
Zynq> printenv 
 baudrate=115200
 bitstream_image=system.bit.bin
 boot_image=BOOT.bin
 boot_size=0xF00000
 bootcmd=run $modeboot
 bootdelay=4
 bootenv=uEnv.txt
 devicetree_image=system.dtb
 devicetree_load_address=0x2000000
 devicetree_size=0x20000
 ethaddr=00:0a:35:00:01:22
 fdt_high=0x20000000
 fdtcontroladdr=3ffa8ed0
 fileaddr=2000000
 filesize=359e
 importbootenv=echo Importing environment from SD ...; env import -t ${loadbootenv_addr} $filesize
 initrd_high=0x20000000
 jtagboot=echo TFTPing Linux to RAM... && tftpboot ${kernel_load_address} ${kernel_image} && tftpboot ${devicetree_load_address} ${devicetree_image} && tftpboot ${ramdisk_load_address} ${ramdisk_image} && bootm ${kernel_load_address} ${ramdisk_load_address} ${devicetree_load_address}
 kernel_image=uImage
 kernel_load_address=0x2080000
 kernel_size=0x500000
 loadbit_addr=0x100000
 loadbootenv=load mmc 0 ${loadbootenv_addr} ${bootenv}
 loadbootenv_addr=0x2000000
 mmc_loadbit=echo Loading bitstream from SD/MMC/eMMC to RAM.. && mmcinfo && load mmc 0 ${loadbit_addr} ${bitstream_image} && fpga load 0 ${loadbit_addr} ${filesize}
 modeboot=sdboot
 nandboot=echo Copying Linux from NAND flash to RAM... && nand read ${kernel_load_address} 0x100000 ${kernel_size} && nand read ${devicetree_load_address} 0x600000 ${devicetree_size} && echo Copying ramdisk... && nand read ${ramdisk_load_address} 0x620000 ${ramdisk_size} && bootm ${kernel_load_address} ${ramdisk_load_address} ${devicetree_load_address}
 norboot=echo Copying Linux from NOR flash to RAM... && cp.b 0xE2100000 ${kernel_load_address} ${kernel_size} && cp.b 0xE2600000 ${devicetree_load_address} ${devicetree_size} && echo Copying ramdisk... && cp.b 0xE2620000 ${ramdisk_load_address} ${ramdisk_size} && bootm ${kernel_load_address} ${ramdisk_load_address} ${devicetree_load_address}
 preboot=if test $modeboot = sdboot && env run sd_uEnvtxt_existence_test; then if env run loadbootenv; then env run importbootenv; fi; fi;
 qspiboot=echo Copying Linux from QSPI flash to RAM... && sf probe 0 0 0 && sf read ${kernel_load_address} 0x100000 ${kernel_size} && sf read ${devicetree_load_address} 0x600000 ${devicetree_size} && echo Copying ramdisk... && sf read ${ramdisk_load_address} 0x620000 ${ramdisk_size} && bootm ${kernel_load_address} ${ramdisk_load_address} ${devicetree_load_address}
 ramdisk_image=uramdisk.image.gz
 ramdisk_load_address=0x4000000
 ramdisk_size=0x5E0000
 rsa_jtagboot=echo TFTPing Image to RAM... && tftpboot 0x100000 ${boot_image} && zynqrsa 0x100000 && bootm ${kernel_load_address} ${ramdisk_load_address} ${devicetree_load_address}
 rsa_nandboot=echo Copying Image from NAND flash to RAM... && nand read 0x100000 0x0 ${boot_size} && zynqrsa 0x100000 && bootm ${kernel_load_address} ${ramdisk_load_address} ${devicetree_load_address}
 rsa_norboot=echo Copying Image from NOR flash to RAM... && cp.b 0xE2100000 0x100000 ${boot_size} && zynqrsa 0x100000 && bootm ${kernel_load_address} ${ramdisk_load_address} ${devicetree_load_address}
 rsa_qspiboot=echo Copying Image from QSPI flash to RAM... && sf probe 0 0 0 && sf read 0x100000 0x0 ${boot_size} && zynqrsa 0x100000 && bootm ${kernel_load_address} ${ramdisk_load_address} ${devicetree_load_address}
 rsa_sdboot=echo Copying Image from SD to RAM... && load mmc 0 0x100000 ${boot_image} && zynqrsa 0x100000 && bootm ${kernel_load_address} ${ramdisk_load_address} ${devicetree_load_address}
 sd_uEnvtxt_existence_test=test -e mmc 0 /uEnv.txt
 sdboot=if mmcinfo; then run uenvboot; echo Copying Linux from SD to RAM... && load mmc 0 ${kernel_load_address} ${kernel_image} && load mmc 0 ${devicetree_load_address} ${devicetree_image} && load mmc 0 ${ramdisk_load_address} ${ramdisk_image} && bootm ${kernel_load_address} ${ramdisk_load_address} ${devicetree_load_address}; fi
 stderr=serial@e0001000
 stdin=serial@e0001000
 stdout=serial@e0001000
 uenvboot=if run loadbootenv; then echo Loaded environment from ${bootenv}; run importbootenv; fi; if test -n $uenvcmd; then echo Running uenvcmd ...; run uenvcmd; fi
 usbboot=if usb start; then run uenvboot; echo Copying Linux from USB to RAM... && load usb 0 ${kernel_load_address} ${kernel_image} && load usb 0 ${devicetree_load_address} ${devicetree_image} && load usb 0 ${ramdisk_load_address} ${ramdisk_image} && bootm ${kernel_load_address} ${ramdisk_load_address} ${devicetree_load_address}; fi
 
 Environment size: 4395/131068 bytes

起動方法を細かく指定しないとダメみたい?

printenv の結果から見ると、

LANG:sh
bootcmd=run $modeboot
modeboot=sdboot
sdboot=if mmcinfo; then \
    run uenvboot; \
    echo Copying Linux from SD to RAM... && 
    load mmc 0 ${kernel_load_address} ${kernel_image} && 
    load mmc 0 ${devicetree_load_address} ${devicetree_image} && 
    load mmc 0 ${ramdisk_load_address} ${ramdisk_image} && 
    bootm ${kernel_load_address} ${ramdisk_load_address} ${devicetree_load_address}; \
  fi
uenvboot=if run loadbootenv; then \
    echo Loaded environment from ${bootenv}; \
    run importbootenv; \
  fi; \
  if test -n $uenvcmd; then \
    echo Running uenvcmd ...; \ 
    run uenvcmd; \
  fi
loadbootenv= \
    load mmc 0 ${loadbootenv_addr} ${bootenv}
importbootenv= \
    echo Importing environment from SD ...; \
    env import -t ${loadbootenv_addr} $filesize

これを z-turn に付いてきた SD Card の uEnv.txt と比べる。

bootargs=console=ttyPS0,115200 root=/dev/mmcblk0p2 rw earlyprintk rootfstype=ext4 rootwait devtmpfs.mount=0
load_image=fatload mmc 0 ${kernel_load_address} ${kernel_image} && fatload mmc 0 ${devicetree_load_address} ${devicetree_image}
uenvcmd=run mmc_loadbit_fat && echo Copying Linux from SD to RAM... && mmcinfo &&  run load_image &&  bootm ${kernel_load_address} - ${devicetree_load_address}

z-turn の SD Card で起動したときの環境変数は、

LANG:console
zynq-uboot> printenv
 baudrate=115200
 bitstream_image=system.bit.bin
 boot_image=BOOT.bin
 boot_size=0x080000
 bootcmd=run $modeboot
 bootdelay=3
 bootenv=uEnv.txt
 devicetree_image=devicetree.dtb
 devicetree_load_address=0x2000000
 devicetree_size=0x010000
 ethact=Gem.e000b000
 ethaddr=00:0a:35:00:01:22
 fdt_high=0x20000000
 importbootenv=echo Importing environment from SD ...; env import -t ${loadbootenv_addr} $filesize
 initrd_high=0x20000000
 ipaddr=192.168.1.55
 jtagboot=echo TFTPing Linux to RAM... && tftpboot ${kernel_load_address} ${kernel_image} && tftpboot ${devicetree_load_address} ${devicetree_image} && tftpboot ${ramdisk_load_address} ${ramdisk_image} && bootm ${kernel_load_address} ${ramdisk_load_address} ${devicetree_load_address}
 kernel_image=uImage
 kernel_load_address=0x2080000
 kernel_size=0x480000
 loadbit_addr=0x100000
 loadbootenv=fatload mmc 0 ${loadbootenv_addr} ${bootenv}
 loadbootenv_addr=0x2000000
 mmc_loadbit_fat=echo Loading bitstream from SD/MMC/eMMC to RAM.. && get_bitstream_name && mmcinfo && fatload mmc 0 ${loadbit_addr} ${bitstream_image} && fpga loadb 0 ${loadbit_addr} ${filesize}
 modeboot=sdboot
 nandboot=echo Copying Linux from NAND flash to RAM... && nand read ${kernel_load_address} 0x100000 ${kernel_size} && nand read ${devicetree_load_address} 0x600000 ${devicetree_size} && echo Copying ramdisk... && nand read ${ramdisk_load_address} 0x620000 ${ramdisk_size} && bootm ${kernel_load_address} ${ramdisk_load_address} ${devicetree_load_address}
 norboot=echo Copying Linux from NOR flash to RAM... && cp.b 0xE2100000 ${kernel_load_address} ${kernel_size} && cp.b 0xE2600000 ${devicetree_load_address} ${devicetree_size} && echo Copying ramdisk... && cp.b 0xE2620000 ${ramdisk_load_address} ${ramdisk_size} && bootm ${kernel_load_address} ${ramdisk_load_address} ${devicetree_load_address}
 qboot_addr=0x000000
 qbootenv_addr=0x080000
 qbootenv_size=0x020000
 qdevtree_addr=0x980000
 qkernel_addr=0x500000
 qramdisk_addr=0x990000
 qspiboot=echo Copying Linux from QSPI flash to RAM... && sf probe 0 0 0 && qspi_get_bitsize 0x0A0000 && sf read ${loadbit_addr} 0x0A0004 ${bitsize} && fpga loadb 0 ${loadbit_addr} ${bitsize} && sf read ${kernel_load_address} ${qkernel_addr} ${kernel_size} && sf read ${devicetree_load_address} ${qdevtree_addr} ${devicetree_size} && echo Copying ramdisk... && sf read ${ramdisk_load_address} ${qramdisk_addr} ${ramdisk_size} && bootm ${kernel_load_address} ${ramdisk_load_address} ${devicetree_load_address}
 qspiupdate=echo Update qspi images from sd card... && echo - Init mmc... && mmc rescan && echo - Init qspi flash... && sf probe 0 0 0 && echo - Write boot.bin... && fatload mmc 0 0x200000 boot.bin && sf erase ${qboot_addr} ${boot_size} && sf erase ${qbootenv_addr} ${qbootenv_size} && sf write 0x200000 0 ${filesize} && get_bitstream_name && echo - Write ${bitstream_image}... && fatload mmc 0 0x200000 ${bitstream_image} && sf erase 0x0A0000 0x460000 && mw.l 0x100000 ${filesize} && sf write 0x100000 0x0A0000 4 && sf write 0x200000 0x0A0004 ${filesize} && echo - Write uImage... && fatload mmc 0 0x200000 uImage && sf erase ${qkernel_addr} ${kernel_size} && sf write 0x200000 ${qkernel_addr} ${filesize} && echo - Write device tree... && fatload mmc 0 0x200000 devicetree.dtb && sf erase ${qdevtree_addr} ${devicetree_size} && sf write 0x200000 ${qdevtree_addr} ${filesize} && echo - Write Ramdisk... && fatload mmc 0 0x200000 uramdisk.image.gz && sf erase ${qramdisk_addr} ${ramdisk_size} && sf write 0x200000 ${qramdisk_addr} ${filesize} && echo - Done.
 ramdisk_image=uramdisk.image.gz
 ramdisk_load_address=0x4000000
 ramdisk_size=0x600000
 rsa_jtagboot=echo TFTPing Image to RAM... && tftpboot 0x100000 ${boot_image} && zynqrsa 0x100000 && bootm ${kernel_load_address} ${ramdisk_load_address} ${devicetree_load_address}
 rsa_nandboot=echo Copying Image from NAND flash to RAM... && nand read 0x100000 0x0 ${boot_size} && zynqrsa 0x100000 && bootm ${kernel_load_address} ${ramdisk_load_address} ${devicetree_load_address}
 rsa_norboot=echo Copying Image from NOR flash to RAM... && cp.b 0xE2100000 0x100000 ${boot_size} && zynqrsa 0x100000 && bootm ${kernel_load_address} ${ramdisk_load_address} ${devicetree_load_address}
 rsa_qspiboot=echo Copying Image from QSPI flash to RAM... && sf probe 0 0 0 && sf read 0x100000 0x0 ${boot_size} && zynqrsa 0x100000 && bootm ${kernel_load_address} ${ramdisk_load_address} ${devicetree_load_address}
 rsa_sdboot=echo Copying Image from SD to RAM... && fatload mmc 0 0x100000 ${boot_image} && zynqrsa 0x100000 && bootm ${kernel_load_address} ${ramdisk_load_address} ${devicetree_load_address}
 sdboot=if mmcinfo; then run uenvboot; get_bitstream_name && echo - load ${bitname} to PL... && fatload mmc 0 0x200000 ${bitname} && fpga loadb 0 0x200000 ${filesize} && echo Copying Linux from SD to RAM... && fatload mmc 0 ${kernel_load_address} ${kernel_image} && fatload mmc 0 ${devicetree_load_address} ${devicetree_image} && fatload mmc 0 ${ramdisk_load_address} ${ramdisk_image} && bootm ${kernel_load_address} ${ramdisk_load_address} ${devicetree_load_address}; fi
 serverip=192.168.1.13
 stderr=serial
 stdin=serial
 stdout=serial
 uenvboot=if run loadbootenv; then echo Loaded environment from ${bootenv}; run importbootenv; fi; if test -n $uenvcmd; then echo Running uenvcmd ...; run uenvcmd; fi
 usbboot=if usb start; then run uenvboot; echo Copying Linux from USB to RAM... && fatload usb 0 ${kernel_load_address} ${kernel_image} && fatload usb 0 ${devicetree_load_address} ${devicetree_image} && fatload usb 0 ${ramdisk_load_address} ${ramdisk_image} && bootm ${kernel_load_address} ${ramdisk_load_address} ${devicetree_load_address}; fi
 
 Environment size: 5720/131068 bytes

こちらでは u-boot コンソールを抜けた後に uEnv.txt が読まれる。 どうしてだろう?

とりあえず置いておいて、

LANG:sh
bootcmd=run $modeboot
modeboot=sdboot
sdboot= \
  if mmcinfo; then \
    run uenvboot; \
    get_bitstream_name && \
    echo - load ${bitname} to PL... && \
    fatload mmc 0 0x200000 ${bitname} && \
    fpga loadb 0 0x200000 ${filesize} && \
    echo Copying Linux from SD to RAM... && \
    fatload mmc 0 ${kernel_load_address} ${kernel_image} && \
    fatload mmc 0 ${devicetree_load_address} ${devicetree_image} && \
    fatload mmc 0 ${ramdisk_load_address} ${ramdisk_image} && \
    bootm ${kernel_load_address} ${ramdisk_load_address} ${devicetree_load_address}; \
  fi
uenvboot= \
  if run loadbootenv; then \
    echo Loaded environment from ${bootenv}; \
    run importbootenv; \
  fi; \
  if test -n $uenvcmd; then \
    echo Running uenvcmd ...; \
    run uenvcmd; \
  fi
loadbootenv= \
  fatload mmc 0 ${loadbootenv_addr} ${bootenv}
importbootenv= \
  echo Importing environment from SD ...; \
  env import -t ${loadbootenv_addr} $filesize
# 以下は uEnv.txt 内
uenvcmd= \
  run mmc_loadbit_fat && \
  echo Copying Linux from SD to RAM... && \
  mmcinfo &&  \
  run load_image && \
  bootm ${kernel_load_address} - ${devicetree_load_address}
load_image= \
  fatload mmc 0 ${kernel_load_address} ${kernel_image} && \
  fatload mmc 0 ${devicetree_load_address} ${devicetree_image}
# 以下再び uEnv.txt 外
mmc_loadbit_fat= \
  echo Loading bitstream from SD/MMC/eMMC to RAM.. && \
  get_bitstream_name && \
  mmcinfo && \
  fatload mmc 0 ${loadbit_addr} ${bitstream_image} && \
  fpga loadb 0 ${loadbit_addr} ${filesize}

なので、

LANG:sh
    get_bitstream_name && \
    echo - load ${bitname} to PL... && \
    fatload mmc 0 0x200000 ${bitname} && \
    fpga loadb 0 0x200000 ${filesize} && \

の部分が追加されている以外、uEnv.txt が呼ばれるまでのところに違いは無い。

uEnv.txt は importbootenv で取り込まれて、uenvcmd が起動されるので、 uenvcmd 内で bootm を呼んでそれ以降の処理(ramdisk の読み込みを含む)を キャンセルしてしまえば良いみたい。そして、ramdisk を使わない場合、 bootm の ramdisk アドレスには - を渡せばいいみたい。

上記の理解を確かめるために u-boot のコマンドラインで

LANG:console
Zynq> get_bitstream_name
 Unknown command 'get_bitstream_name' - try 'help'
Zynq> setenv bootargs console=ttyPS1,115200 root=/dev/mmcblk0p2 rw earlyprintk rootfstype=ext4 devtmpfs.mount=0
Zynq> bootm ${kernel_load_address} - ${devicetree_load_address}

としたところ、Linux が起動した。
これは、すでに uImage と system.dtb がメモリに読み込まれていたため。
uenvcmd を自分で書く場合には、上記と同様にこれらの読み込みも必要になる。

u-boot のコマンドラインで get_bitstream_name が失敗するのはなぜだろう?

今の設定では bitstream が BOOT.BIN に含まれてしまっているのだけれど、 実際には VFAT 上に単独ファイルとして置きたいところ。z-turn 付属の SD カードではそのようになっている。

試しに、design_1_wrapper_0.bit を design1.bit として SD カードに入れ、

LANG:console
Zynq> fatload mmc 0 0x200000 design1.bit
 reading design1.bit
 4045676 bytes read in 275 ms (14 MiB/s)
Zynq> fpga loadb 0 0x200000 ${filesize}
   design filename = "design_1_wrapper;UserID=0XFFFFFFFF;Version=2014.4"
   part number = "7z020clg400"
   date = "2015/08/11"
   time = "17:59:43"
   bytes in bitstream = 4045564
 zynq_align_dma_buffer: Align buffer at 200070 to 200000(swap 1)

としたところ、正しくプログラムできることがわかった。

あれ?いやいや、Linux が立ち上がったっぽいけど sshd が起動しておらず、 コンソールも ttyPS0 を見に行ってしまっているらしく繋がらないので、 本当に起動しているか確認できてない感じ。

inittab の設定

LANG:console
$ sudo mount /dev/sdf2 /mnt/sdcard2
$ sudo jed /mnt/sdcard2/etc/inittab
  # /etc/inittab: init(8) configuration.
  # $Id: inittab,v 1.91 2002/01/25 13:35:21 miquels Exp $
  
  # The default runlevel.
  id:5:initdefault:
  
  # Boot-time system configuration/initialization script.
  # This is run first except when booting in emergency (-b) mode.
  si::sysinit:/etc/init.d/rcS
  
  # What to do in single-user mode.
  ~~:S:wait:/sbin/sulogin
  
  # /etc/init.d executes the S and K scripts upon change
  # of runlevel.
  #
  # Runlevel 0 is halt.
  # Runlevel 1 is single-user.
  # Runlevels 2-5 are multi-user.
  # Runlevel 6 is reboot.
  
  l0:0:wait:/etc/init.d/rc 0
  l1:1:wait:/etc/init.d/rc 1
  l2:2:wait:/etc/init.d/rc 2
  l3:3:wait:/etc/init.d/rc 3
  l4:4:wait:/etc/init.d/rc 4
  l5:5:wait:/etc/init.d/rc 5
  l6:6:wait:/etc/init.d/rc 6
  # Normally not reached, but fallthrough in case of emergency.
  z6:6:respawn:/sbin/sulogin
- PS0:12345:respawn:/bin/start_getty 115200 ttyPS0
+ PS1:12345:respawn:/bin/start_getty 115200 ttyPS1
  # /sbin/getty invocations for the runlevels.
  #
  # The "id" field MUST be the same as the last
  # characters of the device (after "tty").
  #
  # Format:
  #  <id>:<runlevels>:<action>:<process>
  #
  
- 1:12345:respawn:/sbin/getty 38400 tty1
+ #1:12345:respawn:/sbin/getty 38400 tty1
$ sudo umount /dev/sdf2

としたところ、無事ターミナルが起動した。

改めて uEnv.txt

ファイル名をなるべくデフォルトに合わせることにして、

  • ビットストリームを system.bit.bin
  • デバイスツリーを devicetree.dtb

と名前を変えれば、uEnv.txt は

LANG:sh
bootargs=console=ttyPS1,115200 root=/dev/mmcblk0p2 rw earlyprintk rootfstype=ext4 devtmpfs.mount=0
uenvcmd=run mmc_loadbit_fat && echo Copying Linux from SD to RAM... && mmcinfo && run load_image && bootm ${kernel_load_address} - ${devicetree_load_address}
load_image=fatload mmc 0 ${kernel_load_address} ${kernel_image} && fatload mmc 0 ${devicetree_load_address} ${devicetree_image}
mmc_loadbit_fat=echo Loading ${bitstream_image} to PL... && mmcinfo && fatload mmc 0 ${loadbit_addr} ${bitstream_image} && fpga loadb 0 ${loadbit_addr} ${filesize}

でいいみたい。

BOOT.BIN から .bit ファイルを取り除く

起動時に

In FsblHookBeforeBitstreamDload function

でかなり待たされるのも気になる。

というか、今の形だと fsbl 内でビットストリームをダウンロードしちゃってる。

LANG:console
$ petalinux-package --boot --fsbl ../design_1_wrapper_hw_platform_1/fsbl.elf --u-boot --force

として、BOOT.BIN に .bit ファイルを入れないようにしたところ、 待ち時間も無く u-boot が起動して、上記の fatload & fpga loadb でプログラムできることがわかった。

起動しないときがある

どうも動作が安定しません。。。

うまく行かないときの起動ログ:

LANG:console
ALSA device list:
  No soundcards found.
VFS: Cannot open root device "mmcblk0p2" or unknown-block(0,0): error -6
Please append a correct "root=" boot option; here are the available partitions:
0100           16384 ram0  (driver?)
mmc0: new high speed SDHC card at address b368
0101           16384 ram1  (driver?)
0102           16384 ram2 mmcblk0: mmc0:b368 SD08G 7.42 GiB

 (driver?)
 mmcblk0: p1 p2
...

b300         7776256 mmcblk0  driver: mmcblk
  b301          131072 mmcblk0p1 d720fb16-01
  b302         7644160 mmcblk0p2 d720fb16-02
Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)

うまく行く場合は、

LANG:console
ALSA device list:
mmc0: new high speed SDHC card at address b368
  No soundcards found.
mmcblk0: mmc0:b368 SD08G 7.42 GiB
 mmcblk0: p1 p2
EXT4-fs (mmcblk0p2): recovery complete
EXT4-fs (mmcblk0p2): mounted filesystem with ordered data mode. Opts: (null)
VFS: Mounted root (ext4 filesystem) on device 179:2.

なので、

mmc0: new high speed SDHC card at address b368

の前にマウントしようとしているのがいけないみたい。

かなり悩んだあげく uEnv.txt の bootargs に rootwait を入れたところ、直った。
http://might1976.doorblog.jp/tag/rootwait

LANG:console
$ cat /boot/uEnv.txt
 bootargs=console=ttyPS1,115200 root=/dev/mmcblk0p2 noinitrd rw rootwait earlyprintk rootfstype=ext4 devtmpfs.mount=0 uio_pdrv_genirq.of_id=generic-uio
 uenvcmd=run mmc_loadbit_fat && echo Copying Linux from SD to RAM... && mmcinfo && run load_image && bootm ${kernel_load_address} - ${devicetree_load_address}
 load_image=fatload mmc 0 ${kernel_load_address} ${kernel_image} && fatload mmc 0 ${devicetree_load_address} ${devicetree_image}
 mmc_loadbit_fat=echo Loading ${bitstream_image} to PL... && mmcinfo && fatload mmc 0 ${loadbit_addr} ${bitstream_image} && fpga loadb 0 ${loadbit_addr} ${filesize}

カーネルをソースから make

カーネルの設定を変えるには、標準的には

LANG:console
$ petalinux-config -c kernel

でいけるのだけれど、これだと一々ものすごく時間がかかるので、
(petalinux-project-dir)/build/tmp/work-shared/plnx_arm/kernel-source/
に残るソースファイルを使って手動でビルドしたいところ。

上記ディレクトリで make すると、.config が無いと言われる。

で、探してみると
(petalinux-project-dir)/build/tmp/work-shared/plnx_arm/kernel-build-artifacts/
に .config やら何やらがある。

どうやって使ったらいいだろう???

上記 (petalinux-project-dir)/build/tmp/work-shared/plnx_arm/kernel-source/* と
(petalinux-project-dir)/build/tmp/work-shared/plnx_arm/kernel-build-artifacts/.config とを

~/z-turn/kernel-source/ にコピーしてビルドしてみる。

LANG:console
$ cd ~/z-turn
$ cp -R build/tmp/work-shared/plnx_arm/kernel-source/ .
$ cp build/tmp/work-shared/plnx_arm/kernel-build-artifacts/.config kernel-source/
$ git add -f kernel-source/.config
$ echo "/kernel-source" >> .gitignore
$ git commit -m "kernel: petalinux's default config"
$ cd kernel-source/
$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf-
   CHK     include/config/kernel.release
   CHK     include/generated/uapi/linux/version.h
   CHK     include/generated/utsrelease.h
 make[1]: 'include/generated/mach-types.h' は更新済みです.
   CHK     include/generated/bounds.h
   CHK     include/generated/timeconst.h
 /bin/sh: 1: bc: not found
 Kbuild:66: ターゲット 'include/generated/timeconst.h' のレシピで失敗しました
 make[1]: *** [include/generated/timeconst.h] エラー 127
 Makefile:1002: ターゲット 'prepare0' のレシピで失敗しました
 make: *** [prepare0] エラー 2
$ sudo apt-get install bc
$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- UIMAGE_LOADADDR=0x8000 uImage
   CC      drivers/char/xilinx_devcfg.o
 In file included from include/linux/printk.h:6:0,
                  from include/linux/kernel.h:13,
                  from include/linux/list.h:8,
                  from include/linux/kobject.h:20,
                  from include/linux/cdev.h:4,
                  from drivers/char/xilinx_devcfg.c:12:
 drivers/char/xilinx_devcfg.c: In function 'xdevcfg_write':
 include/linux/kern_levels.h:4:18: warning: too many arguments for format [-Wformat-extra-args]
  #define KERN_SOH "\001"  /* ASCII Start Of Header */
                   ^
 include/linux/kern_levels.h:10:18: note: in expansion of macro 'KERN_SOH'
  #define KERN_ERR KERN_SOH "3" /* error conditions */
                   ^
 include/linux/printk.h:252:9: note: in expansion of macro 'KERN_ERR'
   printk(KERN_ERR pr_fmt(fmt), ##__VA_ARGS__)
          ^
 drivers/char/xilinx_devcfg.c:423:5: note: in expansion of macro 'pr_err'
      pr_err("Bitstream does not match the device\n",
      ^
$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- modules

ビルドできた。

./kernel-source/arch/arm/boot/uImage を SD カードにコピーしたところ、 ちゃんと起動することを確認。

以降は、

LANG:console
$ make ARCH=arm menuconfig
$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- UIMAGE_LOADADDR=0x8000 uImage
$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- modules
$ sudo make ARCH=arm INSTALL_MOD_PATH=/mnt/sdcard2 modules_install
$ sudo make ARCH=arm INSTALL_MOD_PATH=/mnt/sdcard2 firmware_install

で設定&ビルド&インストールできる。

ルートファイルシステムのカスタマイズ

上のようにして作った SD カードで起動した場合、

LANG:console
$ uname -a
 Linux plnx_arm 4.6.0-xilinx #1 SMP PREEMPT Thu Feb 23 17:42:19 JST 2017 armv7l GNU/Linux
$ ls -F /lib/modules/4.6.0-xilinx/
 kernel/              modules.builtin.bin  modules.order
 modules.alias        modules.dep          modules.softdep
 modules.alias.bin    modules.dep.bin      modules.symbols
 modules.builtin      modules.devname      modules.symbols.bin
$ ls /lib/firmware
 ls: /lib/firmware: No such file or directory

となりました。

LANG:console
$ petalinux-config -c rootfs

とするとこのファイルシステムに含めるパッケージを選択できるようだけれど 一々ここまで戻らないと必要なパッケージを追加できないのは困るのと、 そもそも個人的に使い慣れた Debian 系 OS にした方がいろいろはかどりそうなのとで、 まるっと入れ替えてしまうことに。

やり方は 電気回路/z-turn/Linuxの設定 と同様ですが、ここでは libmetal 用に libhugetlbfs が必要なので、Ubuntu 16.04 を入れました。

VirtualBox 内の Ubuntu から、

LANG:console
$ sudo apt-get install qemu-user-static debootstrap binfmt-support
$ export targetdir=~/z-turn/rootfs
$ export distro=xenial
$ mkdir -p $targetdir
$ sudo debootstrap --arch=armhf --foreign $distro $targetdir
$ sudo cp /usr/bin/qemu-arm-static $targetdir/usr/bin
$ sudo cp /etc/resolv.conf $targetdir/etc
$ sudo chroot $targetdir
LANG:console
$ export distro=xenial
$ export LANG=C
$ /debootstrap/debootstrap --second-stage
$ cat << EOT > /etc/apt/sources.list
 # http://ascii.jp/elem/000/000/441/441502/index-3.html によれば、
 #   main が Canonical によりメンテナンスされているオープンソースウェア
 #   restricted が Canonical によりメンテナンスされているクローズウェア
 #   universe が オープンソースウェア
 #   multiverse が オープンソースでないもの
deb http://ports.ubuntu.com/ubuntu-ports/ $distro main restricted universe multiverse
deb http://ports.ubuntu.com/ubuntu-ports/ $distro-backports main restricted universe multiverse
deb http://ports.ubuntu.com/ubuntu-ports/ $distro-security main restricted universe multiverse
deb http://ports.ubuntu.com/ubuntu-ports/ $distro-updates main restricted universe multiverse
EOT
$ cat > /etc/apt/apt.conf.d/71-no-recommends
APT::Install-Recommends "0";
APT::Install-Suggests "0";
^D
$ apt-get update
$ apt-get install locales dialog
$ dpkg-reconfigure locales
 Generating locales (this might take a while)...
   en_US.UTF-8... done
   ja_JP.UTF-8... done
 Generation complete.
$ apt-get install etckeeper  # /etc 以下の更新履歴を取る
$ apt-get dist-upgrade
$ apt-get install openssh-server ntpdate hwinfo ntp samba jed aptitude dbus ca-certificates
$ apt-get install build-essential device-tree-compiler cmake doxygen libsysfs-dev libhugetlbfs-dev
$ cat /etc/network/interfaces
 # interfaces(5) file used by ifup(8) and ifdown(8)
 # Include files from /etc/network/interfaces.d:
 source-directory /etc/network/interfaces.d
$ cat << EOT > /etc/network/interfaces.d/eth0-dhcp
 allow-hotplug eth0
 iface eth0 inet dhcp
 EOT
$ echo xenial-zynq > /etc/hostname
$ echo "127.0.0.1    xenial-zynq" >> /etc/hosts
$ echo "/dev/mmcblk0p1  /boot auto  defaults   0   0" >> /etc/fstab
$ adduser osamu
$ adduser osamu sudo
 Adding user `osamu' to group `sudo' ...
 Adding user osamu to group sudo
 Done.
$ su osamu
$ groups
 osamu sudo
$ exit
$ jed /etc/samba/smb.conf
   [global]
 +    # プリンタ関連の警告が出ないようにする
 +    printing = bsd
 +    load printers = no
 +    printcap name = /dev/null
   ...
   [homes]
   ...
 -    read only = yes
 +    # ホームディレクトリを書き込み可能にする
 +    read only = no
   ...
 + # /boot 以下を共有する
 + [boot]
 +    path = /boot
 +    force group = root
 +    force user = root
 +    create mode = 600
 +    directory mode = 755
 +    valid user = osamu
 +    writable = yes
$ # samba インストール前に作られた既存ユーザーについては
$ # 別途 samba に登録してやる必要がある
$ pdbedit -a -u osamu
 new password:
 retype new password:
$ exit
LANG:console
$ sudo mount /dev/sdf2 /mnt/sdcard2/
$ sudo cp -a ~/z-turn/rootfs/* /mnt/sdcard2/
$ sudo umount /dev/sdf2

Ubuntu の場合、手作業で inittab にシリアルポート番号を指定しなくても ちゃんと ttyPS1 にログインシェルを開いてくれました。

dbus がインストールされていなかった

LANG:console
$ sudo shutdown 0
 Failed to connect to bus: そのようなファイルやディレクトリはありません
$ sudo apt-get install dbus
$ sudo shutdown 0

これで問題なくシャットダウンできるようになった。

そのほか入れておきたいもの

LANG:console
$ sudo apt-get install bash-completion

簡易まとめ

最終的な SD カードの構成と、 それぞれの生成方法をまとめる。

  • /dev/mmcblk0p1
    • BOOT.BIN : petalinux-package --boot --fsbl ../design_1_wrapper_hw_platform_1/fsbl.elf --u-boot --force
      • fsbl.elf : z-turn 付属のプロジェクトから vivado で作成
      • u-boot.elf : petalinux-build -c u-boot
    • uEnv.txt : テキストエディタで作成
    • system.bit.bin : vivado で作成
    • devicetree.dtb : テキストエディタで作成
    • uImage : カーネルソースをコンパイル
  • /dev/mmcblk0p2
    • / : Ubuntu 16.04
    • /lib/modules/4.6.0-xilinx/ : カーネルソースからインストール
    • /lib/firmware/ : カーネルソースからインストール

全手順

もう一度はじめから、全手順を確認してみます。

LANG:console
$ cd ~/z-turn
$ mv zturn-v2016.4 zturn-v2016.4_backup
$ petalinux-setup
$ petalinux-create -t project --template zynq -n zturn-v2016.4
$ cd zturn-v2016.4
$ git init
$ cat <<EOT > .gitignore
> .petalinux
> /build
> /images
> /components
> /BOOT.BIN
> *~
> *.old
> EOT
$ git add .
$ git commit -m "newly created"
$ petalinux-config --get-hw-description=../design_1_wrapper_hw_platform_1/
 Linux Components Selection --->
   [Uncheck] First Stage Bootloaer
 Auto Config Settings --->
   [Uncheck] fsbl autoconfig
 Subsystem AUTO Hardware Settings --->
   Advanced bootable images storage Settings --->
     kernel image settings --->
       image storage media --->
         primary sd
     dtb image settings --->
       image storage media --->
         primary sd
 Image Packaging Configuration --->
   Root filesystem type --->
     SD card
   [Uncheck] Copy final images to tftpboot
 u-boot Configuration --->
   U-boot config --->  
     other
 Yocto Settings --->
   Parallel thread execution --->
     BB_NUMBER_THREADS = 4
     PARALLEL_MAKE = 4
$ petalinux-config -c u-boot
 Boot images --->
   [Uncheck] Support Flattened Image Tree
 Boot media --->
   [Check] Support for booting from SD/EMMC
 Networking support --->
   [Uncheck] all
 Device Drivers --->
   [Uncheck] Ethernet PHY support
$ mkdir -p images/linux/
$ petalinux-package --image -c kernel --format uImage
 WARNING: /home/osamu/z-turn/petalinux/components/yocto/source/arm/layers/meta-xilinx/recipes-bsp/u-boot/u-boot-xlnx_2016.07.bb.do_compile is tainted from a forced run
 NOTE: Tasks Summary: Attempted 1793 tasks of which 1378 didn't need to be rerun and all succeeded.
 
 Summary: There was 1 WARNING message shown.
$ ls images/linux
 uImage
$ ls build/tmp/deploy/images/plnx_arm/
 modules-plnx_arm.tgz
 plnx_arm-system.dtb
 plnx_arm-system.dts
 u-boot.bin
 u-boot.elf
 uImage
 ...
$ cp build/tmp/deploy/images/plnx_arm/u-boot.elf images/linux/
$ petalinux-package --boot --fsbl ../design_1_wrapper_hw_platform_1/fsbl.elf --u-boot --force
$ rm BOOT.BIN
$ cp build/tmp/deploy/images/plnx_arm/plnx_arm-system.dtb images/linux/devicetree.dtb
$ cp ../design_1_wrapper_hw_platform_1/design_1_wrapper.bit images/linux/system.bit.bin
$ cat > images/linux/uEnv.txt
bootargs=console=ttyPS0,115200 root=/dev/mmcblk0p2 rw rootwait earlyprintk rootfstype=ext4 devtmpfs.mount=0 rootwait
uenvcmd=run mmc_loadbit_fat && echo Copying Linux from SD to RAM... && mmcinfo && run load_image &&  bootm ${kernel_load_address} - ${devicetree_load_address}
load_image=fatload mmc 0 ${kernel_load_address} ${kernel_image} && fatload mmc 0 ${devicetree_load_address} ${devicetree_image}
mmc_loadbit_fat=echo Loading ${bitstream_image} to PL... && mmcinfo && fatload mmc 0 ${loadbit_addr} ${bitstream_image} && fpga loadb 0 ${loadbit_addr} ${filesize}
^D
$ ls images/linux
 BOOT.BIN  devicetree.dtb  system.bit.bin  u-boot.elf  uEnv.txt  uImage  zynq_fsbl.elf
$ git add .
$ git commit -m "起動可能になった"
  • u-boot の confiture をしないと image.ub を読みに行ってしまいます
  • mkdir -p images/linux/ をしないと uImage などがコピーできないというエラーが出ます
  • BOOT.BIN, devicetree.dtb, system.bit.bin, uEnv.txt, uImage を SD カードの第1パーティション(FAT32 でフォーマット)にコピーします

以下、カーネルソースをコンパイル可能な形にコピーし、設定後、ビルド&インストールする手順

LANG:console
$ cp -R build/tmp/work-shared/plnx_arm/kernel-source/ .
$ cp build/tmp/work-shared/plnx_arm/kernel-build-artifacts/.config kernel-source/
$ cd kernel-source/
$ make ARCH=arm menuconfig
$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- UIMAGE_LOADADDR=0x8000 uImage modules
$ cp arch/arm/boot/uImage ../images/linux
$ sudo make ARCH=arm INSTALL_MOD_PATH=~/z-turn/rootfs modules_install
$ sudo make ARCH=arm INSTALL_MOD_PATH=~/z-turn/rootfs firmware_install

SD カードを直接更新するには

LANG:console
$ sudo mount /dev/sdf1 /mnt/sdcard1
$ sudo mount /dev/sdf2 /mnt/sdcard2
$ sudo cp arch/arm/boot/uImage /mnt/sdcard1/
$ sudo make ARCH=arm INSTALL_MOD_PATH=/mnt/sdcard2 modules_install
$ sudo make ARCH=arm INSTALL_MOD_PATH=/mnt/sdcard2 firmware_install
$ sudo umount /mnt/sdcard*

カーネル設定

General setup --->
  Cross-compiler tool prefix = arm-linux-gnueabihf-
  [Uncheck] Initial RAM filesystem and RAM disk (initramfs/initrd) support
Bus support --->
  [Uncheck] PCI support
Kernel Features --->
  Maximum number of CPUs = 2
Power management options --->
  [Uncheck] Suspend to RAM and standby
  [Uncheck] Device power management core functionality
Device Drivers --->
  Generic Driver Options --->
    [ ] Prevent firmware from being built 
    Default contiguous memory area size
      Size in Mega Bytes = 64
  Device Tree and Open Firmware support --->
    [Check] Device Tree overlays 
  SCSI device support --->
    [Uncheck] SCSI device support
  Input device support --->
    [Uncheck] Mice 
  Character devices --->
    <M> Xillybus generic FPGA interface
    <M>   Xillybus over Device Tree
  I2C support --->
    I2C Hardware Bus support --->
      <M> Xilinx I2C Controller
  SPI support --->
    <M>   Xilinx SPI controller common module
    <M>   Xilinx Zynq QSPI controller
    [*]     Xilinx Zynq QSPI Dual stacked configuration
  GPIO Support --->
    I2C GPIO expanders --->
      <M> PCA95[357]x, PCA9698, TCA64xx, and MAX7310 I/O ports
  <M> Sound card support
  HID support --->
    <M>   Generic HID driver
    Special HID drivers --->
      <M> Microsoft non-fully HID-compliant devices
    USB HID support --->
      <M> USB HID transport layer
  USB support --->
    <M>   Support for Host-side USB
    <M>   USB Gadget Support
  Userspace I/O drivers --->
   <M>   Userspace platform driver with generic irq and dynamic memory
  FPGA Configuration Support --->
    <M> FPGA Configuration Framework
    <M>   Xilinx Zynq FPGA

arch/arm/boot/Image のサイズは

  • petalinux のデフォルト設定で 9640864
  • ramdisk, PCI bus, Power management, SCSI support を消したところ 9617760
    全然変わらない(^^;
    しかも mmcblk0p2 をマウントできなくなりました? → 後にこれは bootargs に rootwait が足りなかったせいと判明
  • 調べるの面倒なので、削除する方向はなしにして、必要なものを追加することにします。
  • 下記をすべて追加したところ 9636832 になりました。あれ?減ってる???
General setup --->
  Cross-compiler tool prefix = arm-linux-gnueabihf-
Device Drivers --->
  Generic Driver Options --->
    [ ] Prevent firmware from being built 
    Default contiguous memory area size
      Size in Mega Bytes = 64
  Device Tree and Open Firmware support --->
    [Check] Device Tree overlays 
  Character devices --->
    <M> Xillybus generic FPGA interface
    <M>   Xillybus over Device Tree
  I2C support --->
    I2C Hardware Bus support --->
      <M> Xilinx I2C Controller
  SPI support --->
    <M>   Xilinx SPI controller common module
    <M>   Xilinx Zynq QSPI controller
    [*]     Xilinx Zynq QSPI Dual stacked configuration
  GPIO Support --->
    I2C GPIO expanders --->
      <M> PCA95[357]x, PCA9698, TCA64xx, and MAX7310 I/O ports
  <M> Sound card support
  HID support --->
    <M>   Generic HID driver
    Special HID drivers --->
      <M> Microsoft non-fully HID-compliant devices
    USB HID support --->
      <M> USB HID transport layer
  USB support --->
    <M>   Support for Host-side USB
    <M>   USB Gadget Support
  Userspace I/O drivers --->
   <M>   Userspace platform driver with generic irq and dynamic memory
  FPGA Configuration Support --->
    <M> FPGA Configuration Framework
    <M>   Xilinx Zynq FPGA

Counter: 34455 (from 2010/06/03), today: 1, yesterday: 0