我有一个设备,我正在尝试为其构建正确的嵌入式Linux内核。
内核版本为4.14.79。
我将设备树blob文件用于此内核。内核和dtb文件在构建时合并为单个itb文件。 kernel.its 用于构建,其内容为
/dts-v1/;
/ {
description = "Simple image with single Linux kernel";
#address-cells = <1>;
images {
kernel@1 {
description = "Vanilla Linux kernel";
data = /incbin/("./zLinux.bin.gz");
type = "kernel";
arch = "arm";
os = "linux";
compression = "gzip";
load = <0x70008000>;
entry = <0x70008000>;
hash@1 {
algo = "crc32";
};
};
fdt@1 {
description = "FDT_blob";
data = /incbin/("./at91.dtb");
type = "flat_dt";
arch = "arm";
compression = "none";
};
};
configurations {
default = "config@1";
config@1 {
description = "Boot Linux kernel";
kernel = "kernel@1";
fdt = "fdt@1";
};
};
};
设备上的RAM地址范围为 0x70000000-0x74000000 。内核映像在启动时加载到位置 0x72000000 ,并在 0x70000000 处解压缩。展平的设备树结构的初始地址类似于itb映像中的 0x722e3bf0 ,其加载地址为 0x72000000 。并且在拆包时,此FDT结构在地址 0x722e3bf0-0x01c00000 = 0x706e3bf0 处发出波束。我稍加修改了U-boot源代码,因此U-boot计算了解压缩的FDT结构地址,并将该地址作为寄存器值传递给内核。内核在此地址找到FDT结构并设置一些选项,这些选项对于正确的内核工作是必需的。初始地址 0x722e3bf0 如果传递给内核是不正确的:内核无法使用该地址进行管理,因此它不知何故不包含在内核虚拟内存映射中。
所以这是启动内核时在腻子上的输出日志:
## Booting kernel from FIT Image at 72000000 ...
FIT CHECK FORMAT
Using 'config@1' configuration
Trying 'kernel@1' kernel subimage
Description: Vanilla Linux kernel
Type: Kernel Image
Compression: gzip compressed
Data Start: 0x720000e0
Data Size: 2857468 Bytes = 2.7 MiB
Architecture: ARM
OS: Linux
Load Address: 0x70008000
Entry Point: 0x70008000
Hash algo: crc32
Hash value: 9399403c
Verifying Hash Integrity ... crc32+ OK
DTB 1
DTB 2
FIT CHECK FORMAT
## Flattened Device Tree from FIT Image at 72000000
Using 'config@1' configuration
Trying 'fdt@1' FDT blob subimage
Description: FDT_blob
Type: Flat Device Tree
Compression: uncompressed
Data Start: 0x722b9bb0
Data Size: 33455 Bytes = 32.7 KiB
Architecture: ARM
Verifying Hash Integrity ... OK
Booting using the fdt blob at 0x722b9bb0
Uncompressing Kernel Image ... OK
do_bootm_linux
setup_start_tag
setup_memory_tags
setup_commandline_tag "mem=64M console=ttyS0,115200n8 initrd=0x70700000,0x31768 root=/dev/ram0 rw, ramdisk_size=31768, quiet"
setup_revision_tag
machid = 0x000008a4
dtb_blob = 0x706b9bb0
Starting kernel ...
START KERNEL
由于某种原因,我需要将内核选项CONFIG_BLOCK设置为启用。但是,当我这样做时,FDT结构停止投影到 initial_address-0x01c00000 地址,并且在其初始地址(例如 0x722e70bf )不可用。而且我没有在 0x70000000-0x72000000 范围内找到此结构。因此内核无法读取FDT结构并且无法启动:
## Booting kernel from FIT Image at 72000000 ...
FIT CHECK FORMAT
Using 'config@1' configuration
Trying 'kernel@1' kernel subimage
Description: Vanilla Linux kernel
Type: Kernel Image
Compression: gzip compressed
Data Start: 0x720000e0
Data Size: 3029564 Bytes = 2.9 MiB
Architecture: ARM
OS: Linux
Load Address: 0x70008000
Entry Point: 0x70008000
Hash algo: crc32
Hash value: 2046e5ff
Verifying Hash Integrity ... crc32+ OK
DTB 1
DTB 2
FIT CHECK FORMAT
## Flattened Device Tree from FIT Image at 72000000
Using 'config@1' configuration
Trying 'fdt@1' FDT blob subimage
Description: FDT_blob
Type: Flat Device Tree
Compression: uncompressed
Data Start: 0x722e3bf0
Data Size: 33511 Bytes = 32.7 KiB
Architecture: ARM
Verifying Hash Integrity ... OK
Booting using the fdt blob at 0x722e3bf0
Uncompressing Kernel Image ... OK
do_bootm_linux
setup_start_tag
setup_memory_tags
setup_commandline_tag "mem=64M console=ttyS0,115200n8 initrd=0x70700000,0x31768 root=/dev/ram0 rw, ramdisk_size=31768, quiet"
setup_revision_tag
machid = 0x000008a4
dtb_blob = 0x706e3bf0
Starting kernel ...
no ATAGS support: can't continue
RomBOOT
内核 .config 文件在此处:https://pastebin.com/CA28Shqq
如何解决这个问题?
更新
在 kernel.its 文件中添加了一些字符串:
/dts-v1/;
/ {
description = "Simple image with single Linux kernel";
#address-cells = <1>;
images {
kernel@1 {
description = "Vanilla Linux kernel";
data = /incbin/("./zLinux.bin.gz");
type = "kernel";
arch = "arm";
os = "linux";
compression = "gzip";
load = <0x70008000>;
entry = <0x70008000>;
hash@1 {
algo = "crc32";
};
};
fdt@1 {
description = "FDT_blob";
data = /incbin/("./at91.dtb");
type = "flat_dt";
load = <0x70700000>;
entry = <0x70700000>;
arch = "arm";
compression = "none";
};
};
configurations {
default = "config@1";
config@1 {
description = "Boot Linux kernel";
kernel = "kernel@1";
fdt = "fdt@1";
};
};
};
启动时内核挂起:
## Booting kernel from FIT Image at 72000000 ...
FIT CHECK FORMAT
Using 'config@1' configuration
Trying 'kernel@1' kernel subimage
Description: Vanilla Linux kernel
Type: Kernel Image
Compression: gzip compressed
Data Start: 0x720000e0
Data Size: 3029568 Bytes = 2.9 MiB
Architecture: ARM
OS: Linux
Load Address: 0x70008000
Entry Point: 0x70008000
Hash algo: crc32
Hash value: 5fac1bbd
Verifying Hash Integrity ... crc32+ OK
DTB 1
DTB 2
FIT CHECK FORMAT
## Flattened Device Tree from FIT Image at 72000000
Using 'config@1' configuration
Trying 'fdt@1' FDT blob subimage
Description: FDT_blob
Type: Flat Device Tree
Compression: uncompressed
Data Start: 0x722e3bf4
Data Size: 33511 Bytes = 32.7 KiB
Architecture: ARM
Verifying Hash Integrity ... OK
Loading FDT from 0x722e3bf4 to 0x70700000
Booting using the fdt blob at 0x70700000
Uncompressing Kernel Image ... OK
do_bootm_linux
setup_start_tag
setup_memory_tags
setup_commandline_tag "mem=64M console=ttyS0,115200n8
initrd=0x70700000,0x31768 root=/dev/ram0 rw, ramdisk_size=31768,
quiet"
setup_revision_tag
machid = 0x000008a4
dtb_blob = 0x70700000
Starting kernel ...
RomBOOT
内核没有启动,但是现在内核启动时,地址0x70700000上有一个扁平的设备树结构。如何使内核在内存映射中添加一些地址范围,以使内核能够管理这些范围内的数据?