SDカードのブート部分についてまとめておく
SDカードイメージ
atlas_sdcard_v1.1.img
FATのファイルリスト
.
├── ATLAS_SOC_GHRD
│ ├── output_files
│ │ ├── ATLAS_SOC_GHRD.rbf -- FPGAイメージ
│ │ └── ATLAS_SOC_GHRD.sof -- rbfのソース.なくても起動する
│ ├── preloader-mkpimage.bin -- preloader?なくても起動する
│ ├── soc_system.dtb -- devicetree??
│ ├── soc_system.dts -- soc_system.dtbのソース
│ └── u-boot.img -- u-bootバイナリ
├── boot.script -- u-boot.scrのソース.なくても起動する
├── u-boot.scr -- u-bootの起動スクリプト
├── zImage -- linuxカーネル
└── zImage-socfpga_cyclone5_de0_sockit.dtb -- devicetree
ファイルごとに消しても起動するかをやってみると、以下のファイルだけあれば起動するようだ
.
├── ATLAS_SOC_GHRD
│ ├── output_files
│ │ ├── ATLAS_SOC_GHRD.rbf -- FPGAイメージ
│ └── u-boot.img -- u-bootバイナリ
├── u-boot.scr -- u-bootの起動スクリプト
├── zImage -- linuxカーネル
└── zImage-socfpga_cyclone5_de0_sockit.dtb -- devicetree
u-bootブートスクリプトの内容
echo ---Booting ATLAS SOC GHRD---
echo ---Programming FPGA---
# Load rbf from FAT partition into memory
fatload mmc 0:1 $fpgadata ATLAS_SOC_GHRD/output_files/ATLAS_SOC_GHRD.rbf;
# Program FPGA
fpga load 0 $fpgadata $filesize;
echo ---Setting Env variables---
# Set the devicetree image to be used
setenv fdtimage zImage-socfpga_cyclone5_de0_sockit.dtb;
# Set the kernel image to be used
setenv bootimage zImage;
# enable the FPGA 2 HPS and HPS 2 FPGA bridges
run bridge_enable_handoff;
echo ---Generating MAC Address---
setenv chipid_addr 0xff207000;
chipid2mac;
echo ---Booting Linux---
# mmcload & mmcboot are scripts included in the default socfpga uboot environment
# it loads the devicetree image and kernel to memory
run mmcload;
# mmcboot sets the bootargs and boots the kernel with the dtb specified above
run mmcboot;
起動の仕組み
Embedded Linux Beginners GuideによるとSDカードのパーティションは以下になっていて
Partition3に一番最初に呼ばれるpreloaderがかかれている。中身はrawなのでファイルとして見えるわけではない。
次にPartition1のFAT32のファイルシステムから
u-boot.img
が読み込まれ、u-bootが起動する。起動ログの中で
reading ATLAS_SOC_GHRD/u-boot.img
とあるように、パスがpreloaderにかかれているようだ。u-boot.imgをルートに移動したりすると起動しない。
u-bootが起動するとboot.scriptから変換されたブートスクリプトu-boot.scrが読み込まれ実行される。boot.scriptの内容を見ると
- ATLAS_SOC_GHRD/output_files/ATLAS_SOC_GHRD.rbf をFPGAに焼く
- zImage-socfpga_cyclone5_de0_sockit.dtb をデバイスツリーに指定
- zImage をカーネルに指定
- bridge_enable_handoffを実行
- chip idからMACアドレスを設定
- linuxをブート
という処理がされていることが分かる。
bridge_enable_handoffって何だ?デフォルトの環境変数で指定されているようだ。u-bootのデフォルト環境変数は以下になっていた
axibridge=ffd0501c
axibridge_handoff=0x00000000
baudrate=115200
bootargs=console=ttyS0,115200
bootcmd=run callscript; run mmcload; run mmcboot
bootdelay=5
bootimage=zImage
bootimagesize=0x600000
bridge_disable=mw $fpgaintf 0; mw $fpga2sdram 0; go $fpga2sdram_apply; mw $axibridge 0; mw $l3remap 0x1
bridge_enable_handoff=mw $fpgaintf ${fpgaintf_handoff}; go $fpga2sdram_apply; mw $fpga2sdram ${fpga2sdram_handoff}; mw $axibridge ${axibridge_handoff}; mw $l3remap ${l3remap_handoff}
callscript=if fatload mmc 0:1 $fpgadata $scriptfile;then source $fpgadata; else echo Optional boot script not found. Continuing to boot normally; fi;
ethact=mii0
fdtaddr=0x00000100
fdtimage=socfpga.dtb
fdtimagesize=0x7000
fpga=0
fpga2sdram=ffc25080
fpga2sdram_apply=3ff79550
fpga2sdram_handoff=0x00000311
fpgadata=0x2000000
fpgadatasize=0x700000
fpgaintf=ffd08028
fpgaintf_handoff=0x00000000
l3remap=ff800000
l3remap_handoff=0x00000019
loadaddr=0x8000
micrel-ksz9021-clk-skew=0xf0f0
micrel-ksz9021-data-skew=0x0
mmcboot=setenv bootargs console=ttyS0,115200 root=${mmcroot} rw rootwait;bootz ${loadaddr} - ${fdtaddr}
mmcload=mmc rescan;${mmcloadcmd} mmc 0:${mmcloadpart} ${loadaddr} ${bootimage};${mmcloadcmd} mmc 0:${mmcloadpart} ${fdtaddr} ${fdtimage}
mmcloadcmd=fatload
mmcloadpart=1
mmcroot=/dev/mmcblk0p2
nandboot=setenv bootargs console=ttyS0,115200 root=${nandroot} rw rootfstype=${nandrootfstype};bootz ${loadaddr} - ${fdtaddr}
nandbootimageaddr=0x120000
nandfdtaddr=0xA0000
nandload=nand read ${loadaddr} ${nandbootimageaddr} ${bootimagesize};nand read ${fdtaddr} ${nandfdtaddr} ${fdtimagesize}
nandroot=/dev/mtdblock1
nandrootfstype=jffs2
netboot=dhcp ${bootimage} ; tftp ${fdtaddr} ${fdtimage} ; run ramboot
qspiboot=setenv bootargs console=ttyS0,115200 root=${qspiroot} rw rootfstype=${qspirootfstype};bootz ${loadaddr} - ${fdtaddr}
qspibootimageaddr=0xa0000
qspifdtaddr=0x50000
qspiload=sf probe ${qspiloadcs};sf read ${loadaddr} ${qspibootimageaddr} ${bootimagesize};sf read ${fdtaddr} ${qspifdtaddr} ${fdtimagesize};
qspiloadcs=0
qspiroot=/dev/mtdblock1
qspirootfstype=jffs2
ramboot=setenv bootargs console=ttyS0,115200;bootz ${loadaddr} - ${fdtaddr}
scriptfile=u-boot.scr
setenv_ethaddr_eeprom=3ff9ad25
soc_board_name=ATLAS_SOC_GHRD
stderr=serial
stdin=serial
stdout=serial
verify=n
変数が入れ子になってるので読み解くのが大変。
u-boot.scrの作り方
ファイル変換の方法は以下のようにやるとできる
mkimage -A arm -O linux -T script -C none -a 0 -e 0 -n "My script" -d boot.script u-boot.scr
参考
わかったこと
- FATにu-boot,FPGAイメージ,カーネルが入ってる
- u-bootスクリプトでいろいろやってる(HPSの初期化やmacアドレス設定)
- u-bootでFPGAが書き込まれている
- soc_system.dtbデバイスツリーは使われていない。なんで?
- chip idからMACアドレスを設定されている。0xff207000にchip idを置いておこう