流程
setup_machine_fdt(__fdt_pointer);
=>early_init_dt_scan() =>early_init_dt_scan_nodes()
=>//从dts中获取 内存容量,地址信息
/* Setup memory, calling early_init_dt_add_memory_arch */
of_scan_flat_dt(early_init_dt_scan_memory, NULL);
arm64_memblock_init
详细分析见博客《memblock 初始化简介》
https://blog.csdn.net/xiongtiancheng/article/details/79418188
initrd 与initramfs
initrd即 init ramdisk,是一种用ram模拟disk设备的根文件系统存放方式。需要制定格式和大小。
启动参数需要类似于 initrd=0x31000000,0x200000 root=/dev/ram rw init=/linuxrc 这样的启动参数。
利用initrd内核在启动阶段可以顺利的加载设备驱动程序,然而initrd存在以下缺点:
-
initrd大小是固定的,例如上面的压缩之前的initrd大小是4M(4k*1024),假设您的根目录(上例中的miniroot/)总大小仅仅是 1M,它仍然要占用4M的空间。如果您在dd阶段指定大小为1M,后来发现不够用的时候,必须按照上面的步骤重新来一次。
-
initrd是一个虚拟的块设备,在上面的例子中,您可是使用fdisk对这个虚拟块设备进行分区。在内核中,对块设备的读写还要经过缓冲区管理模块,也 就是说,当内核读取initrd中的文件内容时,缓冲区管理层会认为下层的块设备速度比较慢,因此会启用预读和缓存功能。这样initrd本身就在内存 中,同时块设备缓冲区管理层还会保存一部分内容。 为了避免上述缺点,于是出现了initramfs,它的作用和initrd类似,您可以使用下面的方法来制作一个initramfs:
initramfs
make menuconfig中配置以下选项就可以了:
General setup --->
[*] Initial RAM filesystem and RAM disk (initramfs/initrd) support
(../rootfs_dir/) Initramfs source file(s)
initramfs方式使得编译出的内核就包含了rootfs,在vmlinux ELF中作为一个段存在。
#ifdef CONFIG_BLK_DEV_INITRD
#define INIT_RAM_FS \
. = ALIGN(4); \
VMLINUX_SYMBOL(__initramfs_start) = .; \
KEEP(*(.init.ramfs)) \
. = ALIGN(8); \
KEEP(*(.init.ramfs.info))
#else
#define INIT_RAM_FS
#endif
initrd 和 initramfs在内核中的处理
1. initrd的位置获取:扫描位于chosen节点的 linux,initrd-start 和 linux,initrd-end
early_init_dt_check_for_initrd(node);
2. initramfs位置位于链接脚本中,编译时确定
《Linux内核Ramdisk(initrd)机制 》 https://blog.csdn.net/ruixj/article/details/3772752