Android O/P 版本以来,谷歌加入了system-as-root的特性,此时ramdisk和system是一起放在同一个system.img镜像中的。而系统起来之后也就不存在system分区了,而是直接把system镜像挂载到/根目录上。那么这个操作是怎么进行的呢?
system.img默认是需要使能dm-verity来挂载的,那么这就涉及到如何使能dm-verity来挂载/根分区。还有一个重要的点,如果我们想要禁用dm-verity功能又要如何操作,这又涉及更深的层次,如果可配置/根分区的挂载方式为dm-verity或者非dm-verity方式
根目录的挂载必须要由kernel去完成了。因为根目录挂载是先于init的运行的,没有根目录就不会有init。那么如何由kernel去挂载system.img镜像呢?
由此我们就通过传入不同的cmdline的方式来启动kernel,进而挂载根目录,也就是system.img镜像。
Kernel command line: console=tty0 console=ttyS0,921600n1 vmalloc=496M slub_max_order=0 slub_debug=OFZPU androidboot.hardware=mt6771 firmware_class.path=/vendor/firmware loop.max_part=7 has_battery_removed=0 maxcpus=8 androidboot.verifiedbootstate=green skip_initramfs rootwait ro init=/init root=/dev/dm-0 dm="system none ro,0 1 android-verity PARTUUID=a4da8f1b-fe07-433b-95cb-84a5f23e477b " androidboot.veritymode=enforcing bootopt=64S3,32N2,64N2 buildvariant=user veritykeyid=id:e58276dac7669ff2e60185d6763d16bf6d898136 androidboot.atm=disabled androidboot.meta_log_disable=0 androidboot.dtbo_idx=0 lpddr_used_index=0
1、 分别查找内核代码关键字:
dm= veritykeyid=
[ 2.883032] <7>.(4)[1:swapper/0]device-mapper: init: attempting early device configuration.
[ 2.883764] <7>.(5)[1:swapper/0]device-mapper: init: adding target '0 1 android-verity PARTUUID=a4da8f1b-fe07-433b-95cb-84a5f23e477b '
[ 2.883783] <7>.(5)[1:swapper/0]device-mapper: android-verity: key:id:7e4333f9bba00adfe0ede979e28ed1920492b40f dev:PARTUUID=a4da8f1b-fe07-433b-95cb-84a5f23e477b
[ 2.893211] <7>.(0)[1:swapper/0]device-mapper: android-verity: bio magic_number:2952900609 protocol_version:0 table_length:254
[ 2.893223] <7>.(0)[1:swapper/0]device-mapper: android-verity: verity_table: 1 /dev/block/platform/bootdevice/by-name/system /dev/block/platform/bootdevice/by-name/system 4096 4096 903183 903183 sha256 01d43da3f751712bd6c7a105a2a65e9cc6575b5658e1d00fea90b8c83c5257f3 aee087a5be3b982978c923f566a94613496b417f2af592639bc80d141e34dfe7
[ 2.894313] <7>.(0)[1:swapper/0]device-mapper: android-verity: Signature verification success
[ 2.894327] <7>.(0)[1:swapper/0]device-mapper: android-verity: Data sectors 7225464
[ 2.895497] <7>.(5)[1:swapper/0]device-mapper: android-verity: android-verity mounted as verity target
[ 2.895650] <7>.(4)[1:swapper/0]device-mapper: init: dm-0 is ready
kernel-4.4\drivers\md\dm-android-verity.c
__setup("veritykeyid=", verity_keyid_param);
kernel-4.4\init\do_mounts_dm.c
__setup("dm=", dm_setup);
static int __init dm_setup(char *str)
2、 verity pub key
kernel-4.4/certs$ ls
Kconfig ko_test_prvk.pem
Makefile system_keyring.c
system_certificates.S verity.x509.pem
这里将Puk 编译进内核,并挂载在 /目录下, 但system验签时,使用的是代码段里的。
key_ref = keyring_search(make_key_ref(system_trusted_keyring, 1),
&key_type_asymmetric, key_id);
key = key_ref_to_ptr(key_ref);
3、 veritykeyid= 来源
build/make/tools/releasetools/sign_target_files_apks.py
# Extract keyid using openssl command.
p = common.Run(["openssl", "x509", "-in", key_path, "-text"],
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
keyid, stderr = p.communicate()
keyid = re.search(
r'keyid:([0-9a-fA-F:]*)', keyid).group(1).replace(':', '').lower()
print("Replacing verity keyid with {}".format(keyid))
common.ZipWriteStr(output_zip, "BOOT/cmdline", out_cmdline)
编译log(可手动敲下命令):veritykeyid=id:\`openssl x509 -in build/target/product/security/verity.x509.pem -text | grep keyid
X509v3 Authority Key Identifier:
keyid:7E:43:33:F9:BB:A0:0A:DF:E0:ED:E9:79:E2:8E:D1:92:04:92:B4:0F
4、下一篇,补充 system 到底是如何去dm验证的。