[Linux] deferred probe pending

3 minute read

deferred probe pending…

업무 중에 처음 보는 로그가 있어서 기록용으로 씁니다.

상황은 오드로이드 커널 6.6의 dtb를 작업하기 위해 커널 버전 업그레이드 하고,,
커널 설치한 뒤, 리부팅 중에 나타났습니다.

Loading, please wait...
Starting version 5:245.4-4ubuntu3+202310161612~focal
[    2.766964] rockchip-vop2 fe040000.vop: Adding to iommu group 2
Begin: Loading essential drivers ... done.
Begin: Running /scripts/init-premount ... done.
Begin: Mounting root file system ... Begin: Running /scripts/local-top ... done.
Begin: Running /scripts/local-premount ... done.
[   13.028331] platform fdc20000.syscon:io-domains: deferred probe pending
[   13.028943] platform fe010000.ethernet: deferred probe pending
[   13.029461] platform fe0a0000.hdmi: deferred probe pending
[   13.029947] platform fe2b0000.mmc: deferred probe pending
Begin: Waiting for root file system ... Begin: Running /scripts/local-block ... done.
done.
Gave up waiting for root file system device.  Common problems:
 - Boot args (cat /proc/cmdline)
   - Check rootdelay= (did the system wait long enough?)
 - Missing modules (cat /proc/modules; ls /dev)
ALERT!  /dev/disk/by-uuid/8b892d53-d29b-447f-9a2e-0f9f3d52ec73 does not exist.  Dropping to a shell!


BusyBox v1.30.1 (Ubuntu 1:1.30.1-4ubuntu6.4) built-in shell (ash)
Enter 'help' for a list of built-in commands.

(initramfs)

어려운 내용은 아니고,
사실 확인할 필요없이 로그에 나타난 플랫폼 디바이스들이 probe 되지 않았습니다.
그래도 내용을 찾아봤습니다.

이 아티클 내용을 보면 대충 이렇습니다.

커널이 드라이버를 로드할 때, 드라이버 마다 특별히 요구하는 드라이버들이 존재한다.
빌드 시 서로 다른 하드웨어 간에 어떤 종속성이 있는지 알 수 없다.
커널 입장에서는 드라이버가 한 두가지가 아니기 때문에, 필요한 드라이버들을 순서대로 추가할 수 없다.


위 상황을 해결하기 위해 드라이버를 probe() 할 수 없으면 -EAGAIN 을 반환하여 연기합니다.
그리고 그 드라이버들을 특정 리스트로 관리합니다.

하지만 커널로그를 보면, 끝내 드라이버 로드에 실패하고 BusyBox 로 넘어갑니다.

로그 중에 mmc 드라이버 probe에 실패한 부분이 나타났습니다.
커널이 올라가 있는 저장장치를 인식하지 못해 결국 커널에 진입하지 못한것입니다.

[   13.029947] platform fe2b0000.mmc: deferred probe pending


먼저, dtb를 확인했습니다. 소스하드커널 github에 있습니다.
arch/arm64/boot/dts/rockchip/rk356x.dtsi
arch/arm64/boot/dts/rockchip/rk3566-odroid-m1s.dts 입니다.

        sdmmc0: mmc@fe2b0000 {
                compatible = "rockchip,rk3568-dw-mshc", "rockchip,rk3288-dw-mshc";
                reg = <0x0 0xfe2b0000 0x0 0x4000>;
                interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&cru HCLK_SDMMC0>, <&cru CLK_SDMMC0>,
                         <&cru SCLK_SDMMC0_DRV>, <&cru SCLK_SDMMC0_SAMPLE>;
                clock-names = "biu", "ciu", "ciu-drive", "ciu-sample";
                fifo-depth = <0x100>;
                max-frequency = <150000000>;
                resets = <&cru SRST_SDMMC0>;
                reset-names = "reset";
                status = "disabled";
        };
&sdmmc0 {
        bus-width = <4>;
        cap-sd-highspeed;
        cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>;
        disable-wp;
        pinctrl-names = "default";
        pinctrl-0 = <&sdmmc0_bus4 &sdmmc0_clk &sdmmc0_cmd &sdmmc0_det>;
        sd-uhs-sdr104;
        vmmc-supply = <&vcc3v3_sys>;
        vqmmc-supply = <&vccio_sd>;
        status = "okay";
};

mmc 드라이버를 사용하기 위해서는
gpio0, sdmmc0_bus4 , sdmmc0_clk , sdmmc0_cmd , sdmmc0_det , vcc3v3_sys , vccio_sd 가 필요합니다.

로그를 다시 들여다 봤을 때, 캐치할 수 있었습니다.

[   13.028331] platform fdc20000.syscon:io-domains: deferred probe pending
[   13.028943] platform fe010000.ethernet: deferred probe pending
[   13.029461] platform fe0a0000.hdmi: deferred probe pending
[   13.029947] platform fe2b0000.mmc: deferred probe pending


mmc 장치사용에 필요한 것들 중에서, 겹치는 부분이 눈에 보였습니다.
io-domains
pmic 쪽이 의심되었고 코드를 확인해 봤습니다.

&pmu_io_domains {
        pmuio1-supply = <&vcc3v3_pmu>;
        pmuio2-supply = <&vcc3v3_pmu>;
        vccio1-supply = <&vccio_acodec>;
        vccio2-supply = <&vcc_1v8>;
        vccio3-supply = <&vccio_sd>;
        vccio4-supply = <&vcc_3v3>;
        vccio5-supply = <&vcc_3v3>;
        vccio6-supply = <&vcc_3v3>;
        vccio7-supply = <&vcc_3v3>;
        status = "okay";
};
        rk809: pmic@20 {
                compatible = "rockchip,rk809";
                reg = <0x20>;
                ...
                regulators {
                        vdd_logic: DCDC_REG1 {
                        ...
                        vcc3v3_pmu: ... {
                        ...
                        vccio_sd: ... {
                        ...
        }


드라이버가 제대로 로드되었는지 확인했습니다.

$ git grep "rockchip,rk809" | grep drivers
drivers/mfd/rk8xx-i2c.c:        { .compatible = "rockchip,rk809", .data = &rk809_data },
$ cat drivers/mfd/Makefile | grep rk8xx-i2c
obj-$(CONFIG_MFD_RK8XX)         += rk8xx-core.o
obj-$(CONFIG_MFD_RK8XX_I2C)     += rk8xx-i2c.o
obj-$(CONFIG_MFD_RK8XX_SPI)     += rk8xx-spi.o


커널 config를 확인했는데 역시나 CONFIG_MFD_RK8XX_I2CCONFIG_MFD_RK8XX 이 없었습니다.

6.1 커널의 config를 그대로 사용했었는데 6.6으로 올라가면서 config가 변경 되었던 것이었습니다.

6.1 에서는 이렇게 사용되었습니다.

$ git checkout odroid-6.1.y
$ git grep "rockchip,rk809" | grep drivers
drivers/mfd/rk808.c:    { .compatible = "rockchip,rk809" },
drivers/mfd/rk808.c:        of_device_is_compatible(np, "rockchip,rk809")) {
$ cat drivers/mfd/Makefile | grep rk808
obj-$(CONFIG_MFD_RK808)         += rk808.o

이 부분에서 차이가 났던 것이었습니다.

CONFIG_MFD_RK8XX_I2C=yCONFIG_MFD_RK8XX=y 을 config에 추가해서 다시 빌드하고 리부팅했습니다.

부팅 되는 것을 확인했습니다.

+ 6.6 커널에서는 6.1 에서도 사용했었던 .scmversion 을 사용하지 않습니다.

Leave a comment