第2阶段:启用eMMC/SD卡设备

目标

上一章节只有 initramfs 的临时文件系统(RAM),断电就没了。手机有 16GB 的 eMMC 芯片焊在主板上,我们需要内核识别它,为后续挂载持久化 rootfs 做准备。

DTS 改动分析

需要写多少 DTS?

答案:两行

1
2
&sdhc_1 { status = "okay"; };   // eMMC — 焊死在主板上的内部存储
&sdhc_2 { status = "okay"; }; // SD 卡 — 外部卡槽(Y927 有 TF 卡槽)

不需要写 GPIO、不需要写 pinctrl、不需要写寄存器地址。原因和阶段0的骨架 DTS 一样——这一切早在 msm8916.dtsimsm8916-pm8916.dtsi 里定义好了。

msm8916.dtsi(SoC 级)第 2170-2190 行为 sdhc_1 写了:

属性 含义
reg 0x07824900 / 0x07824000 eMMC 控制器寄存器物理地址
interrupts GIC_SPI 123 / GIC_SPI 138 中断线
clocks GCC_SDCC1_* eMMC 专用时钟
pinctrl-0 sdc1_default 引脚配置(sdc1_clk/sdc1_cmd/sdc1_data,专用 SDC 功能引脚,在 msm8916.dtsi 第 1466-1500 行定义)
bus-width 8 8 位数据总线
non-removable 标记不可插拔(焊死的)
status "disabled" 板级 DTS 唯一要改的

msm8916-pm8916.dtsi(PMIC 级)第 37-40 行给 sdhc_1 配好了供电:

1
2
3
4
&sdhc_1 {
vmmc-supply = <&pm8916_l8>; // 2.9V 核心电压
vqmmc-supply = <&pm8916_l5>; // 1.8V I/O 电压
};

SD 卡(sdhc_2)同理——SoC dtsi 已定义 4 位总线 + pinctrl,PMIC dtsi 已配好 pm8916_l11/pm8916_l12 供电。唯一多出来的板级信息是 card detect GPIO(SD 卡槽的物理检测脚),这个确实是板子决定的:

1
2
3
4
&sdhc_2 {
status = "okay";
cd-gpios = <&tlmm 38 GPIO_ACTIVE_LOW>; // Y927 TF 卡槽检测脚
};

msm8916-mtp.dts 参考板也配了 cd-gpios = <&tlmm 38 ...>,Y927 复用了同样的 GPIO。

DTS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
// SPDX-License-Identifier: GPL-2.0-only

/dts-v1/;

#include "msm8916-pm8916.dtsi"
#include <dt-bindings/gpio/gpio.h>

/ {
model = "vivo Y927 (PD1410V)";
compatible = "vivo,y927", "qcom,msm8916";
chassis-type = "handset";

aliases {
mmc0 = &sdhc_1; // eMMC 固化为 /dev/mmcblk0
mmc1 = &sdhc_2; // SD 卡 固化为 /dev/mmcblk1
};

usb_id: usb-id {
compatible = "linux,extcon-usb-gpio";
id-gpios = <&tlmm 110 GPIO_ACTIVE_HIGH>;
pinctrl-names = "default";
pinctrl-0 = <&usb_id_default>;
};
};

&usb {
dr_mode = "peripheral";
extcon = <&usb_id>, <&usb_id>;
status = "okay";
};

&usb_hs_phy {
extcon = <&usb_id>;
status = "okay";
};

&tlmm {
usb_id_default: usb-id-default {
pins = "gpio110";
function = "gpio";
drive-strength = <8>;
bias-pull-up;
};
};

&sdhc_1 {
status = "okay"; // eMMC(内部存储)
};

&sdhc_2 {
status = "okay"; // SD 卡(TF 卡槽)
cd-gpios = <&tlmm 38 GPIO_ACTIVE_LOW>;
};

内核配置

不需要改动。msm8916_defconfig 已包含:

1
2
3
4
CONFIG_MMC=y
CONFIG_MMC_SDHCI=y
CONFIG_MMC_SDHCI_PLTFM=y
CONFIG_MMC_SDHCI_MSM=y # MSM8916 的 SDHC 控制器驱动

initramfs

沿用第1阶段的 initramfs(USB serial 交互 shell),无需修改。第2阶段只是在 DTS 中启用了 eMMC/SD 控制器,内核启动后 /dev/mmcblk0* 会自然出现,不需要 init 脚本做任何事。

编译 Linux 内核

1
2
cd ~/y927/linux
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- -j$(nproc) Image.gz dtbs

构建 boot.img 文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
cd ~/y927/linux

# 拼接内核 + DTB
cat arch/arm64/boot/Image.gz \
arch/arm64/boot/dts/qcom/msm8916-vivo-y927.dtb \
> vmlinuz-dtb

~/y927/lk2nd/lk2nd/scripts/mkbootimg \
--kernel vmlinuz-dtb \
--ramdisk $HOME/y927/initramfs/initramfs-phase-1.cpio.gz \
--cmdline "console=ttyGS0,115200 panic=1" \
--base 0x80000000 \
--kernel_offset 0x00008000 \
--ramdisk_offset 0x01000000 \
--second_offset 0x00f00000 \
--tags_offset 0x00000100 \
--pagesize 2048 \
--header_version 0 \
--output boot-phase2.img

刷入 boot.img 文件

1
2
fastboot flash boot boot-phase2.img
fastboot reboot

测试

1
sudo picocom -b 115200 /dev/ttyACM0

输入busybox fdisk -l可以识别到16GB eMMC和8GB SD卡了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Disk /dev/mmcblk0: 14.5G, 15634268160 bytes, 30535680 sectors
1893 cylinders, 256 heads, 63 sectors/track
Units: cylinders of 16128 * 512 = 8257536 bytes

Device Boot StartCHS EndCHS StartLBA EndLBA Sectors Size Id Type
/dev/mmcblk0p1 0,0,1 1023,255,63 1 4294967295 4294967295 2047G ee EFI GPT
Disk /dev/mmcblk1: 7619M, 7989100544 bytes, 15603712 sectors
3504 cylinders, 73 heads, 61 sectors/track
Units: cylinders of 4453 * 512 = 2279936 bytes

Device Boot StartCHS EndCHS StartLBA EndLBA Sectors Size Id Type
/dev/mmcblk1p1 0,130,3 971,72,61 8192 15603711 15595520 7615M b Win95 FAT32
Disk /dev/mmcblk0boot0: 4096K, 4194304 bytes, 8192 sectors
128 cylinders, 4 heads, 16 sectors/track
Units: cylinders of 64 * 512 = 32768 bytes

Disk /dev/mmcblk0boot0 doesn't contain a valid partition table
Disk /dev/mmcblk0boot1: 4096K, 4194304 bytes, 8192 sectors
128 cylinders, 4 heads, 16 sectors/track
Units: cylinders of 64 * 512 = 32768 bytes

Disk /dev/mmcblk0boot1 doesn't contain a valid partition table

第3阶段:真正的DRM显示(HX8394A 面板驱动移植)

TODO