0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

MPFS-DISCO-KIT 向け Ubuntu 22.04 の構築(U-Boot 標準編)

Last updated at Posted at 2024-12-17

はじめに

MPFS-DISCO-KIT(Microchip PolarFire SoC FPGA Discovery Kit) で動作する Ubuntu 22.04 を構築する方法をいくつかの記事に分けて説明します。

上記の記事で構築した MPFS-DISCO-KIT 向け Ubuntu 22.04 Root File System、Linux Kernel、Boot Loader は次の URL にて公開しています。なお、これらはオフシャルなものではなく、筆者の魔改造がはいっています。ご使用の際はこの点にご留意してください。

この記事では、Microchip Technology 社が提供する U-Boot (u-boot-mchp) のビルドについて解説します。
なお、この記事で紹介した U-boot のビルド済みのファイル(uboot.imd、uboot.env、boot.scr) は以下の URL にあります。ビルドが面倒な方はどうぞ。

ダウンロード

u-boot-mchp

Microchip Technology 社が提供する U-Boot は、以下の URL にあります。

この記事では、linux4microchip+fpga-2024.09 というタグのついたものを使用するので、ダウンロードしておきます。

shell$ git clone --depth 1 --branch linux4microchip+fpga-2024.09 https://github.com/linux4microchip/u-boot-mchp.git u-boot-mchp-fpga-2024.09

meta-polarfire-soc-yocto-bsp

上記のリポジトリの他に、meta-polarfire-soc-yocto-bsp からビルドの際に必要なファイルをダウンロードしておきます。必要なファイルの詳細な説明は後述します。

必要なのは、recipes-bsp/u-boot/files/mpfs-disco-kit/ の中身です。./files あたりにコピーしておきます。

shell$ git clone --depth 1 --branch v2024.09 https://github.com/polarfire-soc/meta-polarfire-soc-yocto-bsp.git meta-polarfire-soc-yocto-bsp-v2024.09
shell$ cp -r meta-polarfire-soc-yocto-bsp-v2024.09/meta-polarfire-soc-bsp/recipes-bsp/u-boot/files/mpfs-disco-kit/ ./files

hart-software-services

最終的に HSS からブートするためには、HSS(Hart Software Services)編 で紹介した HSS Payload Generator が必要です。HSS Payload Generator は以下の URL にあります。必要に応じてダウンロードしておきます。

shell$ git clone --depth 1 --branch v2024.09 https://github.com/polarfire-soc/hart-software-services.git hart-software-services-v2024.09

ファイルの説明

今回は u-boot-mchp を単純に make するだけではなく、meta-polarfire-soc-yocto-bsp から幾つかファイルを追加してカスタマイズしています。ここではこれらのファイルの説明をします。

mpfs-disco-kit.cfg

u-boot-mchp についてくる microchip_mpfs_discokit_defconfig(MPFS-DISCO-KIT 用の def_config)に加えて、あらたに変更&追加するコンフィギュレーションです。

files/mpfs-disco-kit.cfg
CONFIG_MPFS_PRIORITISE_QSPI_BOOT=n
CONFIG_ENV_IS_NOWHERE=n
CONFIG_ENV_IS_IN_FAT=y
CONFIG_ENV_FAT_INTERFACE="mmc"
CONFIG_ENV_FAT_DEVICE_AND_PART="0:1"
CONFIG_ENV_FAT_FILE="uboot.env"

主に u-boot が最初に設定する環境変数に関する変更点が記述されています。
u-boot は起動後に環境変数を設定するのですが、環境変数を外部ファイルから読むことを指定しています。
ここでは、アクセスするファイルシステムを FAT に、デバイスを mmc に、ドライブを 0 に、パーティションを 1 に、ファイル名を uboot.env にしています。

uEnv.txt

前述した uboot.env のソースコードです。uEnv.txt を mkenvimage というツールを使って uboot.env に変換します。

