当前位置:首页 > 技术 > LINUX > 正文内容

荔枝派nano(f1c100s)的SPI-Flash系统编译创建全过程

Watrt5年前 (2019-08-11)LINUX61793

前言

本文的目标是创建一个运行在SPI-Flash上的精简系统,附带填一些前人没有提及的坑。在开始之前,请先通读官方教程的即食部分(U-Boot)、Linux编译和SPI-Flash系统的创建部分的教程,并搭建好编译工具链。以下我假设你已经按照上面的教程下载好了U-Boot和Linux内核,并且到Buildroot的官网下载好了Buildroot(但没按教程创建config文件)。

SPI-Flash的分区结构

以下是我这里的分区结构。你可以自由的分配后面两个分区的大小。

ID  SIZE    USAGE   ADDR
0   448kb   U-boot  0x0000 0000 - 0x0007 0000
1   64kb    dtb     0x0007 0000 - 0x0008 0000
2   4mb     kernel  0x0008 0000 - 0x0048 0000
3   7.5mb   rootfs  0x0048 0000 - 0x00c0 0000
4   4mb     overlay 0x00c0 0000 - 0x0100 0000

U-Boot的编译和填坑

按照上面的U-Boot的编译教程来编译基本上是没有什么太大问题。我这里就说一下上面教程里面没有说的配置:

设置内核启动参数

勾上

Enable boot arguments

,然后在下面填上:

panic=5 rootwait root=/dev/mtdblock3 rw rootfstype=squashfs

其中,root=/dev/mtdblock3指定了第3分区为rootfs所在分区,rootfstype=squashfs指定了这个分区的格式是squashfs。

设置Bootcmd

勾上

Enable a default value for bootcmd

,然后在下面填上:

sf probe 0 60000000; sf read 0x80c00000 0x70000 0x10000; sf read 0x80008000 0x80000 0x400000; bootz 0x80008000 - 0x80c00000

0x70000和0x80000分别是分区1和2的起始地址。

减小U-Boot体积

默认配置下,U-Boot的体积是接近1M的,但实际上U-Boot本体才270k左右。多余的空间实际上是被环境配置所占据了。

进入Environment菜单,找到Environment Offset。这个Offset就是配置的偏移地址,只要它比U-Boot本体大就可以了。这里我设置成0x68000,并将Environment Size设置成0x8000,这样编译出来的U-Boot大小就正好是0x70000,也就是448kb。

设置显示输出日志

勾上Console下的 Enable console multiplexing 和 Select console devices from environment,就可以在屏幕上看到启动日志了。

Linux的编译和填坑

Linux的坑就稍微有些多了。在做接下来的东西之前,你最好先载入官方的配置文件。

SPI-Flash的支持

进入 Device Drivers -> SPI support,将 Allwinner A10 SoCs SPI controller取消勾选,然后勾上下面的Allwinner A31 SPI Controller。这是为了修正配置文件中SPI驱动不正确的问题。

勾上并进入 Device Drivers -> Memory Technology Device (MTD) support,选上下面两项:

Command line partitioning table parsing #为了解析内核参数传过来的分区信息,如果用设备树应该可以不选
Caching block device access to MTD devices  #为了生成/dev/mtdblock*设备,不选会报错

取消勾选 General setup -> initramfs support (存疑)。

再进入Filesystem Drivers,选上JFFS2和SquashFS的支持。

然后打开drivers/mtd/spi-nor/spi-nor.c,检查自己的flash型号的参数是否含有SECT_4K,如果有则改为0。例如对于w25q128,需要将

{ "w25q128", INFO(0xef4018, 0, 64 * 1024, 256, SECT_4K) },

改为

{ "w25q128", INFO(0xef4018, 0, 64 * 1024, 256, 0) }

最后修改设备树文件中的分区信息,可以参考前面官方教程里面的dts修改章节。

flash@0 {
    #address-cells = <1>;
    #size-cells = <1>;
    compatible = "macronix,mx25l12805d", "jedec,spi-nor";
    reg = <0>;
    spi-max-frequency = <50000000>;
    partitions {
      compatible = "fixed-partitions";
      #address-cells = <1>;
      #size-cells = <1>;
      partition@0 {
        label = "u-boot";
        reg = <0x000000 0x70000>;
        read-only;
      };
      partition@70000 {
        label = "dtb";
        reg = <0x70000 0x10000>;
        read-only;
      };
      partition@80000 {
        label = "kernel";
        reg = <0x80000 0x400000>;
        read-only;
      };
      partition@480000 {
        label = "rootfs";
        reg = <0x480000 0x780000>;
      };
      
      partition@c00000 {
        label = "overlayfs";
        reg = <0xc00000 0x400000>;
      };
    };
  };

USB Gadget的支持

为了方便调试,需要启用USB Gadget。

