BeagleBone Black 3

摘自:http://jexbat.com/2016/BBB-Prepare-booting/


BeagleBone Black 从零到一 (3 Linux 镜像、initramfs、Device Tree及根文件系统)

基于 Linux 3.8

内核启动

BeagleBone Black 从零到一 (1 MLO、U-Boot) 这篇文章里讲到 U-Boot 启动之后会运行 uEnv.txt 文件里面 uenvcmd 指代的命令,我们也通常把加载镜像文件等命令写在这里。

U-Boot 有很多方法能启动内核,通常使用的是 bootm 或者 bootz 命令:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
U-Boot# help bootz
bootz - boot Linux zImage image from memory

Usage:
bootz [addr [initrd[:size]] [fdt]]
    - boot Linux zImage stored in memory
        The argument 'initrd' is optional and specifies the address
        of the initrd in memory. The optional argument ':size' allows
        specifying the size of RAW initrd.
        When booting a Linux kernel which requires a flat device-tree
        a third argument is required which is the address of the
        device-tree blob. To boot that kernel without an initrd image,
        use a '-' for the second argument. If you do not pass a third
        a bd_info struct will be passed instead

U-Boot# help bootm
bootm - boot application image from memory

Usage:
bootm [addr [arg ...]]
    - boot application image stored in memory
        passing arguments 'arg ...'; when booting a Linux kernel,
        'arg' can be the address of an initrd image
        When booting a Linux kernel which requires a flat device-tree
        a third argument is required which is the address of the
        device-tree blob. To boot that kernel without an initrd image,
        use a '-' for the second argument. If you do not pass a third
        a bd_info struct will be passed instead

For the new multi component uImage format (FIT) addresses
        must be extened to include component or configuration unit name:
        addr:<subimg_uname> - direct component image specification
        addr#<conf_uname>   - configuration specification
        Use iminfo command to get the list of existing component
        images and configurations.

