我正在开发一个嵌入式 Linux,使用 u-boot 作为引导加载程序和 systemd init 系统。这些工具仅限于标准 busybox。
在分析一些问题时,我发现根文件系统是只读的,这导致了问题。原因是某些服务和程序依赖于可写的根文件系统,导致故障。
经过一段时间的研究,我发现根文件系统只有在断电时才是只读的。(当遇到某些错误时,主单元会触发电源回收。)我怀疑当根文件系统尝试写入某些关键文件或更新某些服务/进程时,在电源故障时会在文件系统上设置错误标志。下次启动时,fsck 会读取该标志并将根目录安装/重新安装为只读,或者 fsck 强制进入某种恢复模式(我不知道是否存在任何恢复模式)。
我的假设正确吗?如果是这样,那么错误时在 FS 上设置的 fs 标志是什么?如何防止 root 作为 RO 启动?
笔记:
根文件系统使用“errors=continue”挂载。因此,如果 fsck 读取重新安装选项的超级块,它应该忽略该错误并重新安装为 RW。
我尝试重现该情况,在运行 dd 命令时关闭电源,但从未能够重现。
附加问题:哪个 udev/systemd 魔法挂载 root fs?
看起来
root@testbox:~# dd if=/dev/mem bs=1 count=4 skip=2149646336 | hd
应该几乎等于
root@testbox:~# devmem 2149646336 32
但是,虽然devmem效果很好,但该dd调用给我带来了段错误。对于许多其他 bs,skip 组合(在我尝试解决这个问题时偶然发现的) dd 成功返回,但数据与我期望的完全不同。所有这些都表明,当我使用 dd 时,我实际上并没有解决我认为我正在解决的问题。也许是一些内存映射问题?我是一个硬件专家,所以我只考虑物理地址。
一些血淋淋的细节:
我正在构建一个嵌入式系统,其中 Linux 运行在带有片上 ARM A53 内核的 Xilinx FPGA 上。我经常使用 devmem 来读取或写入 FPGA 逻辑中的内存映射寄存器。我想使用 dd 而不是 devmem 通过一个命令读取一长串地址,并将数据保存到文件或通过管道将其传输到另一个进程。
我的 FPGA 设计有一个内部 RAM 块,可读写,映射到字节地址0x80210000。
我写了一个shell脚本,如下所示:
devmem 0x80210000 32 0x5AB000CD
devmem 0x80210004 32 0x5AB001CD
devmem 0x80210008 32 0x5AB002CD
devmem 0x8021000C 32 0x5AB003CD
... etc etc <250 more lines> ...
devmem 0x802103F8 32 0x5AB0FECD
devmem 0x802103FC …Run Code Online (Sandbox Code Playgroud) 系统时钟由内核维护,而硬件时钟由实时时钟(RTC)维护。
谁能告诉我这两个时钟之间的区别。
我有一个嵌入式系统,它从小型闪存启动并以 root 身份安装 initrd.img ramdisk 运行。启动时,它以只读模式挂载 initrd 映像,但是当 inittab 运行时,它似乎跳过了第一个挂载命令
null::sysinit:/bin/mount -o remount,rw /
Run Code Online (Sandbox Code Playgroud)
据我所知,我使用正确的选项设置了 /etc/fstab:
/dev/root / ext2 rw,noauto,noatime 1 1
Run Code Online (Sandbox Code Playgroud)
然后系统设法给我一个命令提示符,然后我可以以 root 身份登录并键入 mount 命令,该命令可以正常工作。
此外,同样的设置也适用于看似相同的目标硬件。不同之处在于我是从我的笔记本电脑而不是我们使用的常用服务器创建启动映像。我的笔记本电脑正在运行更新版本的 grub,我用它来为映像制作引导加载程序。也许我还有一个更新版本的 genext2fs 用于制作用作 ramdisk 的图像。服务器正在运行 FC10,但我的笔记本电脑使用的是 ubuntu,因此我忽略了一些影响 mount 或 inittab 的差异。可能与/dev/null有关吗?
为什么系统不重新挂载 ramdisk 映像,我该如何解决?
在我的嵌入式系统上,我正在将密集视频流写入标清。我不挂载分区,只是写入/dev/mmcblk0p1. 一段时间后,我的写作过程挂起。我明白了
[16952.240000] INFO: task vrec:1297 blocked for more than 120 seconds.
Run Code Online (Sandbox Code Playgroud)
[mmcqd]吃了 90%,dmesg 向我展示
[64142.350000] mmc0: starting CMD13 arg e6240000 flags 00000015
[64142.350000] mmc0: req done (CMD13): 0: 00000c00 00000000 00000000 00000000
[64142.350000] mmc0: starting CMD13 arg e6240000 flags 00000015
[64142.350000] mmc0: req done (CMD13): 0: 00000c00 00000000 00000000 00000000
[64142.350000] mmc0: starting CMD13 arg e6240000 flags 00000015
[64142.350000] mmc0: req done (CMD13): 0: 00000c00 00000000 00000000 00000000
[64142.350000] mmc0: starting CMD13 arg e6240000 flags 00000015 …Run Code Online (Sandbox Code Playgroud) ps在我的 Linux 系统中执行命令时,我看到一些用户进程两次(不同的 PID...)。我想知道它们是新进程还是同一进程的线程。我知道标准 C 库中的一些函数可以创建一个新进程,例如fork(). 我想知道当我执行ps命令时,哪些具体函数可以使进程出现两次,因为我正在查看创建新进程或线程的源代码。
我正在研究 Zynq Microzed 板。它使用 uramdisk.image.gz 完美启动,但我尝试使用 initramfs.cpio 启动它。
对此,我对u-boot的头文件做了如下修改:
zynq_common.h和zynq_common.h.save改动如下
"ramdisk_image=uramdisk.image.gz\0"
到
"ramdisk_image=initramfs.cpio\0"
在两个头文件中
我收到以下日志消息
它仍在寻找 uramdisk.image.gz 并给出错误
错误的 Ramdisk 映像格式
Ramdisk 映像已损坏或无效
我无法找出我出错的地方以及如何解决它。
我的团队正在为嵌入式 Linux 解决方案开发软件。我们面临的问题是系统需要太多时间才能准备好开始运行我们想要的应用程序(即加载Linux内核太多时间)。通常需要 38 到 43 秒才能完成。我们已经修改了内核配置,删除了我们知道不需要的文件,但仍然需要这么多时间。
我的问题:还有什么办法可以使内核启动更快(最好不改变硬件)?嵌入式 Linux 充电需要这么长时间正常吗?是否可以要求 Linux 内核在内核充满电之前启动我们的应用程序?
该系统是德州仪器OMAP L138。
以下是内核启动时终端中显示的包含所有最相关消息的图像。如果有人对我的问题没有(一般)答案,但了解有助于提高内核启动速度的其中一行,也请随意回答!

我想将带有 U-Boot 的 Linux 内核写入 i.MX6 板上的 eMMC 存储的 mmc hwpartition:
TX6UL U-Boot > mmc info
Device: FSL_SDHC
Manufacturer ID: 11
OEM: 100
Name: 004G6
Tran Speed: 52000000
Rd Block Len: 512
MMC version 5.0
High Capacity: Yes
Capacity: 8 MiB
Bus Width: 4-bit
Erase Group Size: 4 MiB
HC WP Group Size: 4 MiB
User Capacity: 8 MiB WRREL
Boot Capacity: 2 MiB ENH
RPMB Capacity: 512 KiB ENH
GP1 Capacity: 8 MiB WRREL
GP2 Capacity: 1.8 GiB ENH …Run Code Online (Sandbox Code Playgroud) embedded ×10
linux ×4
u-boot ×4
linux-kernel ×2
boot ×1
clock ×1
dd ×1
devices ×1
filesystems ×1
flash-memory ×1
fork ×1
fsck ×1
hardware ×1
mmap ×1
performance ×1
process ×1
sd-card ×1
startup ×1
systemd ×1