android文件系统\busybox文件系统的启动介绍

快速链接:
.
👉👉👉 个人博客笔记导读目录(全部) 👈👈👈

1、android文件系统(rootfs)
在uboot中检查启动参数,如果是normal mode,则load boot.img以及boot.img中的ramdisk,如果是recovery mode,则会load recovery.img以及recovery.img中的ramdisk。

注意:如果开启了system_as_root功能(在android9.0及其后的版本中要求开启了),原先boot.img中的ramdisk搬移到了system.img中。开启system_as_root功能,需要在cmdline中添加"skip_initramfs"参数
kernel/linux/init/initramfs.c中的populate_rootfs()检查到了skip_initramfs后,不去解压uboot解析后的ramdisk,而是创建了一个default_rootfs()空目录,然后将整个system.img mount到根目录.

(normal mode时)

acct       charger data         init                init.currenttest.rc init.recovery.aquilac_evb.rc init.zygote64_32.rc oem     sbin    system                 verity_key 
bin        config  default.prop init.aquilac_evb.rc init.environ.rc     init.usb.configfs.rc         lost+found          proc    sdcard  ueventd.aquilac_evb.rc 
bugreports cores   dev          init.ata.rc         init.factory.rc     init.usb.rc                  mnt                 product storage ueventd.rc             
cache      d       etc          init.calibration.rc init.rc             init.zygote32.rc             odm                 res     sys     vendor

(recovery mode时)

acct       charger data         init                         odm                    proc         root     sideload system_root            vendor                   
bin        config  default.prop init.rc                      oem                    product      sbin     storage  tmp                    vendor_file_contexts     
bugreports cores   dev          init.recovery.aquilac_evb.rc plat_file_contexts     prop.default sdcard   sys      ueventd.aquilac_evb.rc vendor_property_contexts 
cache      d       etc          mnt                          plat_property_contexts res          sepolicy system   ueventd.rc             verity_key  

2、busybox文件系统(rootfs)

xxxx

3、android init的启动 / busybox init的启动

#cat /proc/cmdline

firmware_class.path=/vendor/firmware uart_dma keep_dbgclk_on clk_ignore_unused log_buf_len=1M printk.devkmsg=on pmic_status=0x2 lcd_id=ID1901, fb_base=FB17e200000, fb_size=SZ7f8000, lcd_config=CF101. androidboot.serialno=0123456789 board_id=2 crash_page=0x10c040000 init=/init skip_initramfs rootwait root=/dev/dm-0 dm="system none ro,0 1 android-verity /dev/mmcblk0p20" veritykeyid=id:7e4333f9bba00adfe0ede979e28ed1920492b40f buildvariant=userdebug printk_nc earlycon nokaslr androidboot.dtbo_idx=0 androidboot.hardware=aquilac_evb androidboot.selinux=enforcing

在kernel_init()中:
(1)先检查ramdisk_execute_command变量(对应的cmdline中的rdinit参数,该参数是一个可执行文件的名字),如果存在则执行.
(2)、再检查execute_command(对应的cmdline中的init参数,该参数是一个可执行文件的名字),如果存在则执行,然后返回.
(3)、如果步骤(2)不存在,则会尝试执行"/sbin/init"、“/etc/init”、“/bin/init”、“/bin/sh”

vim kernel/linux/init/main.c
static int __ref kernel_init(void *unused)
{
	int ret;

	kernel_init_freeable();
	/* need to finish all async __init code before freeing the memory */
	async_synchronize_full();
	free_initmem();
	mark_readonly();
	system_state = SYSTEM_RUNNING;
	numa_default_policy();

	flush_delayed_fput();

	printk("kernel_init enter\n");
	if (ramdisk_execute_command) {
		ret = run_init_process(ramdisk_execute_command);
		if (!ret)
			return 0;
		pr_err("Failed to execute %s (error %d)\n",
		       ramdisk_execute_command, ret);
	}

	/*
	 * We try each of these until one succeeds.
	 *
	 * The Bourne shell can be used instead of init if we are
	 * trying to recover a really broken machine.
	 */
	if (execute_command) {
		ret = run_init_process(execute_command);
		if (!ret)
			return 0;
		panic("Requested init %s failed (error %d).",
		      execute_command, ret);
	}
	 printk("kernel_init execute_command after\n");
	if (!try_to_run_init_process("/sbin/init") ||
	    !try_to_run_init_process("/etc/init") ||
	    !try_to_run_init_process("/bin/init") ||
	    !try_to_run_init_process("/bin/sh"))
		return 0;

	panic("No working init found.  Try passing init= option to kernel. "
	      "See Linux Documentation/init.txt for guidance.");
}

在android的设计中,根目录下的init就是system/core/init/init.cpp编译生成的可执行文件,并且cmdline添加了"init=/init"参数, 自然而然的就运行了android的init,接下来就是执行parse init.rc、load property、selinux等程序。android init的流程就不在本文介绍了。

在非android系统的设计中(如busybox文件系),依然在cmdline添加了"init=/init"参数,但此时根目录下的init是busybox中的init程序

busybox init程序会依次调用:
a. 为init设置信号处理过程
b. 初始化控制台
c. 剖析/etc/inittab文件
d. 执行系统初始化命令行,缺省情况下会使用/etc/init.d/rcS
e. 执行所有导致init暂停的inittab命令(动作类型:wait)
f. 执行所有仅执行一次的inittab(动作类型:once)

其中,/etc/inittab不是linux shell脚本,有一定的语法规则,如下是我系统中的inittab:

This is run first except when booting in single-user mode.

#Startup the system
::sysinit:/bin/mount -t proc proc /proc
::sysinit:/bin/mount -t sysfs sysfs /sys
::sysinit:/bin/mount -t devtmpfs devtmpfs /dev
::sysinit:/bin/mount -o remount,rw /
::sysinit:/bin/mkdir -p /dev/pts
::sysinit:/bin/mount -t devpts devpts /dev/pts
::sysinit:/bin/mount -a

::sysinit:/etc/init.d/rcS

#Stuff to do before rebooting
::ctrlaltdel:/sbin/reboot
::shutdown:/etc/init.d/rcK
::shutdown:/sbin/swapoff -a
::shutdown:/bin/umount -a -r

#Stuff to do when restarting the init process
::restart:/sbin/init

#set hostname
null::sysinit:/bin/busybox hostname -F /etc/hostname
ttyS0::respawn:-/bin/sh

在这里插入图片描述
《ARMv8/ARMv9架构学习系列课程》全系列,共计52节课,超16h的视频课程

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Arm精选

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值