Sub-commands to do part of the bootm sequence.  The sub-commands must be
issued in the order below (it's ok to not issue all sub-commands):
        start [addr [arg ...]]
        loados  - load OS image
        ramdisk - relocate initrd, set env initrd_start/initrd_end
        fdt     - relocate flat device tree
        cmdline - OS specific command line processing/setup
        bdt     - OS specific bd_t processing
        prep    - OS specific prep before relocation or go
        go      - start OS

bootz 启动存储在内存中的 zImage ,支持 device-tree,其中一些参数:
addr:内核地址
initrd:ramdisk 镜像地址,如果没有指定的 initrd 需要传递一个 - 给启动指令。什么是 ramdisk 镜像呢?我们下面会讲到。
fdt: flat device tree 地址,如果没有指定 fdt 地址,会传入一个 bd_info 结构体。什么是 Device Tree 呢?我们下面也会讲到。

Linux 启动需要的文件

Linux 启动的时候需要挂载根文件系统来运行初始化程序,再总结 bootz 命令,所以 U-Boot 启动 Linux 内核需要以下文件:
内核镜像、initrd 文件(ramdisk 镜像)、DTB(Device Tree Binary)、根文件系统
不是必要但是也是需要的文件:
System.map

Linux 内核镜像

vm 代表 Virtual Memory,Linux 支持虚拟内存,因此得名 vm。Linux 内核按引导程序的不同分不同的格式,主要有:

  • vmlinux : 最原始的内核静态链接后可执行的文件格式 ELF,没有压缩,不可启动的内核镜像,可能在调试阶段才会用到。
  • vmlinux.bin : 和 vmlinux 类似不过是可启动的 RAW Binary 格式。所有的标志和重定位信息都被丢弃,由 vmlinux 通过命令 objcopy -O binary vmlinux vmlinux.bin 生成。
  • vmlinuz : 经过压缩过的 vmlinux 可启动镜像。可启动表示有能力加载操作系统到内存中运行,vmlinuz 通常由 zImage 和 bzImage 拷贝而来。
  • zImage : 比zImage 是 ARM linux 常用的一种压缩镜像文件,它是由 vmlinux 加上解压代码经 gzip 压缩而成,通常放在小尺寸 ROM 中(小于 512K),zImage 解压缩内核到低容量内存(640K)。由命令 make zImage生成。
  • bzImage : bz 表示 big zImage,其格式与 zImage 类似,但采用了不同的压缩算法。bzImage 需要解压缩内核到高容量内存(1M以上)。由命令 make bzImage 生成。
  • uImage : uImage 是 uboot 专用的镜像文件,它是在 zImage 之前加上一个长度为 0x40 的头信息(tag),在头信息内说明了该镜像文件的类型、加载 位置、生成时间、大小等信息。其 0x40 之后与 zImage 没区别。

编译及生成:

BeagleBone 的内核镜像托管在 Github
编译之前可能需要安装的库

1
2
➜ sudo apt-get install lzop
➜ sudo apt-get install libncurses5-dev libncursesw5-dev

源码里面已经包含了 BeagleBone 的配置文件:

1
2
3
4
5
6
➜ git clone git://github.com/beagleboard/linux.git
➜ cd linux
➜ git checkout 3.8
➜ make distclean
➜ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- bb.org_defconfig 
➜ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- zImage dtbs -j4

编译完成后会在 arch/arm/boot 目录下面生成 zImage 镜像和 dtbs 文件。
或者也可以使用 make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- menuconfig 或者 make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- xconfig 来自己配置需要编译的内容。
如果使用 make xconfig 则需要安装 qt 和一些依赖,如果使用虚拟机不能使用 ssh 的方式远程编译,需要打开虚拟的图形界面进行编译。
xconfig 的一些依赖:

1
2
3
➜ sudo apt-get update
➜ sudo apt-get install libqt4-dev pkg-config
➜ sudo apt-get install g++

initrd、initramfs

Linux kernel 在自身初始化完成之后,需要能够找到并运行第一个用户程序(这个程序通常叫做 “init” 程序)。用户程序存在于文件系统之中,因此,内核必须找到并挂载一个文件系统才可以成功完成系统的引导过程。根文件系统(rootfs) 所在的储存装置很可能极难寻找,比方说 SCSI 装置就需要复杂且耗时的程序,若用 RAID 系统更是需要看配置情况而定,同样的问题也发生在 USB storage 上,因为 kernel 得花上更长的等待与配置时间,又或者需要远端挂载 rootfs,不仅得处理网路装置的问题,甚至还得考虑相关的伺服器认证、通讯往返时间等议题。为解决此问题,Linux kernel 提出了一个 RAM disk 的解决方案,把一些启动所必须的用户程序和驱动模块放在 RAM disk 中,这个 RAM disk 看上去和普通的 disk 一样,有文件系统,有 cache,内核启动时,首先把 RAM disk 挂载起来,等到 init 程序和一些必要模块运行起来之后,再切到真正的文件系统之中。更重要的是,有了 initrd(init ram disk) 我们可在放置某些特别的程式,一来作为挂载 rootfs 作准备,比方说硬体初始化、解密、解压缩等等,二来提示使用者或系统管理员目前的状态,这对于消费性电子产品来说,有很大的意义。
整体来说,如果能增加开机的弹性(比方说配合简单的shell script 即​​可达成USB/SCSI 初始化动作,若透过 kernel code 实做,恐怕上百千行是免不掉的),又能适度降低 kernel image 本身的设计复杂度与空间使用量,采取 initrd 是很不错的方式,所以几乎各大Linux distribution 都有提供 initrd,以解决在不同硬体、不同装置上开机的技术议题。
如果仔细考虑一下,initrd 虽然解决了问题但并不完美。 比如,disk 有 cache 机制,对于 RAM disk 来说,这个 cache 机制就显得很多余且浪费空间;disk 需要文件系统,那文件系统(如 ext2 等)必须被编译进 kernel 而不能作为模块来使用。
Linux 2.6 kernel 提出了一种新的实现机制,即 initramfs。顾名思义,initramfs 只是一种 RAM filesystem 而不是 disk。initramfs 实际是一个 cpio 归档,启动所需的用户程序和驱动模块被归档成一个文件。因此,不需要 cache,也不需要文件系统。

引用:关于 initramfs

The only purpose of an initramfs is to mount the root filesystem. The initramfs is a complete set of directories that you would find on a normal root filesystem. It is bundled into a single cpio archive and compressed with one of several compression algorithms.
initramfs 的唯一用途就是挂载根文件系统。initramfs 就是一个普通文件系统目录的完整的集合。它用几个压缩算法打包成 cpio 格式。
There are only four primary reasons to have an initramfs in the LFS environment: loading the rootfs from a network, loading it from an LVM logical volume, having an encrypted rootfs where a password is required, or for the convenience of specifying the rootfs as a LABEL or UUID. Anything else usually means that the kernel was not configured properly.
在 LFS (Linux From Scratch) 中 initramfs 的存在主要有四个主要的原因:从网络加载根文件系统、从 LMM 逻辑卷加载的根文件系统、加密过的需要密码的根文件系统或者方便的指定根文件系统为 LABLE 或者 UUID。还有别的通常意味着内核配置不正确。
For most distributions, kernel modules are the biggest reason to have an initramfs. In a general distribution, there are many unknowns such as file system types and disk layouts. In a way, this is the opposite of LFS where the system capabilities and layout are known and a custom kernel is normally built. In this situation, an initramfs is rarely needed.
对于大多数分发版本来说,需要 initramfs 最大的原因是内核模块。在一般的分发中,有很多未知的文件系统和磁盘分布,在某种程度下,这是在系统能力和布局未知的情况。 如果说系统能力和布局已知,内核已经建立的情况下很少需要 initramfs。

上面提到的 RAM DISK 为 image-initrd,RAM filesystem 为 cpio-initrd,内核启动的时候会先判断是否为 cpio 格式,如果不是的话会当作 image-initrd 处理。

cpio-initrd 和 image-initrd 处理流程可以参考:Linux2.6 内核的 Initrd 机制解析

编译及生成:

Linux 2.6 以来都是默认使用 initramfs(”General setup” 的子項目 “Initial RAM filesystem and RAM disk (initramfs/initrd) suppot” 是默认勾选的) ,只是编译的输出很多还沿袭传统使用 initrd 的名字。编译的时候会生成 usr/initramfs_data.cpio 文件,内核编译的时候会把这个文件编译进内核。如果配置选项里面 “Initramfs source file” 为空(不指定 CONFIG_INITRAMFS_SOURCE),会默认编译出一个空的 initramfs 包(没有 init 文件)。
这样一来 Linux 内核编译的时候如果按默认方式编译(勾选 “initial RAM filesystem and RAM disk (initramfs/initrd) suppot”) 则有四种方法生成 initramfs 文件:
1. 不指定 CONFIG_INITRAMFS_SOURCE 则会编译出一个空的 initramfs
2. 为 CONFIG_INITRAMFS_SOURCE 指定一个现有的 initramfs 文件

如果你有一个现有的 initramfs_data.cpio.gz 文件,可以指定给 CONFIG_INITRAMFS_SOURCE ,内核编译时会自动检测文件类型然后链接到内核镜像中去。
3. 为 CONFIG_INITRAMFS_SOURCE 指定一个现有的根文件系统目录
如果为 CONFIG_INITRAMFS_SOURCE 指定一个目录,编译的时候会自动把此目录打包成 cpio 文件,但是不是用的标准的 cpio 命令打包,内核编译时会在指定的目录生成一个描述目录结构的文本文件 gen_initramfs_list.sh,然后给 gen_init_cpio 程序(在 usr 目录下)调用,就会生成 cpio 包。
4. 使用 initramfs_list 配置文件配置
这就是刚刚第三种方法讲的配置文件 gen_initramfs_list.sh,不过我们这里是手动创建配置文件而不是自动生成。手动创建后放入一个目录中,然后指定 CONFIG_INITRAMFS_SOURCE 为那个目录编译的时候就可以生成相应的 cpio 包。
例子:

gen_initramfs_list.sh
1
2
file /init usr/hello 500 0 0
dir /dev 755 0 0

这个内容表示把 usr/hello 指定为文件系统中的 init 文件,权限为 500,uid 和 gid 都为0,并且创建 /dev文件夹,权限为 755,uid 和 gid 都为 0。
详细使用方法请看:Tech Tip: How to use initramfs.

值得注意的是我们按照这个方法制作出来的内核镜像实际上比原来的大了许多,这是因为我们是将 initramfs 根文件系统直接合并到内核镜像里边了。这样,启动内核时的参数就不需要添加 initrd=…… 来指定 initramfs 的位置了(或者配置内核的时候直接不勾选 “Initial RAM filesystem and RAM disk (initramfs/initrd) suppot”,但是为了可扩展性一般默认勾选)。
启动命令为:

1
bootz ${loadaddr} - ${fdtaddr};

当然如果想指定外部的 initramfs 文件来启动 Linux,首先直接指定 CONFIG_INITRAMFS_SOURCE 为空,这样就会链接一个空的 initramfs (一百多字节)进内核,然后指定外部 initramfs 的位置来启动。
命令为:

1
bootz ${loadaddr} ${rdaddr}:${rdsize}  ${fdtaddr};

手动生成 initramfs 文件:

1
2
3
4
5
6
➜ mkdir sub   
➜ cp hello sub/init
➜ cd sub
➜ find . | cpio -o -H newc | gzip > ../initramfs_data.cpio.gz
➜ cd ..
➜ rm -rf sub

System.map

System.map 是一个特定内核的内核符号表。它是你当前运行的内核的符号链接。Linux 内核是一个很复杂的代码块,有许许多多的全局符号。内核并不使用符号名。它是通过变量或函数的地址(指针)来使用变量或函数的,而不是使用 size_t BytesRead,内核更喜欢使用(例如) c0343f20 来引用这个变量。
当你编译一个新内核时,各个符号名的地址要发生变化,你的老的 System.map 具有的是错误的符号信息。每次内核编译时产生一个新的 System.map,你应当用新的System.map 来取代老的 System.map。
虽然内核本身并不真正使用 System.map,但其它程序比如 klogd, lsof 和 ps 等软件需要一个正确的 System.map。如果你使用错误的或没有 System.map,klogd 的输出将是不可靠的,这对于排除程序故障会带来困难。没有 System.map,你可能会面临一些令人烦恼的提示信息。
另外少数驱动需要 System.map 来解析符号,没有为你当前运行的特定内核创建的System.map 它们就不能正常工作。
Linux 的内核日志守护进程 klogd 为了执行名称-地址解析,klogd 需要使用System.map。System.map 应当放在使用它的软件能够找到它的地方。执行:man klogd 可知,如果没有将 System.map 作为一个变量的位置给 klogd,那么它将按照下面的顺序,在三个地方查找 System.map:
/boot/System.map
/System.map
/usr/src/linux/System.map
System.map 也有版本信息,klogd 能够智能地查找正确的映象(map)文件。

编译及生成:

System.map 文件在编译内核的时候会自动生成在源码根目录下,每次重新编译内核都要替换掉相应的 System.map。

Device Tree 机制

Kernel 3.x 版本之后开始支持 Device Tree 机制。
在早期的ARM Linux Kernel中,板级细节(BSP)使用代码形式,存放在 arch/arm/ 目录。名字通常为:plat-xxxx 或者 mach-xxxx,相当多数的代码只是在描述板级细节,而这些板级细节对于内核来讲,不过是垃圾。板级代码只对相应开发板有用,每次升级 Kernel 都需要对板级代码进行升级和测试,ARM 对应的开发板又种类繁多所以这些代码越来越臃肿庞大。
引入了 Device Tree 之后,改变了原来用硬编码的方式把板级代码嵌入在内核里面,改用通过 Bootloader 传递 DB 文件的方式把硬件信息传递给 Kernel,实现了内核和板级代码的低耦合,减少内核代码的臃肿降低维护人员的成本。
Uboot 的主线代码从 v1.1.3 开始就支持 DT 了,其对ARM的支持和 Kernel 对 Device Tree 的支持是同期完成的,在 Uboot 中需要在配置文件中加入 #define CONFIG_OF_LIBFDT 配置项即可,当我们将 DTB 文件在 Uboot 里加载到内存中后,通过 fdt addr 0xnnnnnnnn 命令来设置 DTB 文件对应地址,这样就可以使用 fdt resizefdt print 等命令对 DTB 文件进行操作了。对于 ARM,使用 bootz ${loadaddr} ${rdaddr}:${rdsize} ${fdtaddr} 命令来启动 Kernel。
更多背景介绍:Device Tree 背景介绍

编译及生成:

DTS:Device Tree Source 位于目录 linux/arch/arm/boot/dts
DTC:Device Tree Compiler 位于目录 linux/scripts/dtc/dtc
DTB:Device Tree Binary 生成在 linux/arch/arm/boot/dts
DTB 是由 DTS 通过 DTC 编译而成。
在构建内核的时候可以使用 make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- dtbs 生成。
Device Tree Binary 在编译 linux 内核的时候自动根据 arch/arm/boot/dts/Makefile 指定的方式生成,也可以通过 dtc 手动编译:

1
➜ ./scripts/dtc/dtc -I dts -O dtb -o ./devicetree.dtb ./beaglebone.dts

DTS 组成和结构专门写一篇文章来讲。

根文件系统

根文件系统是内核挂载的第一个文件系统,根文件系统为分层文件树的顶点。它包含对于系统操作很关键的文件和目录,包括设备目录和用于引导系统的程序。根文件系统还包含可安装文件系统以连接到根文件系统层次结构的安装点。
Linux 只有一个文件树,整个文件系统是以一个树根 “/“ 为起点的,所有的文件和外部设备都以文件的形式挂结在这个文件树上,包括硬盘、软盘、光驱、调制解调器等,这和以 “驱动器盘符” 为基础的Windows系统是大不相同的。

编译及生成:

根文件系统的制作可以自己建立各个系统文件夹添加需要的库和启动文件然后打包成可分发的镜像。
目前一般使用 buildroot 或者 busybox 来制作根文件系统,buildroot 比 busybox 更强大并且包含了 busybox 。

下载 buildroot 源码:

1
➜ git clone git://git.buildroot.net/buildroot

为 Beaglebone 配置 buildroot:

1
➜ make beaglebone_defconfig

如果只编译文件系统,需要做一些修改:

1
➜ make menuconfig

取消勾选 Kernel --> Linux Kernel,这里不编译内核;
取消勾选 bootloaders --> u-boot,也不编译 u-boot;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

Target options --->:
    Floating point strategy (NEON)
    ARM instruction set (Thumb2)
Toolchain --->
    Toolchain type (External toolchain)
    Toolchain (Linaro ARM 2014.08)
    Toolchain origin (Toolchain to be downloaded and installed) //让 buildroot 自己下载
Target packages --->
    Networking applications --->
        [*] dhcpcd
        [*] openssh
    Text editors and viewers --->
        [*] nano
Filesystem images --->
    ext2/3/4 variant (ext4) --->
        (X) ext4

保存然后:

1
➜ make

make 的时候 buildroot 会联网下载一些编译工具或者依赖包。最后会在 output 文件夹中生成相应的文件系统,把生成的文件系统烧写进 SD 卡中:

1
➜ sudo dd if=buildroot/output/images/rootfs.ext4 of=/dev/sdc2

值得注意的是用以上命令烧写之后可以看到 SD 卡使用率变成 100%,没有空间写别的文件进去了。
这是因为使用 dd 命令不仅仅把文件而是把整个文件系统都烧写到 SD 卡中了,包括磁盘使用率的 metadata 描述。虽然 SD 卡上还有很多剩余空间,但是剩余空间还没有合并到特定的分区上,隐藏在 SD 卡分区的末尾。
这个时候使用 resize 命令就能合并了(在 ext2、ext3和ext4上都能使用,并且执行命令的时候会提示使用 e2fsck 检查下文件系统,按提示操作即可):

1
➜ sudo resize2fs /dev/sda99

如果我们在 buildroot 中的 toolchain 指定外部编译工具为之前在 Ubuntu 上面 apt-get 的交叉编译器,那么编译的时候则会出现错误信息:

Distribution toolchains are unsuitable for use by Buildroot,
as they were configured in a way that makes them non-relocatable,
and contain a lot of pre-built libraries that would conflict with
the ones Buildroot wants to build.

这是因为 Ubuntu 得到的交叉编译器被配置成不可重定位的,而且包含了一些与 buildroot 相冲突的库,官方解释:

Distro toolchains, i.ie. toolchains coing with distributions, will
almost invariably be unsuitable for use with Buildroot:

  • they are mostly non-relocatable;
    • their sysroot is tainted with a lot of extra libraries.

Especially, the toolchains coming with Ubuntu (really, all the Debian
familly of distros) are configured with –sysroot=/ which makes them
non-relocatable, and they already contain quite some libraries that
conflict (in any combination of version, API or ABI) with what Buildroot
wants to build (i.e. extra libraries, some not even present in
Buildroot…) but also their mere preence when Buildroot does not expect
them to be already built (so that a package would enable features when
it should not).

所以我们要自己下载交叉编译工具或者让 buildroot 自动下载。

开始完整启动 Linux

准备:

  • SD 卡已经分好两个区,区 1 为 FTA 格式,区 2 为 EXT4 格式,区 1 前面留有 1 MB 的空间供 U-Boot 使用
  • U-Boot 已经编译好并把 MLO 和 uboot.img 文件烧写到 SD 卡的前 1M 起始位置,以便处理器用 RAW Mode 启动 U-boot,具体请看BeagleBone Black 从零到一 (1 MLO、U-Boot)
  • Linux 已经编译好并且生成了 zImage、System.map;
  • initramfs 已经制作好并且生成了 initrd.img;(如果没有特殊的启动前要求此项可以忽略);
  • 文件系统已经制作好并且烧入到 SD 卡的 ext4 分区中;

新建 boot 目录:

1
➜ mkdir boot

拷贝内核编译出来的 zImage 和 System.map 至 boot 目录并重命名:

1
2
3
➜ cp zImage  ~/boot/
➜ cp System.map ~/boot/
➜ mv ~/boot/zImage ~/boot/vmlinuz

把 initrd.img 和 dtb 文件拷贝到 boot 文件夹,再把整个 boot 文件夹拷贝到 ext4 分区的根目录。
在 FTA 分区中新建 uEnv.txt 文件,让 U-Boot 启动之后自动运行相应的指令启动 Linux:

uEnv.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
## uEnv.txt 可以引用默认的环境变量,在 include/configs/xxx.h 里面定义
## 因为 SDRAM 的地址是从 0x80000000开始的,这里设置镜像、dtb、initrd加载到的地址分别为 0x82000000、0x88000000、0x88080000
loadaddr=0x82000000
fdtaddr=0x88000000
rdaddr=0x88080000
## 设置
initrd_high=0xffffffff
fdt_high=0xffffffff

## 设置命令为先打印 debug 信息,然后从第 0 个 MMC 设备的第 2 个分区里面的boot 文件夹中的 vmliuz 文件加载到 loadaddr 处
loadximage=echo debug: [/boot/vmlinuz] ... ; load mmc 0:2 ${loadaddr} /boot/vmlinuz}
## 同样的加载 dtb 文件
loadxfdt=echo debug: [/boot/{fdtfile}] ... ;load mmc 0:2 ${fdtaddr} /boot/${fdtfile}
## 加载 initrd
loadxrd=echo debug: [/boot/initrd.img] ... ; load mmc 0:2 ${rdaddr} /boot/initrd.img; setenv rdsize ${filesize}
## 加载第二个分区的 uEnv.txt 文件
loaduEnvtxt=load mmc 0:2 ${loadaddr} /boot/uEnv.txt ; env import -t ${loadaddr} ${filesize};
## 检查 ${dtb} 字符串长度是否不为 0,如果不为 0 就赋值给 fdtfile
check_dtb=if test -n ${dtb}; then setenv fdtfile ${dtb};fi;
## 运行前面指定的命令
loadall=run loaduEnvtxt; run check_dtb; run loadximage; run loadxrd; run loadxfdt;

