AN889の日記

組込みエンジニアのブログ

【Yocto】Intel 64ビットプロセッサー向けLinuxビルド(meta-intel)

はじめに

Intel 64ビットプロセッサー(x64)向けLinuxをYoctoでビルドする方法です。 meta-intel を使います。

環境構築

$ mkdir path/to/prj
$ mkdir sources
$ cd sources
$ git clone git://git.yoctoproject.org/poky -b kirkstone
$ git clone git://git.openembedded.org/meta-openembedded -b kirkstone
$ git clone git://git.yoctoproject.org/meta-intel -b kirkstone
$ cd ..
$ . ./sources/poky/oe-init-build-env build

設定

build/conf/local.conf
  • MACHINEの設定
MACHINE = "intel-corei7-64"
WKS_FILE = "image-installer.wks.in"
IMAGE_FSTYPES:append = " ext4"
IMAGE_TYPEDEP_wic = "ext4"
INITRD_IMAGE_LIVE = "core-image-minimal-initramfs"
do_image_wic[depends] += "${INITRD_IMAGE_LIVE}:do_image_complete"
do_image_wic[recrdeptask] += "do_image_ext4"
do_rootfs[depends] += "virtual/kernel:do_deploy"
IMAGE_BOOT_FILES:append = " \
${KERNEL_IMAGETYPE} \
    microcode.cpio \
    ${IMGDEPLOYDIR}/${IMAGE_BASENAME}-${MACHINE}.ext4;rootfs.img \
    ${@bb.utils.contains('EFI_PROVIDER', 'grub-efi', 'grub-efi-bootx64.efi;EFI/BOOT/bootx64.efi', '', d)} \
    ${@bb.utils.contains('EFI_PROVIDER', 'grub-efi', '${IMAGE_ROOTFS}/boot/EFI/BOOT/grub.cfg;EFI/BOOT/grub.cfg', '', d)} \
    ${@bb.utils.contains('EFI_PROVIDER', 'systemd-boot', 'systemd-bootx64.efi;EFI/BOOT/bootx64.efi', '', d)} \
    ${@bb.utils.contains('EFI_PROVIDER', 'systemd-boot', '${IMAGE_ROOTFS}/boot/loader/loader.conf;loader/loader.conf ', '', d)} \
    ${@bb.utils.contains('EFI_PROVIDER', 'systemd-boot', '${IMAGE_ROOTFS}/boot/loader/entries/boot.conf;loader/entries/boot.conf', '', d)} \
    "
build/conf/bblayers.conf
  • レシピパスの設定
BBLAYERS ?= " \
      ${TOPDIR}/../sources/poky/meta \
      ${TOPDIR}/../sources/poky/meta-poky \
      ${TOPDIR}/../sources/poky/meta-yocto-bsp \
      ${TOPDIR}/../sources/meta-openembedded/meta-oe \
      ${TOPDIR}/../sources/meta-openembedded/meta-networking \
      ${TOPDIR}/../sources/meta-openembedded/meta-python \
      ${TOPDIR}/../sources/meta-openembedded/meta-filesystems \
      ${TOPDIR}/../sources/meta-openembedded/meta-multimedia \
      ${TOPDIR}/../sources/meta-intel \
      "

ビルド

  • X11 の最小イメージ
$ bitbake core-image-x11
  • SATO デスクトップイメージ
$ bitbake core-image-sato

インストールUSBメモリーの作成

  • X11 の最小イメージ
$ sudo dd if=tmp/deploy/images/intel-corei7-64/core-image-x11-intel-corei7-64.wic of=/dev/sdx status=progress
  • SATO デスクトップイメージ
$ sudo dd if=tmp/deploy/images/intel-corei7-64/core-image-sato-intel-corei7-64.wic of=/dev/sdx status=progress

sdx は環境に合わせて変更ください。
[例]sdc

Windows機ならrufusで作成できます。
Rufus - 起動可能なUSBドライブを簡単に作成できます

ターゲット機のBIOSUEFI)でブートデバイス順序の第1をUSBにして、このUSBメモリーをターゲット機に挿して起動すればインストール開始します。

