OpenWrt Forum Archive

Topic: SD card as extroot on dir-300 b1 mod SD [SOLVED]

The content of this topic has been archived on 16 Mar 2018. There are no obvious gaps in this topic, but there may still be some posts missing at the end.

Hi guys!
Thank you for great OpenWRT!

In short I have DIR-300B1 SD Mod with Chaos Culmer (r48430) and I've already solved all hardware problems but when I try to make extroot I have a problem because not clearly understand boot logic. Please help me.

What we have:
Router boot and script /etc/init.d/mmc_over_gpio successfully create /dev/mmcblk0p1 (4GB SD card with ext4). I can successfully "mount -t ext4 /dev/mmcblk0p1 /mnt/".

<CUTTED: THIS TEXT DELETE, BECAUSE THE SOLUTION WAS FOUND>

I think the problem in boot process. Please help me to pass final step.

(Last edited by Dirry on 25 Jan 2016, 08:07)

Hello again. I've made Chaos Culmer from source and try again to make extroot for SD card.

Current problem: I don't know how to run /etc/init.d/mmc_over_gpio when system boot. As result mount_root says "device not present" because mmc_over_gpio not running (not created /dev/mmcblk0p1):

[    9.260000] mount_root: loading kmods from internal overlay
[    9.420000] block: attempting to load /tmp/jffs_cfg/upper/etc/config/fstab
[    9.440000] block: extroot: device not present, retrying in 5 seconds
[   14.460000] block: extroot: cannot find device with UUID 6f008146-081d-45e7-a4bf-9618dde1895d
[   14.480000] mount_root: switching to jffs2 overlay

How can I run /etc/init.d/mmc_over_gpio before mount_root ?

I try to read /etc/init.d/mmc_over_gpio and rc.common but it's really complicated for me. I see that mmc_over_gpio script just make files with pinout config, but I don't understand, whats next. How mmc_over_gpio add device to /dev/?

If you know nothing about gpio help me please to debug boot process.

That script reads out the SPI configuration information provided in /etc/config/mmc_over_gpio (so, also configurable via uci) and provides it to the kernel module via configfs. With these informations, the kernel module can instantiate a device entry in /dev.
What the script does is:
* mount configgs (to /config) if not yet done (you can check it by doing "mount | grep configfs" and do it manually by issuing "mkdir -p /config; mount configfs -t configfs /config")
* create an entry in configfs and put in your configuration values:

mkdir -p /config/gpiommc/mmc_over_gpio
echo 10 > /config/gpiommc/mmc_over_gpio/gpio_data_in
echo 11 > /config/gpiommc/mmc_over_gpio/gpio_data_out
echo 12 > /config/gpiommc/mmc_over_gpio/gpio_clock
echo 13 > /config/gpiommc/mmc_over_gpio/gpio_chipselect
echo 0 > /config/gpiommc/mmc_over_gpio/spi_mode
echo 1 > /config/gpiommc/mmc_over_gpio/register

All values above between 10 and 13 should be replaced with the ones corresponding to your configuration. Anyway, you should start by checking if these directory entries exist and the files contain your configured values. Change them appropriately, if necessary and check the kernel output via dmesg.

Now I found (after tests) that /lib/preinit and /lib/functions is load after root_mount. Please tell me if I wrong.

I see only one solution: create kernel module. Please check my logic.

I see in dmesg:

[    9.260000] mount_root: loading kmods from internal overlay
[    9.320000] kmodloader: failed to open /tmp/overlay/upper/etc/modules-boot.d/30-gpio-button-hotplu
g
[    9.260000] mount_root: loading kmods from internal overlay
[    9.420000] block: attempting to load /tmp/jffs_cfg/upper/etc/config/fstab
[    9.440000] block: extroot: device not present, retrying in 5 seconds
[   14.460000] block: extroot: cannot find device with UUID 6f008146-081d-45e7-a4bf-9618dde1895d
[   14.480000] mount_root: switching to jffs2 overlay

It means that if I create /etc/modules.d/ kernel module and place link to it in /etc/modules-boot.d/ then it will be load before root mount. Right? How it works with USB devices?

I need kernel module with this logic:

mkdir -p /config/gpiommc/default
echo 9 > /config/gpiommc/default/gpio_data_in
echo 13 > /config/gpiommc/default/gpio_data_out
echo 8 > /config/gpiommc/default/gpio_clock
echo 0 > /config/gpiommc/default/gpio_chipselect
echo 0 > /config/gpiommc/default/spi_mode
echo 1 > /config/gpiommc/default/register
mount configfs -t configfs /config