## 设置传递给内核的参数,其中 cmdline 是在第二个分区也就是放置 linux 镜像的分区内的 boot 文件夹中的 uEnv.txt 加载的
mmcargs=setenv bootargs console=tty0 console=${console} ${optargs} ${cape_disable} ${cape_enable} root=/dev/mmcblk0p2 rootfstype=${mmcrootfstype} ${cmdline}

##  根据前面几篇文章 U-Boot 的配置,启动后会运行 uenvcmd
uenvcmd=run loadall; run mmcargs; echo debug: [${bootargs}] ... ; echo debug: [bootz ${loadaddr} ${rdaddr}:${rdsize} ${fdtaddr}] ... ; bootz ${loadaddr} ${rdaddr}:${rdsize} ${fdtaddr};

SD 卡中 ext4 分区中 boot 文件夹中再创建一个 uEnv.txt,这边的 uEnv.txt 便于向 U-Boot 传递一些内核参数之类的,不用每次换了内核之类的都去修改 U-Boot 那边的文件:

uEnv.txt
1
2
3
4
uname_r=3.8.13-bone79
#uuid=
#dtb=
cmdline=coherent_pool=1M quiet init=/lib/systemd/systemd cape_universal=enable

都设置好了之后,把 SD 卡插入 beaglebone 中并且按住 S2 键上电就能从 SD 卡中启动了。

参考:

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值