カスタマイズ

インストール開始までの待ち(タイムアウト)時間変更

デフォルトだと、インストール開始まで5秒待たされます。この待ち時間はsources/meta-intel/wic/image-installer.wks.inで変更できます。
[例]1秒

bootloader --ptable gpt --timeout=1 --append=" rootwait "
インストール処理の変更

インストール処理はsources/poky/meta/recipes-core/initrdscripts/files/init-install-efi.shに記述されています。 インストール処理を変更したい場合はこのファイルを編集ください。

  • [例]インストール先指定に待ち時間を設定
--- sources/poky/meta/recipes-core/initrdscripts/files/init-install-efi.sh.orig      2023-12-26 13:21:42.493604948 +0900
+++ sources/poky/meta/recipes-core/initrdscripts/files/init-install-efi.sh     2023-12-07 09:14:09.962019853 +0900
@@ -101,12 +101,16 @@

 # Get user choice
 while true; do
-    echo "Please select an install target or press n to exit ($hdnamelist ): "
-    read answer
+    echo "Please select an install target or press n to exit ($hdnamelist ), waiting for 5 secs ...: "
+    read -t 5 answer || true
     if [ "$answer" = "n" ]; then
         echo "Installation manually aborted."
         exit 1
     fi
+    if [ -z "$answer" ]; then
+        echo "Default target (sda) selected."
+        answer=sda
+    fi
     for hdname in $hdnamelist; do
         if [ "$answer" = "$hdname" ]; then
             TARGET_DEVICE_NAME=$answer
  • [例]インストール先の強制フォーマット
 @@ -208,7 +212,7 @@
 mkfs.vfat $bootfs

 echo "Formatting $rootfs to ext4..."
-mkfs.ext4 $rootfs
+mkfs.ext4 -F $rootfs

 echo "Formatting swap partition...($swap)"
 mkswap $swap
  • [例]ブートオプションの変更
@@ -274,7 +278,7 @@
     # delete any root= strings
     sed -i "s/ root=[^ ]*/ /" $SYSTEMDBOOT_CFGS
     # add the root= and other standard boot options
-    sed -i "s@options *@options root=PARTUUID=$rootuuid rw $rootwait quiet @" $SYSTEMDBOOT_CFGS
+    sed -i "s@options *@options root=PARTUUID=$rootuuid rw $rootwait @" $SYSTEMDBOOT_CFGS
 fi

 umount /tgt_root
Linuxブートまでの待ち(タイムアウト)時間変更

デフォルトだと、Linuxブートまで10秒待たされます。この待ち時間はbuild/conf/local.confに下記追加で変更できます。
[例]1秒

SYSTEMD_BOOT_TIMEOUT = "1"

【BD-HW51】STBとの予約録画連携の設定

CATV(ケーブルテレビ)のSTB(セットトップボックス)の予約録画設定で録画先をLAN接続したHDDレコーダーにしてますが、ときどき録画失敗してました。録画時間前になるとHDDレコーダーが起動しますが、このときSTBとのLAN接続失敗が原因でした。
私のHDDレコーダーはシャープ製BD-HW51ですが、クイック起動設定がデフォルトの「する(設定2)」のままでした。この設定だと録画時間前に起動しても録画時間までにSTBとLAN接続できませんでした。そこで、設定を「する(設定1)」に変更したところ、録画失敗することなくなりました。

クイック起動設定については取説 操作編のp210に載ってます。

https://jp.sharp/support/av/dvd/doc/bdhw51_ope.pdf

【TRACE32】Infineon製SPIフラッシュS25FLxのレジスター設定

Infineon製SPIフラッシュS25FLxをQSPIで使うにはレジスターでクアッドモードに設定する必要があります。
an889.hatenablog.com

このレジスター設定をローターバッファ社製デバッガーソフトウェアTRACE32でするお話です。

TRACE32でSPIフラッシュを扱う場合、付属のフラッシュプログラムを使います。
プロセッサーがZynqMP(XILINXプロセッサーZynq™ UltraScale+™ MPSoC)の場合です。