转到 Device Driver -> USB support -> USB Gadget support,勾上 Usb gadget functions configurable through configfs,和上面的Serial gadget console support,以及下面的CDC ACM、CDC ECM、RNDIS、FunctionFS,再取消USB Gadget precomposed configurations的勾选。(具体原因和操作方法可以看我前面的文章)

对文件drivers/clk/sunxi-ng/ccu-suniv.c应用下面这个补丁,修正USB驱动问题

--- ../linux/drivers/clk/sunxi-ng/ccu-suniv.c    2019-01-15 22:48:18.824587965 +0800
+++ drivers/clk/sunxi-ng/ccu-suniv.c    2019-01-23 09:05:17.959348454 +0800
@@ -238,7 +238,7 @@
/* The BSP header file has a CIR_CFG, but no mod clock uses this definition */
static SUNXI_CCU_GATE(usb_phy0_clk,    "usb-phy0",    "osc24M",
-              0x0cc, BIT(8), 0);
+              0x0cc, BIT(1), 0);
static SUNXI_CCU_GATE(dram_ve_clk,    "dram-ve",    "pll-ddr",
              0x100, BIT(0), 0);

Wifi支持

我这里用的是rtl8723bs,所以在drivers->staging里面启用相关的驱动就可以了。

Buildroot的使用和rootfs的编译

下载Buildroot后解压,不要使用官方的配置文件,应当自己从零开始编译。

基础设置

Target options
  -- Target Architecture (ARM (little endian))
  -- Target Variant arm926t
Toolchain
  -- C library (musl) # 使用musl减小最终体积
System configuration
  -- Use syslinks to /usr .... # 启用/bin, /sbin, /lib的链接
  -- Enable root login # 启用root登录
  -- Run a getty after boot # 启用登录密码输入窗口
  -- remount root filesystem # 重新挂载根文件系统到可读写
  -- Install Timezone info # 安装时区信息。我的程序需要所以就打开了这个玩意
     -- timezone list (asia)
     -- default local time (Asia/Shanghai)
Target Packages
  -- mount/umount # 如果要用overlayfs,那就要用这个挂载

网络部分软件包

这里我给出包名然后自己搜素就好了

ifupdown scripts

iw # 用做无线网络管理的,可不要

wpa_supplicant # 无线网络管理需要这个玩意

linux-firmware -> rtl87xx # 无线网卡的固件

其他可能需要的软件包

lrzsz # rz/sz命令,用于传输文件

gawk # 用于解析iw命令的输出

dialog # 用于wifish管理的图形界面的生成

Busybox的设置

有一些软件包在busybox内是自带的,可以到使用busybox的menuconfig进行配置。需要先运行一次make生成busybox的构建文件夹,然后再使用 make busybox-menuconfig 配置。每次clean后都需要重新配置一次,因为在clean的时候这个配置会被清除。

可能需要的软件包:

ntpd # 网络自动校正时间

udhcpc # dhcp客户端

烧写镜像的生成和其他设置

下面所说的所有操作都包含在这个打包脚本里面了:licheepi-nano-image-master

镜像的生成

