第一句子网 - 唯美句子、句子迷、好句子大全
第一句子网 > Exynos4412 移植针对Samsung的Linux-6.1(二)SD卡驱动——解决无法挂载SD卡的根文件系统

Exynos4412 移植针对Samsung的Linux-6.1(二)SD卡驱动——解决无法挂载SD卡的根文件系统

时间:2020-11-19 11:38:55

相关推荐

Exynos4412 移植针对Samsung的Linux-6.1(二)SD卡驱动——解决无法挂载SD卡的根文件系统

系列文章目录

Exynos4412 移植针对Samsung的Linux-6.1(一)下载、配置、编译Linux-6.1Exynos4412 移植针对Samsung的Linux-6.1(二)SD卡驱动——解决无法挂载SD卡的根文件系统Exynos4412 移植针对Samsung的Linux-6.1(三)SD卡驱动——解决mmc0: Timeout waiting for hardware interrupt.Exynos4412 移植针对Samsung的Linux-6.1(四)NandFlash卡驱动Exynos4412 移植针对Samsung的Linux-6.1(五)DM9000网卡驱动

Exynos4412 移植针对Samsung的Linux-6.1(二)SD卡驱动

系列文章目录1、检查Linux内核的配置2、修改设备树3、解决无法挂载SD卡的根文件系统

Linux对于SD的支持是很全面的、很完善的。按道理来说,移植SD卡应该很简单。但是,我在移植SD卡驱动的时候,碰到了2个问题:

加载SDMMC驱动正常,但是无法发现SD卡无法挂载SD卡上的根文件系统

解决以上问题仍然花费了很长时间解决问题。问题的解决,关键是对设备树的修改。现记录下来,供大家参考以避坑。

由电路图可以看出,SD卡用到了CLK、CMD、DATA和CD这4类引脚。WP引脚是写保护,电路上是接地的,根本就不起作用。我这次出问题,就出在CD这个引脚上。CD引脚是用来检测是否插入SD卡的,当SD卡插入时引脚电平会被拉低。

另外,开发板上是接到了SDMMC2控制器上。

1、检查Linux内核的配置

执行了make exynos_defconfig之后,默认是配置加载SDMMC驱动的。但是,还是检查一下为好。有2个地方,一是Device Drivers ;另一个是File systems,要想支持中文还得选上Simplified Chinese charset 。

Device Drivers —>

<*> MMC/SD/SDIO card support —>

< > ARM AMBA Multimedia Card Interface support

<*> Secure Digital Host Controller Interface support

< > SDHCI platform and OF driver helper

<*> SDHCI support on Samsung S3C/S5P/Exynos SoC

[*] DMA support on S3C SDHCI

< > MMC/SD/SDIO over SPI

<*> Synopsys DesignWare Memory Card Interface

File systems —>

[ ] Validate filesystem parameter description

<*> Second extended fs support

[ ] Ext2 extended attributes

< > The Extended 3 (ext3) filesystem

<*> The Extended 4 (ext4) filesystem

-*- Native language support —>

<*> Simplified Chinese charset (CP936, GB2312)

<*> NLS UTF-8

2、修改设备树

SDMMC设备树的写法,根据开发板的不同,有不同的写法。

例1:来自基于tiny4412的Linux内核移植 – SD卡驱动移植(五) 。这篇博文中,目标板是tiny4412,作者碰到了问题:

[ 2.245838] s3c-sdhci 12530000.sdhci: No vmmc regulator found[ 2.251358] s3c-sdhci 12530000.sdhci: No vqmmc regulator found

原因是设备树中没有为sdhc2设置vmmc或者vqmmc。这两个是关于regulator的。该作者采用的设备树如下:

