开发GUI 便宜好用的ARM 不多见了,f1c100s 作为首选,搜索相关spinand 启动支持 的uboot 帖子大多相当久远,随着uboot的升级 已经支持spinand 启动,但是spl 部分支持任然需要查询相关资料才行;
参考该博主文章,已经写的非常清楚了,但是有一些细节处理不好可能无法从spl 跳转到 uboot 中去
F1C100s支持从SPI-NAND启动了,顺便说下如何向 U-Boot SPL 添加一个Image Loader - IotaHydrae - 博客园 (cnblogs.com)
这里我采用uboot2023.01 地址 ftp.denx.de,测试发现小于该版本则spinand 无法支持 并且dts 设备树没有spi 节点,大于 该版本则编译 python 出错 凡是遇到python 却库或者版本对不上的很难弄 ;
将spl_spi_nand_sunxi.c 放入arch/arm/mach-sunxi/ 后,选择 MTD 支持:
勾选 mtd 命令
加入设备树支持:
&spi0 {pinctrl-names = "default";pinctrl-0 = <&spi0_pc_pins>;status = "okay";flash@0 {#address-cells = <1>;#size-cells = <1>;//compatible = "winbond,w25q128", "jedec,spi-nor";compatible = "spi-nand";reg = <0>;spi-max-frequency = <50000000>;};
};
保存,编译之 ;得到 u-boot-sunxi-with-spl.bin ,准备一张TF 卡,将之烧入,并且格式化为FAT 格式 方便烧入 spinand 中 ;
dd if=u-boot-sunxi-with-spl.bin of=/dev/sdx bs=1024 seek=8
由于spinand 页大小2K ,启动的spl 加载是1K 页加载,则需要把u-boot-sunxi-with-spl.bin 的spl部分打包为1K 页:用到脚本 gen_sunxi_spinand_onlyboot_img.sh 如下 :
#!/usr/bin/env bash
#
# Copyright (C) 2019 Benedikt-Alexander Mokroß (iCOGNIZE GmbH)
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#set -ex
[ $# -eq 4 ] || [ $# -eq 6 ] || {echo "SYNTAX: $0 <outputfile> <u-boot image> <nand page size> <nand block size in KiB> [<spl copies> <u-boot copies>]"echo "Given: $@"exit 1
}OUTPUT="$1"
UBOOT="$2"
PAGESIZE="$3"
BLOCKSIZE="$4"
SPLCOPIES="0"
UBOOTCOPIES="0"[ $# -eq 6 ] && {SPLCOPIES=$(($5 - 1))UBOOTCOPIES=$(($6 - 1))
}# SPL-Size is an uint32 at 16 bytes offset contained in the SPL header
SPLSIZE=$(od -An -t u4 -j16 -N4 "$UBOOT" | xargs)
# The u-boot size is at offset 12 (4. 32-bit int) from the start of u-boot, which is padded 0x2000 bytes (observed) after the SPL
UBOOTSIZE=$(od --endian=big -An -t u4 -j $(($SPLSIZE + 8192 + 12)) -N4 "$UBOOT" | xargs)ALIGNCHECK=$(($PAGESIZE%1024))
if [ "$ALIGNCHECK" -ne "0" ]; thenecho "Page-size is not 1k alignable and thus not supported by EGON"exit -1
fiKPAGESIZE=$(($PAGESIZE/1024))
SPLBLOCKS=$(($SPLSIZE/1024))
LOOPSPLBLOCKS=$(($SPLBLOCKS-1))
SPLENTRYSTEPS=$(($KPAGESIZE * 32))
TOTALSPLSIZE=$((($SPLENTRYSTEPS * $SPLCOPIES) + $SPLBLOCKS))
NEXTPEB=$(($TOTALSPLSIZE + $BLOCKSIZE - ($TOTALSPLSIZE % $BLOCKSIZE)))
UBOOTPEBS=$((($UBOOTSIZE/1024) + $BLOCKSIZE - ($UBOOTSIZE/1024) % $BLOCKSIZE))echo "$@" > $OUTPUT.imgmeta
echo "SPL-size $SPLSIZE">> $OUTPUT.imgmeta
echo "u-boot-size $UBOOTSIZE">> $OUTPUT.imgmeta
echo "block-size 1 KiB" >> $OUTPUT.imgmeta
echo "Page-size $KPAGESIZE KiB">> $OUTPUT.imgmeta
echo "PEB-size $BLOCKSIZE KiB">> $OUTPUT.imgmeta
echo "SPL-count $(($SPLCOPIES + 1))">> $OUTPUT.imgmeta
echo "u-boot-count $(($UBOOTCOPIES + 1))">> $OUTPUT.imgmeta
printf "SPL-entry-steps 0x%x\n" $(($SPLENTRYSTEPS*1024))>> $OUTPUT.imgmeta
echo "SPL-blocks $TOTALSPLSIZE">> $OUTPUT.imgmeta
echo "u-boot-block $UBOOTPEBS">> $OUTPUT.imgmeta
echo "first-u-boot $NEXTPEB">> $OUTPUT.imgmeta
echo "## Layout ##">> $OUTPUT.imgmeta# The BROM of the SUNXI is only able to load 1k per page from SPI-NAND
# Thus, even if we have an 2k or 4k page-size, we have to chunk the SPL in 1k pieces
#
# Entry-Pages:
# 32, 64, 96, 128, 160, 192, 224
# 1k: 0x8000, 0x10000, 0x18000 0x20000, 0x28000, 0x30000, 0x38000
# 2k: 0x10000, 0x20000, 0x30000, 0x40000, 0x50000, 0x60000, 0x70000
# 4K: 0x20000, 0x40000, 0x60000, 0x80000, 0xA0000, 0xC0000, 0xE0000
# 8K: 0x40000, 0x80000, 0xC0000, 0x100000, 0x140000, 0x180000, 0x1C0000echo "Generating 0-image for boot part of size $SPLSIZE ($SPLBLOCKS blocks)"
dd if="/dev/zero" of="$OUTPUT" bs=1024 count=$(($SPLBLOCKS * ($SPLCOPIES + 1)))for splcopy in `seq 0 $SPLCOPIES`;
doecho "SPL Copy $splcopy"printf "spl-%u 0x%x\n" $splcopy $(($SPLENTRYSTEPS * $splcopy * 1024)) >> $OUTPUT.imgmetaecho "Copying block 0 to $(($SPLENTRYSTEPS * $splcopy))"dd if="$UBOOT" of="$OUTPUT" bs=1024 count=2 seek=$(($SPLENTRYSTEPS * $splcopy)) skip=0 conv=notruncfor from in `seq 1 $LOOPSPLBLOCKS`;doto=$((($SPLENTRYSTEPS * $splcopy) + ($from*$KPAGESIZE)))echo "Copying block $from to $to"dd if="$UBOOT" of="$OUTPUT" bs=1024 count=1 seek=$to skip=$from conv=notruncdonedone# it was observed, that u-boot is padded 0x2000 behind the spl. so add 0x2000 (= 8192 -> 8x1024k blocks) to the splsize to get the uboot-entry
for ubootcopy in `seq 0 $UBOOTCOPIES`;
doecho "Appending u-boot to chunked SPL at block $(($NEXTPEB + ($UBOOTPEBS * $ubootcopy))) (origin: $SPLBLOCKS)"dd if="$UBOOT" of="$OUTPUT" bs=1024 seek=$(($NEXTPEB + ($UBOOTPEBS * $ubootcopy))) skip=$(($SPLBLOCKS + 8)) conv=notruncprintf "u-boot-%u 0x%x\n" $ubootcopy $((($NEXTPEB + ($UBOOTPEBS * $ubootcopy)) * 1024)) >> $OUTPUT.imgmeta
done
使用如下,将uboot 打包为 spinand 烧录文件
./gen_sunxi_spinand_onlyboot_img.sh u-boot-sunxi-spinand.bin u-boot-sunxi-with-spl.bin 2048 128
将文件 u-boot-sunxi-spinand.bin 烧写到 TF卡 第一个 FAT 分区下,方便下一步
启动后首先应该加载的TF 卡uboot ,进入uboot 后输入命令 mtd list ,可以扫描到 spinand
接下来 使用mtd命令 加载 uboot 到 spinand 中 :
完成后断电 ,取下TF 卡 可以看到能从spinand 启动;不过遇到的新的问题,那就是 启动后卡在了 SPL
使用bin查看器 查看uboot-sunxi-spinand.bin :
这里uboot 的位置 在 8192 ,也就是 8192*16 = 0x2000 的位置 ,查看uboot menuconfig 地址偏移设置 :
将该地址设置为0x20000 ,重新编译,打包spinand烧录文件,烧写启动如下 :