uEnv.txt (長いので折りたたみ)
files/uEnv.txt
arch=riscv
baudrate=115200
board=mpfs_discokit
board_name=mpfs_discokit
boot_a_script=load ${devtype} ${devnum}:${distro_bootpart} ${scriptaddr} ${prefix}${script}; source ${scriptaddr}
boot_efi_binary=load ${devtype} ${devnum}:${distro_bootpart} ${kernel_addr_r} efi/boot/bootriscv64.efi; if fdt addr -q ${fdt_addr_r}; then bootefi ${kernel_addr_r} ${fdt_addr_r};else bootefi ${kernel_addr_r} ${fdtcontroladdr};fi
boot_efi_bootmgr=if fdt addr -q ${fdt_addr_r}; then bootefi bootmgr ${fdt_addr_r};else bootefi bootmgr;fi
boot_extlinux=sysboot ${devtype} ${devnum}:${distro_bootpart} any ${scriptaddr} ${prefix}${boot_syslinux_conf}
boot_prefixes=/ /boot/
boot_script_dhcp=boot.scr.uimg
boot_scripts=boot.scr.uimg boot.scr
boot_syslinux_conf=extlinux/extlinux.conf
boot_targets= mmc0 dhcp
bootcmd=run distro_bootcmd
bootcmd_dhcp=devtype=dhcp; if dhcp ${scriptaddr} ${boot_script_dhcp}; then source ${scriptaddr}; fi;setenv efi_fdtfile ${fdtfile}; setenv efi_old_vci ${bootp_vci};setenv efi_old_arch ${bootp_arch};setenv bootp_vci PXEClient:Arch:00027:UNDI:003000;setenv bootp_arch 0x1b;if dhcp ${kernel_addr_r}; then tftpboot ${fdt_addr_r} dtb/${efi_fdtfile};if fdt addr -q ${fdt_addr_r}; then bootefi ${kernel_addr_r} ${fdt_addr_r}; else bootefi ${kernel_addr_r} ${fdtcontroladdr};fi;fi;setenv bootp_vci ${efi_old_vci};setenv bootp_arch ${efi_old_arch};setenv efi_fdtfile;setenv efi_old_arch;setenv efi_old_vci;
bootcmd_mmc0=devnum=0; run mmc_boot
bootdelay=2
bootm_size=0x10000000
cpu=mpfs
design_overlays=if test -n ${no_of_overlays}; then setenv inc 1; setenv idx 0; fdt resize ${dtbo_size}; while test $idx -ne ${no_of_overlays}; do setenv dtbo_name dtbo_image${idx}; setenv fdt_cmd "fdt apply $"$dtbo_name; run fdt_cmd; setexpr idx $inc + $idx; done; fi;
distro_bootcmd=for target in ${boot_targets}; do run bootcmd_${target}; done
efi_dtb_prefixes=/ /dtb/ /dtb/current/
fdt_addr_r=0x8a000000
fdtoverlay_addr_r=0x8a080000
kernel_addr_r=0x80200000
load_efi_dtb=load ${devtype} ${devnum}:${distro_bootpart} ${fdt_addr_r} ${prefix}${efi_fdtfile}
loadaddr=0x80200000
mmc_boot=if mmc dev ${devnum}; then devtype=mmc; run scan_dev_for_boot_part; fi
mtdparts=mtdparts=spi-nand0:2m(payload),128k(env),119m(rootfs)
ramdisk_addr_r=0x8aa00000
scan_dev_for_boot=echo Scanning ${devtype} ${devnum}:${distro_bootpart}...; for prefix in ${boot_prefixes}; do run scan_dev_for_extlinux; run scan_dev_for_scripts; done;run scan_dev_for_efi;
scan_dev_for_boot_part=part list ${devtype} ${devnum} -bootable devplist; env exists devplist || setenv devplist 1; for distro_bootpart in ${devplist}; do if fstype ${devtype} ${devnum}:${distro_bootpart} bootfstype; then part uuid ${devtype} ${devnum}:${distro_bootpart} distro_bootpart_uuid ; run scan_dev_for_boot; fi; done; setenv devplist
scan_dev_for_efi=setenv efi_fdtfile ${fdtfile}; for prefix in ${efi_dtb_prefixes}; do if test -e ${devtype} ${devnum}:${distro_bootpart} ${prefix}${efi_fdtfile}; then run load_efi_dtb; fi;done;run boot_efi_bootmgr;if test -e ${devtype} ${devnum}:${distro_bootpart} efi/boot/bootriscv64.efi; then echo Found EFI removable media binary efi/boot/bootriscv64.efi; run boot_efi_binary; echo EFI LOAD FAILED: continuing...; fi; setenv efi_fdtfile
scan_dev_for_extlinux=if test -e ${devtype} ${devnum}:${distro_bootpart} ${prefix}${boot_syslinux_conf}; then echo Found ${prefix}${boot_syslinux_conf}; run boot_extlinux; echo EXTLINUX FAILED: continuing...; fi
scan_dev_for_scripts=for script in ${boot_scripts}; do if test -e ${devtype} ${devnum}:${distro_bootpart} ${prefix}${script}; then echo Found U-Boot script ${prefix}${script}; run boot_a_script; echo SCRIPT FAILED: continuing...; fi; done
scriptaddr=0x8e000000
vendor=microchip