Any body help me? Or may be anybody can write this module? Please help.

(May be this source can be used as template - http://projects.qi-hardware.com/index.p … gpiommc.c)

I've found the alternative way to connect SD (instead of configfs):

/home/user/owrt/chaos_calmer/build_dir/toolchain-mipsel_24kec+dsp_gcc-4.8-linaro_uClibc-0.9.33.2/linux-3.18.23/Documentation:

GPIOMMC - Driver for an MMC/SD card on a bitbanging GPIO SPI bus
================================================================

The gpiommc module hooks up the mmc_spi and spi_gpio modules for running an
MMC or SD card on GPIO pins.

Two interfaces for registering a new MMC/SD card device are provided:
A static platform-device based mechanism and a dynamic configfs based interface.


Registering devices via platform-device
=======================================

The platform-device interface is used for registering MMC/SD devices that are
part of the hardware platform. This is most useful only for embedded machines
with MMC/SD devices statically connected to the platform GPIO bus.

The data structures are declared in <linux/mmc/gpiommc.h>.

To register a new device, define an instance of struct gpiommc_platform_data.
This structure holds any information about how the device is hooked up to the
GPIO pins and what hardware modes the device supports. See the docbook-style
documentation in the header file for more information on the struct fields.

Then allocate a new instance of a platform device by doing:

        pdev = platform_device_alloc(GPIOMMC_PLATDEV_NAME, gpiommc_next_id());

This will allocate the platform device data structures and hook it up to the
gpiommc driver.
Then add the gpiommc_platform_data to the platform device.

        err = platform_device_add_data(pdev, pdata, sizeof(struct gpiommc_platform_data));

You may free the local instance of struct gpiommc_platform_data now. (So the
struct may be allocated on the stack, too).
Now simply register the platform device.

        err = platform_device_add(pdev);

Done. The gpiommc probe routine will be invoked now and you should see a kernel
log message for the added device.


Registering devices via configfs
================================
...
...
...

Next level.
I've built gpiommc.ko from source and found that GPIOMMC.KO loads in /etc/modules-boot.d/mmc thus we have this boot alg:

[    9.260000] mount_root: loading kmods from internal overlay
------
GPIOMMC.KO load here!
------
[    9.420000] block: attempting to load /tmp/jffs_cfg/upper/etc/config/fstab
[    9.440000] block: extroot: device not present, retrying in 5 seconds
[   14.460000] block: extroot: cannot find device with UUID 6f008146-081d-45e7-a4bf-9618dde1895d
[   14.480000] mount_root: switching to jffs2 overlay

It means that if we modify gpiommc.c ( http://projects.qi-hardware.com/index.p … /gpiommc.c ) as write in my post #8 then we can try platform_device_add(pdev) for make /dev/mmcblk0p1 and thus we fix the "device not present" error.

Anybody help with code http://projects.qi-hardware.com/index.p … /gpiommc.c ?

In short we need improve:

static int __init gpiommc_modinit(void) {...}

For initialize SD/MMC over GPIO: di=9, do=13, clk=8, cs=0. I see the function gpiommc_probe(struct platform_device *pdev), but don't know, how to make "struct platform_device".

(Last edited by Dirry on 24 Jan 2016, 20:15)

I think you are heading into the wrong direction. Better follow these steps:
1. Install fresh Chaos Calmer image
2. Install and configure kmod-mmc-over-gpio and make sure you can mount and access your storage card
3. Configure extroot for Chaos Calmer by pivoting /overlay

MBS, I already try this way. Step 1-2 was success. Step 3 have no result as I wrote before:

[    9.420000] block: attempting to load /tmp/jffs_cfg/upper/etc/config/fstab
[    9.440000] block: extroot: device not present, retrying in 5 seconds
[   14.460000] block: extroot: cannot find device with UUID 6f008146-081d-45e7-a4bf-9618dde1895d
[   14.480000] mount_root: switching to jffs2 overlay

As you see mount_root not found device ("device not present") and "switching to jffs2 overlay". Kmod-mmc-over-gpio will no help because add SD device to /dev/ going much later mount_root. We must make /dev/ device before mount_root.

Now I've already hack kernel module: wrote C code in gpiommc.c for init my SD card when module init (as I wrote in post #8).  Testing...

I did it! Full extroot pivot-root on DIR-300 B1 SD Mod + Chaos Calmer. First time in the Internet! smile cool

I'll write a manual a bit later.

(Last edited by Dirry on 24 Jan 2016, 23:56)

Guys, please read the fstab section. I think forget something.

If you build from sources, wouldn't it be easier to provide the GPIOs for the different mmc-pins via the menuconfig section?
Kernel modules ---> Other modules ---> kmod-mmc-over-gpio ---> Configuration --->GPIO [DI, DO, CLK, CS] pin

MBS, thank you! Add this to manual.

It can help when use /etc/init.d/gpio_over_mmc. But important for understanding that adding SD card to /dev/ heppends when kernel initalizes gpiommc.ko that contains hardcoded pinout:

    pdata.pins.gpio_di = 9;
    pdata.pins.gpio_do = 13;
    pdata.pins.gpio_clk = 8;
    pdata.pins.gpio_cs = 0;
    pdata.pins.cs_activelow = 1;
    pdata.mode = 0;
    pdata.no_spi_delay = 0;
    pdata.max_bus_speed = 5000000;

OK, menuconfig just adds those values to the config file.
Some other thoughts are to change the parameter delay_root and change mmc_over_gpio start priority from default 90 to something below the one of fstab (40). Easiest way for the latter is to rename the symlink in /etc/rc.d/ from S90... to like S39...

MBS, no it's not a solution. I've tried it. You don't clearly understand how boot works and why I must hack gpio kernel module.

Boot process here:
1. Kernel load modules from /etc/module-boot.d/
2. [After block-mount install] Kernel see /etc/config/fstab for "/" or "/overlay" and mount rootfs if they set
3. Kernel load /lib/preinit/*, /etc/rc.d/* and others script

You understand problem?
Before step 2 no scripts load. Only kernel modules. Thus I've added gpiommc to /etc/modules-boot.d/mmc and hack gpiommc.ko for initialize device /dev/mmcblk0p1 on STEP 1.

(Last edited by Dirry on 26 Jan 2016, 03:19)

Plus.
Why I've faced with problem to mount SD as extroot? Because kernel not load SD and not made device in /dev/ when gpiommc initialize.

How it works with USB devices:
1. When kernel goes to mount_root process it already have device /dev/sda.
2. Kernel see fstab and successfully mounted root to /dev/sda

With hacked SD card step 1 not happend.

So, now we've got solution ) I think it works for any devices with soldered SD.

(Last edited by Dirry on 26 Jan 2016, 03:29)

Finally i've built image "OpenWRT Chaos Calmer dir300b1 factory" for comfort SD card formatting and extrooting. Image contains packages:
* kmod-gpio-over-mmc (patched dirry hack)
* kmod-fs-ext4
* block-mount
* fdisk
* e2fsprogs (mkfs.ext2, mkfs.ext3, mkfs.ext4)

Enjoy on github: https://github.com/Dirry/dir300b1-sdmod-extroot

awesome work mate, impeccable timing too - yesterday ive decided to shuffle few routers around the house and dir300b got me attention, since i forgot the password.. imagine my surprise when ive found sdcard mod on openwrt wiki

there is however slight wink problem with your image

[    9.480000] mount_root: jffs2 not ready yet, using temporary tmpfs overlay
[   30.590000] jffs2: Too few erase blocks (4)
[ 1150.750000] jffs2: Too few erase blocks (4)

Filesystem           1K-blocks      Used Available Use% Mounted on
rootfs                   14604        48     14556   0% /
/dev/root                 2560      2560         0 100% /rom
tmpfs                    14604        64     14540   0% /tmp
overlayfs:/tmp/root      14604        48     14556   0% /
tmpfs                      512         0       512   0% /dev

seems you need to remove few packages for it to be usable
cheers

dnp, thank you! I've rebuld image only with:
* kmod-gpio-over-mmc (patched)
* kmod-fs-ext4

Try it here: https://github.com/Dirry/dir300b1-sdmod-extroot

Install block-mount from opkg... so... you know smile

(Last edited by Dirry on 27 Jan 2016, 19:17)

hmm, cheers mate, jffs root works now
however.. wink
seems modules-boot.d are loaded from initramfs, hence editing them on jffs does nothing and after disabling gpio script card is no longer being detected. script edits needs to be done from within buildroot
nope, i have no clue whats going on here (but card is no longer detected after loading modules from mmc script)

[    9.180000] mount_root: loading kmods from internal overlay
[    9.400000] gpio-mmc: [DIRRY-HACK] Init
[    9.400000] gpio-mmc: [DIRRY-HACK] platform_device_alloc...
[    9.410000] gpio-mmc: [DIRRY-HACK] platform_device_add_data...
[    9.430000] gpio-mmc: [DIRRY-HACK] platform_device_add...
[    9.440000] gpiommc gpiommc.0: no of_node; not parsing pinctrl DT
[    9.450000] gpio-mmc: Failed to request mmc_spi module.
[    9.460000] spi-gpio spi-gpio.0: no of_node; not parsing pinctrl DT
[    9.460000] rt2880-pinmux pinctrl: request pin 8 (io8) for pio:8
[    9.460000] rt2880-pinmux pinctrl: request pin 9 (io9) for pio:9
[    9.460000] rt2880-pinmux pinctrl: request pin 13 (io13) for pio:13
[    9.460000] rt2880-pinmux pinctrl: request pin 0 (io0) for pio:0
[    9.460000] gpio-mmc: MMC-Card ATATA
[    9.470000] gpio-mmc: MMC-Card "default" attached to GPIO pins di=9, do=13, clk=8, cs=0, activelow=1, nospi=0, max_bus_speed=5000000, mode=0
[    9.490000] gpio-mmc: [DIRRY-HACK] OK! WAIT FOR GPIO-SPI...
[    9.510000] mmc_spi spi32766.0: no of_node; not parsing pinctrl DT
[    9.510000] mmc_spi spi32766.0: ASSUMING 3.2-3.4 V slot power
[    9.540000] mmc_spi spi32766.0: setup: unsupported mode bits 4
[    9.550000] mmc_spi spi32766.0: can't change chip-select polarity
[    9.580000] mmc_spi spi32766.0: SD/MMC host mmc0, no DMA, no WP, no poweroff
[    9.710000] block: attempting to load /tmp/jffs_cfg/upper/etc/config/fstab
[    9.730000] block: extroot: device not present, retrying in 5 seconds
[   14.750000] block: extroot: cannot find device mmcblk0p1
[   14.760000] mount_root: switching to jffs2 overlay

block-mount should be on image as its more space efficient to have it in squash, its important <20kb (uncompressed) anyway

another thing, i seem to be getting couple second freezes and hangs/reboot after mounting mmc, reminds me similar issue on rtl8186 sdcard mod i did couple years back, as im thinking bout it now, it is possible card is at fault here, as i reused it

(Last edited by dnp on 28 Jan 2016, 02:08)

dnp, please try to another card because I've repeated all steps in manual from scratch and have a success:

root@OpenWrt:~# dmesg | grep -E "(mmc|mount)"
[    9.210000] mount_root: loading kmods from internal overlay
[    9.420000] gpio-mmc: [DIRRY-HACK] Init
[    9.430000] gpio-mmc: [DIRRY-HACK] platform_device_alloc...
[    9.440000] gpio-mmc: [DIRRY-HACK] platform_device_add_data...
[    9.460000] gpio-mmc: [DIRRY-HACK] platform_device_add...
[    9.470000] gpiommc gpiommc.0: no of_node; not parsing pinctrl DT
[    9.470000] gpio-mmc: Failed to request mmc_spi module.
[    9.490000] gpio-mmc: MMC-Card ATATA
[    9.490000] gpio-mmc: MMC-Card "default" attached to GPIO pins di=9, do=13, clk=8, cs=0, activelow=1, nospi=0, max_bus_speed=5000000, mode=0
[    9.520000] gpio-mmc: [DIRRY-HACK] OK! WAIT FOR GPIO-SPI...
[    9.530000] mmc_spi spi32766.0: no of_node; not parsing pinctrl DT
[    9.540000] mmc_spi spi32766.0: ASSUMING 3.2-3.4 V slot power
[    9.570000] mmc_spi spi32766.0: setup: unsupported mode bits 4
[    9.580000] mmc_spi spi32766.0: can't change chip-select polarity
[    9.610000] mmc_spi spi32766.0: SD/MMC host mmc0, no DMA, no WP, no poweroff
[    9.650000] mmc0: host does not support reading read-only switch, assuming write-enable
[    9.670000] mmc0: new SDHC card on SPI
[    9.670000] mmcblk mmc0:0000: no of_node; not parsing pinctrl DT
[    9.690000] mmcblk0: mmc0:0000 SD04G 3.67 GiB 
[    9.770000]  mmcblk0: p1 p2 p3  <--- I have three partitions on my SD card
[   13.110000] EXT4-fs (mmcblk0p1): mounting ext3 file system using the ext4 subsystem
[   22.100000] EXT4-fs (mmcblk0p1): recovery complete
[   22.170000] EXT4-fs (mmcblk0p1): mounted filesystem with ordered data mode. Opts: 
[   24.440000] mount_root: switched to extroot

(Last edited by Dirry on 28 Jan 2016, 07:13)

dnp wrote:

block-mount should be on image as its more space efficient to have it in squash, its important <20kb (uncompressed) anyway

I've tried to include block-mount to image but have a fail: kmodloader not loads mmc modules before root_mount. I don't know why. If block-mount dont include to image and opkg install (as in my manual) everything is works. I don't know about many aspects about boot. My bad.

figured this one out, it seems this old card dosnt like soft reset for whatever reason, works fine from hard reset tho (poweroff), hate this type of bugs
upon further examination of the mmc-spi protocol it might have to do with cards FTL spi-mode implementation, removal of power led could help, possibly, or tweaking delay in mmc_spi driver. im fine with it for now

[    4.330000] init: - preinit -
[    5.530000] 8021q: adding VLAN 0 to HW filter on device eth0
[    5.660000] random: mktemp urandom read with 8 bits of entropy available
[    9.140000] jffs2: notice: (274) jffs2_build_xattr_subsystem: complete building xattr subsystem, 0 of xdatum (0 unchecked, 0 orphan) and 0 of xref (0 dead, 0 orphan) found.
[    9.180000] mount_root: loading kmods from internal overlay
[    9.390000] gpio-mmc: [DIRRY-HACK] Init
[    9.400000] gpio-mmc: [DIRRY-HACK] platform_device_alloc...
[    9.410000] gpio-mmc: [DIRRY-HACK] platform_device_add_data...
[    9.420000] gpio-mmc: [DIRRY-HACK] platform_device_add...
[    9.430000] gpiommc gpiommc.0: no of_node; not parsing pinctrl DT
[    9.440000] gpio-mmc: Failed to request mmc_spi module.
[    9.450000] spi-gpio spi-gpio.0: no of_node; not parsing pinctrl DT
[    9.450000] rt2880-pinmux pinctrl: request pin 8 (io8) for pio:8
[    9.450000] rt2880-pinmux pinctrl: request pin 9 (io9) for pio:9
[    9.450000] rt2880-pinmux pinctrl: request pin 13 (io13) for pio:13
[    9.450000] rt2880-pinmux pinctrl: request pin 0 (io0) for pio:0
[    9.460000] gpio-mmc: MMC-Card ATATA
[    9.460000] gpio-mmc: MMC-Card "default" attached to GPIO pins di=9, do=13, clk=8, cs=0, activelow=1, nospi=0, max_bus_speed=5000000, mode=0
[    9.490000] gpio-mmc: [DIRRY-HACK] OK! WAIT FOR GPIO-SPI...
[    9.510000] mmc_spi spi32766.0: no of_node; not parsing pinctrl DT
[    9.510000] mmc_spi spi32766.0: ASSUMING 3.2-3.4 V slot power
[    9.540000] mmc_spi spi32766.0: setup: unsupported mode bits 4
[    9.550000] mmc_spi spi32766.0: can't change chip-select polarity
[    9.580000] mmc_spi spi32766.0: SD/MMC host mmc0, no DMA, no WP, no poweroff
[    9.680000] mmc0: host does not support reading read-only switch, assuming write-enable
[    9.690000] mmc0: new SD card on SPI
[    9.700000] mmcblk mmc0:0000: no of_node; not parsing pinctrl DT
[    9.730000] mmcblk0: mmc0:0000 SD01G 968 MiB
[    9.810000]  mmcblk0: p1
[    9.830000] block: attempting to load /tmp/jffs_cfg/upper/etc/config/fstab
[    9.850000] block: extroot: device not present, retrying in 5 seconds
[   20.050000] EXT4-fs (mmcblk0p1): recovery complete
[   20.120000] EXT4-fs (mmcblk0p1): mounted filesystem with ordered data mode. Opts:
[   20.400000] mount_root: switched to extroot
[   20.770000] procd: - early -

ah, indeed, installing block-mount from imagebuild will have it in initramfs by default, this would require more complex solution (or some manual hacking) but i havent worked with buildroot for ages, its good enough as it is anyway, so no worries wink

cheers

(Last edited by dnp on 28 Jan 2016, 11:29)

The discussion might have continued from here.