FLASHFILE.TARGET 0xFFFC1000++0x2FFF  E:0xFFFC4000++0x27FF ./spiw4b64_zynqultra.bin /KEEP /STACKSIZE 0x400 /DUALPORT
FLASHFILE.TARGET 0xFFFC1000++0x2FFF  E:0xFFFC4000++0x27FF ./spi4b64_zynqultra.bin  /KEEP /STACKSIZE 0x400 /DUALPORT


レジスター設定方法です。

  • デュアルパラレル接続
FLASHFILE.SPI.CMD 0x06 0x06 ; Write Enable
FLASHFILE.SPI.CMD 0x01 0x01 0x00 0x00 0x02 0x02 ; Write <SR1> <SR1> <CR1> <CR1>
FLASHFILE.SPI.CMD 0x04 0x04 ; Write Disable
  • デュアルスタックまたはシングル接続
FLASHFILE.SPI.CMD 0x06 ; Write Enable
FLASHFILE.SPI.CMD 0x01 0x00 0x02 ; Write <SR1> <CR1>
FLASHFILE.SPI.CMD 0x04 ; Write Disable


設定できたかどうかレジスター読出しで確認できます。

  • デュアルパラレル接続
FLASHFILE.SPI.CMD 0x35 0x35 /READ 0x2
  • デュアルスタックまたはシングル接続
FLASHFILE.SPI.CMD 0x35 /READ 0x1


FLASHFILE.SPI.CMDの書式です。

  • デュアルパラレル接続
FLASHFILE.SPI.CMD <cmd for flash_bottom> <cmd for flash_top> <data[0] for flash_bottom> <data[0] for flash_top> <data[1] for flash_bottom> <data[1] for flash_top> ...
  • デュアルスタックまたはシングル接続
    デュアルスタックで上位デバイスの設定はできません。
FLASHFILE.SPI.CMD <cmd> <data[0]> <data[1]> ...


その他注意事項です。

  • FLASHFILE.unlockはCR1(Configuration register 1)を初期化するので、使わないでください。

【U-Boot】ZynqMPでInfineon製SPIフラッシュS25FLxを使うときの注意事項

XILINXプロセッサーZynq™ UltraScale+™ MPSoC(以下、ZynqMP)でInfineon製SPIフラッシュS25FLシリーズ*1を使ったときのことです。
ZynqMPとこのフラッシュとはQSPIデュアルパラレル接続しました*2

QSPIなのでフラッシュをクアッドモードに設定する必要があります。
このフラッシュのU-Bootでのクアッド設定はdrivers/mtd/spi/spi-nor-core.cspansion_read_cr_quad_enable()です。これはspi_nor_init()内で呼ばれます。ところが、クアッド設定に失敗します。

このフラッシュのクアッド設定はCR1[1](Configuration register 1のビット1 QUAD)で行います。工場出荷値は0でクアッド無効です。CR1を設定するにはWRR(Write Register)コマンド0x01を使うのですが、その際のデータ部は2バイトで、データ部の0バイト目をSR1(Status Register 1)のデータ、1バイト目をCR1のデータにします。
このデータ長が2というのが落とし穴でした。デュアルパラレル接続ではストライプでデータをフラッシュへ送信します。偶数バイトを下位フラッシュへ、奇数バイトを上位フラッシュへと *3。なので、0バイト目のSR1のデータが下位フラッシュへ、1バイト目のCR1のデータが上位デバイスへ送信され、下位・上位フラッシュそれぞれにはWRRコマンドがデータ長1になってました(バス波形でも確認)。これではSR1の設定になるので、CR1を設定できません。
なので、WRRコマンド送信時はストライプを無効にする必要があります。ストライプ有効/無効はZynqMPのGQSPI_GEN_FIFOレジスタ*4のビット18で設定します。

そこで、spansion_read_cr_quad_enable()内で呼ばれるwrite_sr_cr()でストライプ設定を無効にすることで、CR1を設定できるようになり、クアッドモードにすることができました。このパッチです。これはv2023.01_2023.1*5用です。v2023.01_2023.2*6ではストライプ設定実装が変わってるので、このパッチは適用できません。