uEnv.txt では主にブートシーケンスの記述が含まれています。実はこのブートシーケンスは KV260 とほぼ同じです。詳しいブートシーケンスについては以下の記事を参照してください。

最終的に boot_a_script コマンドによりブートデバイスにある boot.scr の実行を試みます。

boot.cmd

前述した boot.scr のソースコードです。boot.cmd を mkimage というツールを使って boot.scr に変換します。

boot.cmd
setenv fdt_high 0xffffffffffffffff
setenv initrd_high 0xffffffffffffffff

load mmc 0:${distro_bootpart} ${scriptaddr} fitImage
bootm start ${scriptaddr};
bootm loados ${scriptaddr};
# Try to load a ramdisk if available inside fitImage
bootm ramdisk;
bootm prep;
fdt set /soc/ethernet@20110000 mac-address ${discokit_mac_addr0};
run design_overlays;
bootm go;

ブートデバイスにある fitImage というファイルをロードしています。fitImage は u-boot で使用される FIT(Flattend Image Tree) というフォーマットのファイルです。このスクリプトでは、ロードした Device Tree になにやら ethernet の MAC Address を上書きしているようです。

uboot.yaml

u-boot.bin を hss-payload-generator を使って uboot.img(HSS からブートできるイメージファイル)に変換する際に使用する設定ファイルです。

uboot.yaml
#
# HSS Payload Generator
#

# First, we can optionally set a name for our image, otherwise one will be created dynamically
set-name: 'PolarFire-SoC-HSS::U-Boot'

#
# Next, we'll define the entry point addresses for each hart, as follows:
#
hart-entry-points: {u54_1: '0x80200000', u54_2: '0x80200000', u54_3: '0x80200000', u54_4: '0x80200000'}

#
# Finally, we'll define some payloads (source ELF files) that will be placed at certain regions in memory
# The payload section is defined with the keyword payloads, and then a number of individual
# payload descriptors.
#
# Each payload has a name (path to its ELF file), an owner-hart, and optionally 1-3 secondary-harts.
#
# Additionally, it has a privilege mode in which it will start execution.
#  * Valid privilege modes are PRV_M, PRV_S and PRV_U.
#
#
# In the following example:
#  * test/baremetal is assumed to be a bare metal application that runs in u54_3,
#    and expects to start in PRV_M
#  * test/u-boot is the Das U-Boot bootloader, and it runs on U54_1, U54_2 and U54_4.
#    It expects to start in PRV_S.
#
# Case only matters for the ELF path names, not the keywords.
#
payloads:
  u-boot.bin: {exec-addr: '0x80200000', owner-hart: u54_1, secondary-hart: u54_2, secondary-hart: u54_3, secondary-hart: u54_4, priv-mode: prv_s}

名前やブートするファイル名や各々の CPU が実行する際のエントリーポイントが記述されています。

ビルド

ディレクトリ構造とファイル

  • files/
    • boot.cmd
    • mpfs-disco-kit.cfg
    • uEnv.txt
    • uboot.yaml
  • u-boot-mchp-fpga-2024.09/
  • hart-software-services-v2024.09/
    • tools/
      • hss-payload-generator/
  • uboot.img (ビルドした成果物)
  • uboot.env (ビルドした成果物)
  • boot.scr (ビルドした成果物)

環境設定

shell$ cd u-boot-mchp-fpga-2024.09
shell$ export CROSS_COMPILE=riscv64-unknown-linux-gnu-

uboot.img のビルド

hss-payload-generator のビルド

あらかじめ hss-payload-generator をビルドしておきます。

shell$ make -C ../hart-software-services-v2024.09/tools/hss-payload-generator/ 

microchip_mpfs_discokit_defconfig のコンフィギュレーション