这里有个脚本可以一键生成镜像。

   OUT_FILENAME="flashimg.bin"
    UBOOT_FILE=../u-boot-new/u-boot-sunxi-with-spl.bin
    KERNEL_DIR=../linux
    KERNEL_MODULES_DIR=$KERNEL_DIR/out/*
    DTB_FILE=$KERNEL_DIR/arch/arm/boot/dts/suniv-f1c100s-licheepi-nano.dtb
    KERNEL_FILE=$KERNEL_DIR/arch/arm/boot/zImage
    ROOTFS_FILE=../buildroot-2018.11.1/output/images/rootfs.tar
    SPEC_FILE=./custom/*
    SCRIPTES=./scripts/*.sh
    dd if=/dev/zero of=$OUT_FILENAME bs=1M count=16
    dd if=$UBOOT_FILE of=$OUT_FILENAME bs=1K conv=notrunc
    dd if=$DTB_FILE of=$OUT_FILENAME bs=1K seek=448  conv=notrunc
    dd if=$KERNEL_FILE of=$OUT_FILENAME bs=1K seek=512  conv=notrunc
    mkdir rootfs
    tar xf $ROOTFS_FILE -C ./rootfs
    cp -r $KERNEL_MODULES_DIR rootfs/usr/
    cp -r $SPEC_FILE rootfs/
    # add some custom modify
    for f in $SCRIPTES; do
        ROOTFS_PATH=./rootfs bash "$f" -H
    done
    fakeroot mksquashfs rootfs/ rootfs.img -no-exports -no-xattrs -all-root
    fakeroot mkfs.jffs2 -s 0x100 -e 0x10000 --pad=0x400000 -o jffs2.img -d overlay/
    dd if=rootfs.img of=$OUT_FILENAME  bs=1K seek=4608  conv=notrunc
    dd if=jffs2.img of=$OUT_FILENAME bs=1M seek=12 conv=notrunc
    rm -rf rootfs rootfs.img jffs2.img

启用Gadget与串口

需要增加一个开机启动脚本,指向前面文章的USB gadget的配置脚本。

需要修改/etc/inittab,增加ttyGS0的getty。

sed -i 's/\# Put a getty on the serial port/\# Put a getty on the serial port\nttyGS0::respawn:\/sbin\/getty -L ttyGS0 0 vt100 # GENERIC_SERIAL/g' $ROOTFS_PATH/etc/inittab

配置网络

修改/etc/network/interface,增加wlan0

auto wlan0
iface wlan0 inet dhcp
    pre-up wpa_supplicant -i wlan0 -c /overlay/etc/wpa_supplicant.conf -B
    wait-delay 15
    hostname $(hostname)
    post-down killall -q wpa_supplicant

为了使wpa_supplicant.conf可写,故我将其放在了overlay分区上。

配置挂载点

修改/etc/fstab,增加一行

/dev/mtdblock4  /overlay    jffs2   defaults    0   0

这就将第四分区挂载到了/overlay上。需要注意这个文件夹需要预先创建

配置wpa_supplicant

在overlay分区创建etc/wpa_supplicant.conf,内容如下:

   ctrl_interface=/var/run/wpa_supplicant
    ctrl_interface_group=wheel
    update_config=1
    eapol_version=1
    ap_scan=1
    fast_reauth=1

增加的update_config=1是为了让wpa_cli能够修改这个文件,保存wifi的配置。

创建/etc/wpa_supplicant/wpa_cli-action.sh,内容见:
https://git.yoctoproject.org/cgit/cgit.cgi/meta-intel-edison/plain/meta-intel-edison-distro/recipes-connectivity/wpa_supplicant/wpa-supplicant/wpa_cli-actions.sh

增加一个启动脚本,命令行为:

/usr/sbin/wpa_cli -a /etc/wpa_supplicant/wpa_cli-action.sh -B


上面的两个脚本的作用是让wpa_cli在Wifi连接上后调用wpa_cli-action.sh,从而自动调用udhcpc获取ip地址。

wifish

按照安装脚本将wifish的文件复制到它们应该在的地方。启动后就可以调用wifish来配置WiFi了。


分享给朋友:

相关文章

在Linux中怎么使用cron计划任务

在Linux中怎么使用cron计划任务

没有时间运行命令?使用 cron 的计划任务意味着你不用熬夜程序也可以运行。系统管理员(在许多好处中)的挑战之一是在你该睡觉的时候去运行一些任务。例如,一些任务(包括定期循环运行的任务)需要在没有人使用计算机资源的时候去运行,如午夜或周末。在下班后,我没有时间去运行命令或脚本。而且,我也不想在晚上去启动备份或重大更新。取而代之的是,我使用两个服务功能在我预定的时间去运行命令、程序和任务。cron 和 at 服务允许系统管理员去安排任务运行在未来的某个特定时间。at 服务指定在某个时间去运行一次任...

基于 debootstrap 和 busybox 构建 mini ubuntu

基于 debootstrap 和 busybox 构建 mini ubuntu

最近的工作涉及到服务器自动安装和网络部署操作系统,然后使用 ansible 和 saltsatck 进行配置并安装 openstack 。难点在于服务器的自动安装,由于不单只是通过 PXE 安装服务器,还需要能够安装时进行分区、配置网卡等工作,因此需要在开始安装前,必须先收集服务器的硬件信息。调研了一下目前的开源项目中,提供此类功能的有 tinycorelinux 、 puppet razor-el-mk 可做类似的工作。tinycorelinux 是个很好的工具,整个系统在 PXE 之后在内存...

buildroot编译中的问题

buildroot编译中的问题

在编译中遇到flex 报错。一直过不了。后来发现安装flex bison两个包后解决sudo apt-get install flex bison...

荔枝派Nano 全流程指南

荔枝派Nano 全流程指南

u-boot 初体验安装交叉编译链首先需要安装交叉编译链:# 此处为获取7.2.1版本,您可获取其他版本或者通过链接直接下载 wget http://releases.linaro.org/components/toolchain/binaries/7.2-2017.11/arm-linux-gnueabi/gcc-linaro-7.2.1-2017.11-x86_64_arm-linux-gnueabi.tar.xz tar -vxJf gcc-li...

评论列表

访客
访客 IP:
4年前 (2020-06-21)

我编译这个,加载了驱动,没看到wlan0,这不知道是哪个环节出了问题了

Watrt IP:四川省 回复:
查日志看看sdio是否正常,rtl8723bs是否挂载正常。
4年前 (2020-07-29)
访客
访客 IP:
4年前 (2020-06-21)

厉害

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。