4バイトアドレスモードにするためのset_4byte()も同様の対処必要です。このフラッシュを4バイトアドレスモードにするにはBAR[7](Bank address registerのビット7 EXTADD)を1にする必要ありますが、その設定のBRWR(Bank Register Write)コマンド0x17もストライプ有効だとデータ部が1バイトのため下位デバイスのみに送信されます。この対処もパッチに入れています。

diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c
index cff390b4..b58a4c43 100644
--- a/drivers/mtd/spi/spi-nor-core.c
+++ b/drivers/mtd/spi/spi-nor-core.c
@@ -2108,7 +2108,12 @@ static int write_sr_cr(struct spi_nor *nor, u8 *sr_cr)
 
    write_enable(nor);
 
+   if (nor->isparallel) /* eratta */
+       nor->spi->flags &= ~SPI_XFER_STRIPE;
    ret = nor->write_reg(nor, SPINOR_OP_WRSR, sr_cr, 2);
+   if (nor->isparallel) /* eratta */
+       nor->spi->flags |= SPI_XFER_STRIPE;
+
    if (ret < 0) {
        dev_dbg(nor->dev,
            "error while writing configuration register\n");
@@ -3656,6 +3661,38 @@ static void s25fl256l_default_init(struct spi_nor *nor)
 static struct spi_nor_fixups s25fl256l_fixups = {
    .default_init = s25fl256l_default_init,
 };
+
+static int s25fl512s_post_bfpt_fixup(struct spi_nor *nor,
+                  const struct sfdp_parameter_header *header,
+                  const struct sfdp_bfpt *bfpt,
+                  struct spi_nor_flash_parameter *params)
+{
+   int ret;
+
+   if (nor->isparallel) {
+       /* eratta */
+       nor->spi->flags &= ~SPI_XFER_STRIPE;
+       ret = set_4byte(nor, nor->info, 1);
+       nor->spi->flags |= SPI_XFER_STRIPE;
+   } else if (nor->isstacked) {
+       ret = set_4byte(nor, nor->info, 1);
+       nor->spi->flags |= SPI_XFER_U_PAGE;
+       ret |= set_4byte(nor, nor->info, 1);
+       nor->spi->flags &= ~SPI_XFER_U_PAGE;
+   } else {
+       ret = set_4byte(nor, nor->info, 1);
+   }
+   if (ret)
+       return ret;
+
+   nor->addr_width = 4;
+
+   return 0;
+}
+
+static struct spi_nor_fixups s25fl512s_fixups = {
+   .post_bfpt = s25fl512s_post_bfpt_fixup,
+};
 #endif
 
 #ifdef CONFIG_SPI_FLASH_S28HX_T
@@ -4432,6 +4469,10 @@ void spi_nor_set_fixups(struct spi_nor *nor)
    if (CONFIG_IS_ENABLED(SPI_FLASH_BAR) &&
        !strcmp(nor->info->name, "s25fl256l"))
        nor->fixups = &s25fl256l_fixups;
+
+   if (!CONFIG_IS_ENABLED(SPI_FLASH_BAR) &&
+       !strncmp(nor->info->name, "s25fl512s", 9))
+       nor->fixups = &s25fl512s_fixups;
 #endif
 
 #ifdef CONFIG_SPI_FLASH_MT35XU

【ZynqMP】xqspipsu_generic_flash_interrupt_example.c の修正

XILINX社のSDKであるVitisにはいろいろなサンプルプログラムが同梱されています。 japan.xilinx.com

このうちのQSPIフラッシュテストプログラム embeddedsw/XilinxProcessorIPLib/drivers/qspipsu/examples/xqspipsu_generic_flash_interrupt_example.c at xlnx_rel_v2022.2 · Xilinx/embeddedsw · GitHub
にいけてないところが少しあるので修正しました。

  • FlashEnableQuadMode()
    case SPANSION_ID_BYTE0で、WRITE_ENABLE_CMD 発行前にチップセレクトも兼ねる GetRealAddr() が実行されないので、フラッシュがデュアルパラレルだと上位デバイスへ WRITE_ENABLE_CMD コマンドが発行されません。
    なので、WRITE_ENABLE_CMD 発行前に GetRealAddr() を実行するようにしました。

  • QspiPsuInterruptFlashExample()
    コマンドのデバッグ文が元の位置だと、その後に選択された4バイトモードコマンドが表示されないので、4バイトモードコマンド選択後に移動しました。

--- xqspipsu_generic_flash_interrupt_example.c.orig  2023-10-10 10:28:10.692908400 +0900
+++ xqspipsu_generic_flash_interrupt_example.c    2023-10-17 15:25:32.296358072 +0900
@@ -371,10 +371,6 @@
        FSRFlag = 0;
    }
 