まずは u-boot-mchp にある microchip_mpfs_discokit_defconfig でコンフィギュレーションします。同時に scripts にある各種ツールもビルドされます。

shell$ make microchip_mpfs_discokit_defconfig
  HOSTCC  scripts/basic/fixdep
  HOSTCC  scripts/kconfig/conf.o
  YACC    scripts/kconfig/zconf.tab.c
  LEX     scripts/kconfig/zconf.lex.c
  HOSTCC  scripts/kconfig/zconf.tab.o
  HOSTLD  scripts/kconfig/conf
#
# configuration written to .config
#

files/mpfs-disco-kit.cfg のマージ

recipes-bsp/u-boot/files/mpfs-disco-kit/mpfs-disco-kit.cfg を .config にマージします。

shell$ ./scripts/kconfig/merge_config.sh .config ../files/mpfs-disco-kit.cfg
Using .config as base
Merging ../files/mpfs-disco-kit.cfg
Value of CONFIG_MPFS_PRIORITISE_QSPI_BOOT is redefined by fragment ../files/mpfs-disco-kit.cfg:
Previous value: CONFIG_MPFS_PRIORITISE_QSPI_BOOT=y
New value: CONFIG_MPFS_PRIORITISE_QSPI_BOOT=n

Value of CONFIG_ENV_IS_NOWHERE is redefined by fragment ../files/mpfs-disco-kit.cfg:
Previous value: CONFIG_ENV_IS_NOWHERE=y
New value: CONFIG_ENV_IS_NOWHERE=n

Value of CONFIG_ENV_IS_IN_FAT is redefined by fragment ../files/mpfs-disco-kit.cfg:
Previous value: # CONFIG_ENV_IS_IN_FAT is not set
New value: CONFIG_ENV_IS_IN_FAT=y

scripts/kconfig/conf  --alldefconfig Kconfig
#
# configuration written to .config
#
Value requested for CONFIG_MPFS_PRIORITISE_QSPI_BOOT not in final .config
Requested value:  CONFIG_MPFS_PRIORITISE_QSPI_BOOT=n
Actual value:     # CONFIG_MPFS_PRIORITISE_QSPI_BOOT is not set

Value requested for CONFIG_ENV_IS_NOWHERE not in final .config
Requested value:  CONFIG_ENV_IS_NOWHERE=n
Actual value:     # CONFIG_ENV_IS_NOWHERE is not set

u-boot.bin のビルド

shell$ make
   :
 (中略)
   :
  LD      u-boot
  OBJCOPY u-boot.srec
  OBJCOPY u-boot-nodtb.bin
  DTC     arch/riscv/dts/microchip-mpfs-disco-kit.dtb
  SHIPPED dts/dt.dtb
  CAT     u-boot-dtb.bin
  COPY    u-boot.bin
  SYM     u-boot.sym
  COPY    u-boot.dtb
  OFCHK   .config

uboot.img に変換

u-boot.bin を hss-payload-generator を使って uboot.img(HSS からブートできるイメージファイル)に変換します。

shell$ ../hart-software-services-v2024.09/tools/hss-payload-generator/hss-payload-generator -c ../files/uboot.yaml -v ../uboot.img

uboot.env

files/uEnv.txt (uboot.env のソースコード)を uboot.env(u-boot が直接扱う環境変数ファイル) に変換します。
その際、u-boot をビルドした際に設定した CONFIG_ENV_SIZE が必要です。

shell$ grep CONFIG_ENV_SIZE .config
CONFIG_ENV_SIZE=0x2000
shell$ export CONFIG_ENV_SIZE=0x2000
shell$ tools/mkenvimage -s $CONFIG_ENV_SIZE ../files/uEnv.txt -o ../uboot.env

boot.scr

files/boot.cmd(boot.scr のソースコード) を boot.scr(u-boot が直接扱うスクリプトファイル) に変換します。

shell$ tools/mkimage -c none -A riscv -T script -d ../files/boot.cmd ../boot.scr
Image Name:   
Created:      Fri Nov 22 15:18:44 2024
Image Type:   RISC-V Linux Script (gzip compressed)
Data Size:    368 Bytes = 0.36 KiB = 0.00 MiB
Load Address: 00000000
Entry Point:  00000000
Contents:
   Image 0: 360 Bytes = 0.35 KiB = 0.00 MiB

参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?