3

我试图了解 linux 在 arm 架构上启动的细节。我在互联网上进行了大量搜索,到目前为止了解了一些细节,尽管我觉得每次阅读一篇文章都会带来很多其他新术语,这让事情变得更加复杂。我确实有 2 个运行 linux 的板,一个 olimex 9261 和一个 beaglebone black。我在嵌入式系统尤其是 arm 方面的专业知识非常好,但在 linux 上玩的并不多(除了一些用户空间程序和内核中的 char 驱动程序)。

以下是我的问题:

一块一块板我有以下uboot输出(linux 2.6.30):

 bootargs=mem=64M console=ttyS0,115200 root=/dev/mtdblock1 rw rootfstype=jffs2
 bootcmd= cp.b 0xC0042000 0x22000000 0x00199954; bootm 0x22000000

该板有 64MB RAM(映射在 0x20000000)、512MB nand flash(目前没有找到映射)和 2MB 数据闪存(映射在 0xc0000000)。

我在这里不明白的是:

  • 为什么 bootargs 中有 mem=64?这不应该作为 ATAG 或 DTB 给出吗?
  • 当我们将控制权传递给内核时,为什么会有一个控制台作为参数?使用 tty 的内核是否已经由 uboot 配置?
  • initrd 与 rootfs。这对我来说仍然不清楚。我知道 initrd 可以作为块设备或单独的映像包含在内核中,uboot 必须将地址详细信息传递给内核(真的吗?)。我们能否拥有一个不包含 initrd 的内核 + 另一个文件系统,如 jffs2,内核将从该文件系统运行其余驱动程序?实际上我无法理解内核在启动时使用的文件系统的全部细节。在我的这个设置中,有 4 个文件:uImage、bootstrap、env.bin 和 jffs2 文件系统。所以没有initrd。这是如何工作的?以及上述 bootargs 中指向的文件系统的 root 过程如何?在我的理解中,内核应该首先访问 jffs2 文件系统,然后抓取 /dev/mtdblock1 中的映像并挂载它。也许我的理解是错误的。实际上内核和文件系统之间的这种交互是我似乎不理解的。在上面的 bootcmd 中,内核从 nand 复制到 sdram,然后 bootm 跳转到它。但是内核如何在引导时找到 jffs 呢?我在引导期间看到此输出行:VFS: Mounted root (jffs2 filesystem) on device 31:1。

在董事会用户指南中,我发现了这一点:

警告:由于 AT91SAM9261 芯片勘误表不支持从 NAND 闪存引导。

...

512MB NAND 闪存(在 Linux 中被视为硅驱动器)。

  • 编译内核后,我观察到 System.map 没有所有符号。我检查了vmlinux,它是一样的。有谁知道为什么?也许编译器没有正确配置?

非常感谢,丹尼尔。

4

2 回答 2

2
  • mem=64 - 我认为在加载设备树之前可能需要这样做。也许不吧。
  • tty - 但是内核如何知道引导加载程序配置了哪个 tty?必须有一些配置,要么传递给,要么编译进去,或者只是一个默认设置。
  • initrd(或 initramfs)与什么都没有 - initrd 只是一个非常小的用户空间,可以即。提示输入解密密码,等待插入带有rootfs的USB设备,或其他。事情可以没有,只要确保编译所有必要的模块以从 rootfs 引导。如果我没记错的话,几年前引入了 initramfs 作为 initrd 的替代品。它是一个打包在内核中的 CPIO 存档,它可能是您在“没有 initrd”时看到的
于 2014-12-22T23:34:33.933 回答
2

您的大部分问题都可以通过阅读Linux 源代码随附的文档来回答。一些关键文件是,

  • 内核参数.txt
  • 手臂/booting.txt

请仔细阅读它们,因为它们将包含您的 Linux 版本的最新信息。


一块一块板我有以下uboot输出(linux 2.6.30):

2.6.30 内核早于 ARM 的设备树。

为什么 bootargs 中有 mem=64?这不应该作为 ATAG 或 DTB 给出吗?

有两种机制。ATAGS更加灵活,因为它可以指定多个不连续的内存库。这个想法是引导代码可以探测内存并通过ATAGS提供它。这就是理论。这通常很难做到,因此允许用户指定mem=64更容易实现。如果有两种板类型,一种是 64MB,一种是 128MB,则由用户提供命令行以使用额外的内存。

当我们将控制权传递给内核时,为什么会有一个控制台作为参数?使用 tty 的内核是否已经由 uboot 配置?

有些设备有多个串行端口。一些内核可能希望将“u-boot”端口用于其他用途。HDSPA 调制解调器、打印机等。Linux 内核和 u-boot 控制台可能不同。这是一个特点。我经常使用/dev/null作为控制台。硬件往往吝啬于提供额外的串口。也许你很幸运,你的硬件人员不认为软件是免费的。

initrd 与 rootfs。

您可以直接引导到文件系统 (rootfs),但所有代码和查找代码的机制都必须在 Linux 映像中。即使它们是(JFFS2/NAND),您也可能会在 NAND 磨损时导致rootfs损坏。前 128MB 的 NAND 通常质量更高。您可以在此处放置一个带有 initrd 的 Linux,它能够修复主文件系统。对于其他引导设备,引导设备可能并不直接,并且可以在 initrd 映像中做出复杂的决定。通常initrd的挂载时间要少得多,并且您可以更快地执行某些操作。最后,您可以加载不同的模块,然后在 initrd 中锁定模块加载。

您可以直接使用rootfs。实现起来更简单。initrd更加灵活和强大。您可能希望从 JFFS2 过渡到 Ubi/UbiFS。如果您没有initrd,那么这几乎是不可能的(至少实现起来要困难得多)。

在我的这个设置中,有 4 个文件:uImage、bootstrap、env.bin 和 jffs2 文件系统。所以没有initrd。

uImage可能附加了一个initrd 。它被挂载为 ramdisk,在它卸载(以及switch_root新的/最终的rootfs)之后,内存就可以自由使用了。但是,您的命令行没有initrd信息,因此您可能没有。

在我的理解中,内核应该首先访问 jffs2 文件系统,然后抓取 /dev/mtdblock1 中的映像并挂载它。也许我的理解是错误的。实际上内核和文件系统之间的这种交互是我似乎不理解的。在上面的 bootcmd 中,内核从 nand 复制到 sdram,然后 bootm 跳转到它。但是内核如何在引导时找到 jffs 呢?我在引导期间看到此输出行:VFS: Mounted root (jffs2 filesystem) on device 31:1。

您有信息可以找到设备;root=/dev/mtdblock1你告诉它文件系统类型;rootfstype=jffs2. 缺少的部分是init=/sbin/init. 您可以在 Linux 的kernel-parameters.txt中了解它。安装 JFFS2 后,init代码会查找要运行的进程。它是一切的父进程,它将开始执行许多不同的进程。通常它是init,但您可以指定init=/bin/sh并且您将只有一个 shell 开始。这可能是开发initrd映像的好方法,因为您可以仅在一个进程运行的情况下测试脚本。

编译内核后,我观察到 System.map 没有所有符号。我检查了vmlinux,它是一样的。有谁知道为什么?也许编译器没有正确配置?

System.map实际上只是外部函数和数据。它不包括所有功能。实际上,由于内联,某些功能可能不存在。

警告:由于 AT91SAM9261 芯片勘误表不支持从 NAND 闪存引导。

我想这是 u-boot 的工作来处理这个问题。

于 2014-12-23T18:22:55.483 回答