regulators {compatible = "simple-bus";#address-cells = <1>;#size-cells = <0>;mmc_reg: regulator@0 {compatible = "regulator-fixed";reg = <0>;regulator-name = "VMEM_VDD_2.8V";regulator-min-microvolt = <2800000>;regulator-max-microvolt = <2800000>;enable-active-high;};};&sdhci_2 {bus-width = <4>;pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_cd &sd2_bus4>;pinctrl-names = "default";vmmc-supply = <&mmc_reg>;status = "okay";//status = "disabled";};

regulator与电源管理有关。但是,我的开发板上没有电源管理芯片,所以这样的写法复制到我的dts文件中,会语法错误,编译不通过。

例2:Documentation/devicetree/bindings/mmc/samsung,s3c6410-sdhci.yaml

帮助文档的示例如下:

66#include <dt-bindings/clock/exynos4.h>67#include <dt-bindings/gpio/gpio.h>68#include <dt-bindings/interrupt-controller/arm-gic.h>69 70mmc@12510000 {71 compatible = "samsung,exynos4210-sdhci";72 reg = <0x12510000 0x100>;73 interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;74 clocks = <&clock CLK_SDMMC0>, <&clock CLK_SCLK_MMC0>;75 clock-names = "hsmmc", "mmc_busclk.2";76 bus-width = <4>;77 cd-gpios = <&gpx3 4 GPIO_ACTIVE_LOW>;78 pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_bus4 &sdhci2_cd>;79 pinctrl-names = "default";80 vmmc-supply = <&ldo21_reg>;81};

以上第70 ~ 75行,在arch/arm/boot/dts/exynos4.dtsi中已经有了,只需要引用exynos4.dtsi就可以。可以看出,例子中添加了第77~80行的属性。

我按照上述属性修改我的设备树,如下:

77 /* SD card deviceTree node78 * sdhci_2: sdhci@1253000079 */80 &sdhci_2 {81pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_bus4 &sd2_cd>;82pinctrl-names = "default";83samsung,bus-width = <4>;84samsung,timing = <1 2 3>;85cd-gpios = <&gpk2 2 0>;86wp-gpios = <&gpx0 5 0>;87status = "okay";88 };

虽然dts编译通过了,但是Linux启动时,显示加载了驱动,但是没有找到SD卡。

[ 2.277294][ T9] of_get_named_gpiod_flags: parsed 'cd-gpios' property of node '/soc/mmc@12530000[0]' - status (0)[ 2.294318][ T9] s3c-sdhci 12530000.mmc: clock source 2: mmc_busclk.2 (20000000 Hz)[ 2.308484][ T9] s3c-sdhci 12530000.mmc: GPIO lookup for consumer cd[ 2.319385][ T9] s3c-sdhci 12530000.mmc: using device tree for GPIO lookup[ 2.326584][ T9] of_get_named_gpiod_flags: parsed 'cd-gpios' property of node '/soc/mmc@12530000[0]' - status (0)[ 2.342686][ T9] gpio_stub_drv gpiochip15: Persistence not supported for GPIO 2[ 2.354581][ T9] s3c-sdhci 12530000.mmc: Got CD GPIO[ 2.364380][ T9] s3c-sdhci 12530000.mmc: GPIO lookup for consumer wp[ 2.377609][ T9] s3c-sdhci 12530000.mmc: using device tree for GPIO lookup[ 2.390432][ T9] of_get_named_gpiod_flags: parsed 'wp-gpios' property of node '/soc/mmc@12530000[0]' - status (0)[ 2.400806][ T9] gpio_stub_drv gpiochip32: Persistence not supported for GPIO 5[ 2.416815][ T9] s3c-sdhci 12530000.mmc: Got WP GPIO[ 2.466252][ T9] mmc0: SDHCI controller on samsung-hsmmc [12530000.mmc] using ADMA

其中,有2行错误

[ 2.342686][ T9] gpio_stub_drv gpiochip15: Persistence not supported for GPIO 2[ 2.400806][ T9] gpio_stub_drv gpiochip32: Persistence not supported for GPIO 5

第一行针对cd-gpios = <&gpk2 2 0>;,第二行针对wp-gpios = <&gpx0 5 0>;。查找Linux-6.1的源码,Persistence not supported代表的含义是pin的状态是睡眠或者控制器重置。

@PIN_CONFIG_PERSIST_STATE: retain pin state across sleep or controller reset

后来,我受到启发,想到可能是cd-gpios的属性设置不正确,于是把第85行cd-gpios属性注释掉,问题就解决了。CBT4412开发板的可行SDMMC设备树如下:

77 /* SD card deviceTree node78 * sdhci_2: sdhci@1253000079 */80 &sdhci_2 {81pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_bus4 &sd2_cd>;82pinctrl-names = "default";83samsung,bus-width = <4>;84samsung,timing = <1 2 3>;85// cd-gpios = <&gpk2 2 0>;86wp-gpios = <&gpx0 5 0>;87status = "okay";88 };

Linux启动结果:

[ 2.465081][ T9] mmc0: SDHCI controller on samsung-hsmmc [12530000.mmc] using ADMA[ 2.700852][ T35] mmc0: new high speed SD card at address 0002[ 2.732352][ T35] mmcblk0: mmc0:0002 968 MiB [ 2.732992][ T1] /dev/root: Can't open blockdev[ 2.739237][ T1] VFS: Cannot open root device "mmcblk0p3" or unknown-block(0,0): error -6[ 2.742335][ T35] mmcblk0: p1 p2 p3[ 2.880395][ T1] driver: mmcblk[ 2.888522][ T1] b301 10240 mmcblk0p1 c5a42637-01[ 2.888534][ T1] [ 2.896680][ T1] b302614400 mmcblk0p2 c5a42637-02[ 2.896691][ T1] [ 2.904839][ T1] b303363008 mmcblk0p3 c5a42637-03[ 2.904850][ T1] [ 2.913065][ T1] Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)

3、解决无法挂载SD卡的根文件系统

此时,无法完全启动Linux,显示无法挂载SD卡上的根文件系统

Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)

原因是挂载根文件系统太早了,此时SD卡还没有挂载完成。

解决方法也很简单,修改BootLoader的启动参数,增加rootwait就可以。如下:

setenv bootargs root=/dev/mmcblk0p3 rw rootfstype=ext4 init=/linuxrc console=ttySAC0,115200n8 rootwait

启动结果如下:

[ 2.699872][ T35] mmc0: new high speed SD card at address 0002[ 2.729229][ T1] Waiting for root device /dev/mmcblk0p3...[ 2.730965][ T35] mmcblk0: mmc0:0002 968 MiB [ 2.746932][ T35] mmcblk0: p1 p2 p3[ 3.311368][ T1] EXT4-fs (mmcblk0p3): recovery complete[ 3.314494][ T1] EXT4-fs (mmcblk0p3): mounted filesystem with ordered data mode. Quota mode: disabled.[ 3.314748][ T1] VFS: Mounted root (ext4 filesystem) on device 179:3.[ 3.316175][ T1] devtmpfs: mounted[ 3.317624][ T1] Freeing unused kernel image (initmem) memory: 1024K[ 3.321581][ T1] Run /linuxrc as init process[ 3.325766][ T1] with arguments:[ 3.329340][ T1]/linuxrc[ 3.332590][ T1] with environment:[ 3.336371][ T1]HOME=/[ 3.339408][ T1]TERM=linuxcan't run '/etc/init.d/rcS': No such file or directoryPlease press Enter to activate this console. / # lsbin etc.oldlinuxrcproc tmpdev home mk_mod_.sh sbin usretc lib mnt sys var/ #

至此,SD卡移植完成。总结一下:

还是要仔细分析错误信息一般来说,Linux的驱动已经比较完善,出错还是首先看看设备树的写法是否有误,可以结合compatible查看驱动程序中查看需要设置哪些属性。

你还有什么启发,请评论区留言。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。