-  xil_printf("ReadCmd: 0x%x, WriteCmd: 0x%x,"
-         "StatusCmd: 0x%x, FSRFlag: %d\n\r",
-         ReadCmd, WriteCmd, StatusCmd, FSRFlag);
-
    if (Flash_Config_Table[FCTIndex].FlashDeviceSize > SIXTEENMB) {
        Status = FlashEnterExit4BAddMode(QspiPsuInstancePtr, ENTER_4B);
        if (Status != XST_SUCCESS) {
@@ -393,6 +389,10 @@
        }
    }
 
+   xil_printf("ReadCmd: 0x%x, WriteCmd: 0x%x,"
+          "StatusCmd: 0x%x, FSRFlag: %d\n\r",
+          ReadCmd, WriteCmd, StatusCmd, FSRFlag);
+
    for (UniqueValue = UNIQUE_VALUE, Count = 0;
            Count < PageSize;
            Count++, UniqueValue++) {
@@ -1986,6 +1986,7 @@
        while (TransferInProgress);
 
        WriteEnableCmd = WRITE_ENABLE_CMD;
+       GetRealAddr(QspiPsuPtr, TEST_ADDRESS);
        /*
         * Send the write enable command to the Flash
         * so that it can be written to, this needs
@@ -2006,8 +2007,6 @@
        }
        while (TransferInProgress);
 
-      GetRealAddr(QspiPsuPtr, TEST_ADDRESS);
-
        WriteBuffer[0] = WRITE_CONFIG_CMD;
        WriteBuffer[1] |= 0x02;
        WriteBuffer[2] |= 0x01 << 1;
@@ -2071,6 +2070,7 @@
        FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
        FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
 
+       memset(ReadBfrPtr, 0xff, sizeof(ReadBfrPtr));
        FlashMsg[1].TxBfrPtr = NULL;
        FlashMsg[1].RxBfrPtr = ReadBfrPtr;
        FlashMsg[1].ByteCount = 1;

【ZynqMP】Linux版XICのプロキシー設定

XILINX社提供のXIC(Xilinx Information Center)は同社SDK(VivadoやVitisなど)のインストール状態を管理するツールですが、これのLinux版の話です。 プロキシー環境下だと毎回起動時にプロキシー設定画面が表示され、いちいちプロキシー設定する必要がありました。

XIC - Change Proxy Settings

なんとかならないかと、XICのインストールディレクトリーを調べると、設定ファイルらしきものがありました。 /opt/Xilinx/xic/tps/lnx64/jre11.0.11_9/conf/net.properties(私は/opt下にインストールしています)です。
このファイルで下記のように設定したところ、設定画面が表示されなくなりました(IPアドレスとポート番号はご自身の環境に合わせて設定ください)。

http.proxyHost=IPアドレス
http.proxyPort=ポート番号
# http.nonProxyHosts=localhost|127.*|[::1]

https.proxyHost=IPアドレス
https.proxyPort=ポート番号

ftp.proxyHost=IPアドレス
ftp.proxyPort=ポート番号
# ftp.nonProxyHosts=localhost|127.*|[::1]

【Yocto】NXP QorIQプロセッサ向け64ビットLinux

NXPのQorIQシリーズのT1024/14プロセッサーは64ビットなので、64ビットLinuxを試しました。 4.19*1は正常に動きました。
4.14*2はSPIフラッシュアクセスでカーネルエラーになります。本家*3のppc64関連のパッチを当てましたがダメでした。

未解決です。