Split-partition SD card

This topic contains 7 replies, has 2 voices, and was last updated by  danilovesky 3 years, 12 months ago.

Viewing 8 posts - 1 through 8 (of 8 total)
  • Author
    Posts
  • #31517

    Hi!

    In Reference Manual of SDK v.19 there is a nice tutorial on how to build a split-partition Linux image (Appendix D). I tried to follow it and managed to obtain a vmlinux.ub file. By the way, I think there are few typos in the tutorial, some of them I am sure about (e.g. host${PWD} inside EXTRA_LDFLAGS definition), the others are not so obvious (e.g. I am not sure if linuxrc of the ramdisk should point to sbin/init, as proposed by the tutorial or to bin/busybox, which seems to be more logical). Anyway, this is something for another discussion…

    The problem is the booting process gets stuck at “Starting kernel …” line. I am pretty sure the reason for this failure is the way the minimal ramdisk is built (by copying busybox, few libraries and init script). It may be too minimal and missing some important binaries…

    If I generate the ramdisk by compiling a default buildroot (cd buildroot; make comet_minimorph_defconfig; make), then copying rootfs.cpio over into ramdisk.cpio of the kernel tree, and replace the init script inside it, then the rest of the flow works fine – the generated vmlinux.ub boots and mounts the realroot file system as expected.

    So, the question is, are you sure the guidelines in Appendix D create a proper minimal ramdisk? Is it possible something is missing there?

    For a reference, here is a script (derived from Appendix D with minor corrections) which I use to generate the image:

    #!/usr/bin/env bash

    RAMDISK=${PWD}/ramdisk
    KERNEL=${PWD}/metag-linux
    ROOTFS=${PWD}/buildroot
    UBOOT=${PWD}/u-boot

    echo "Step 1: Edit inittab"
    echo "
    "

    echo "1a) Comment out some of the lines beginning with ::sysinit:"
    if [ ! -f ${ROOTFS}/output/target/etc/inittab.original ]
    then
    cp -f ${ROOTFS}/output/target/etc/inittab ${ROOTFS}/output/target/etc/inittab.original
    fi
    sed -i "s@^(null::sysinit:/bin/mount -t devtmpfs devtmpfs /dev)@#1@" ${ROOTFS}/output/target/etc/inittab
    sed -i "s@^(null::sysinit:/bin/mount -t proc proc /proc)@#1@" ${ROOTFS}/output/target/etc/inittab


    echo "Step 2: Create minimal ramdisk"
    echo "
    "

    echo "2a) Create a temporary directory for the ramdisk"
    rm -rf ${RAMDISK}
    mkdir -p ${RAMDISK}

    echo "2b) Install busybox to the temporary directory"
    make -C ${ROOTFS}/output/build/busybox-*
    CROSS="${ROOTFS}/output/host/usr/bin/metag-linux-"
    CROSS_COMPILE="${ROOTFS}/output/host/usr/bin/metag-linux-"
    CC="${ROOTFS}/output/host/usr/bin/metag-linux-gcc"
    EXTRA_LDFLAGS="-L${ROOTFS}/output/staging/lib -L${ROOTFS}/output/staging/usr/lib --sysroot=${ROOTFS}/output/staging/"
    ARCH=metag CONFIG_PREFIX=${RAMDISK} install

    echo "2c) Copy required support files"
    cp -rf ${ROOTFS}/output/target/dev ${ROOTFS}/output/target/proc ${ROOTFS}/output/target/sys ${RAMDISK}
    mkdir -p ${RAMDISK}/lib
    cp -f ${ROOTFS}/output/target/lib/ld-uClibc* ${ROOTFS}/output/target/lib/libuClibc* ${ROOTFS}/output/target/lib/libc.so* ${RAMDISK}/lib

    echo "2d) Remove unnecessary files from ramdisk"
    rm -f ${RAMDISK}/sbin/init
    rm -f ${RAMDISK}/init
    rm -f ${RAMDISK}/linuxrc

    echo "2e) Copy ramdisk init file"
    cp -f init_script ${RAMDISK}/sbin/init
    chmod 777 ${RAMDISK}/sbin/init
    ln -s sbin/init ${RAMDISK}/init
    ln -s sbin/init ${RAMDISK}/linuxrc # !!! MAYBE "ln -s bin/busybox ${RAMDISK}/linuxrc" ?

    echo "2f) Set file permissions from fakeroot"
    pushd ${RAMDISK}
    KERNEL=${KERNEL} ${ROOTFS}/output/host/usr/bin/fakeroot --
    chown -R 0:0 .;
    find . | cpio --quiet -o -H newc | gzip -9 -c > ${KERNEL}/arch/metag/boot/ramdisk.cpio
    popd

    echo "Step 3: Rebuild kernel with minimal ramdisk"
    echo "
    "
    make -C ${KERNEL} ARCH=metag
    CROSS_COMPILE="${ROOTFS}/output/host/usr/bin/metag-linux-"


    echo "Step 4: Convert vmlinux.bin and u-boot script to U-Boot-compatible format"
    echo "
    "
    ${UBOOT}/tools/mkimage -A metag -O linux -T script -C none -a 0 -e 0 -n "Boot script" -d u-boot.sh u-boot.scr
    gzip -c ${KERNEL}/arch/metag/boot/vmlinux.bin > vmlinux.bin.gz
    ${UBOOT}/tools/mkimage -A metag -O linux -T kernel -C gzip -a 0x40000000 -e 0x40000000 -n "Meta Linux v1.9" -d vmlinux.bin.gz vmlinux.ub
    rm -f vmlinux.bin.gz

    #38125

    Sean
    Moderator

    Thank you for your detailed explanation. We are taking a look and will let you know.

    Regards,
    Sean.

    #38126

    Sean
    Moderator

    It looks like it’s caused by a missing path in the SD card mount command.
    The /realroot directory doesn’t exist within the initial ramdisk, and so is causing mount to fail, and drop to a single shell.

    Add the following to your creation script in section 2c: mkdir -p ${RAMDISK}/realroot

    Sean.

    #38127

    Thanks for the hint! I will try it on Monday when I have access to the board, however I think the cause of the failure is something else.

    The thing is I moved the creation of /realroot directory into my init_script (which is copied over to ramdisk init) – I thought it is more logical there…

    Also this would not explain why a “bigger” ramdisk (obtained from default configuration of buildroot) which does not have /realroot directory works fine (the /realroot directory is created in init script).

    In any case, I will do the experiment and report back with the results!

    By the way, here is my init script which works with “bigger” ramdisk but not with the “minimal” one:

    #!/bin/sh

    mknod /dev/console c 5 1
    exec 0</dev/console
    exec 1>/dev/console
    exec 2>/dev/console
    export PATH=/bin:/sbin:/usr/bin:/usr/sbin

    echo "Mounting filesystems..."
    mount -t proc proc /proc
    mount -t sysfs sysfs /sys
    mount -t devtmpfs devtmpfs /dev
    mkdir -p /dev/pts
    mount -t devpts devpts /dev/pts
    echo /sbin/mdev > /proc/sys/kernel/hotplug
    mdev -s

    echo "Mounting SD card as root filesystem..."
    mkdir -p /realroot
    mount -t ext2 -o rw /dev/mmcblk0p2 /realroot
    mount --move /dev /realroot/dev
    mount --move /proc /realroot/proc
    mount --move /sys /realroot/sys

    echo "Passing control to the root file system now..."
    exec switch_root /realroot /sbin/init
    #38128

    Hi Sean,

    I tried to statically create the /realroot directory in the ramdisk, but as I was expecting it did not help – the same problem: the boot process stops at “Starting kernel …” line. I guess the /realroot is not a problem because it is long way before switching the root takes place…

    Do the instructions in Appendix D work for you (with a ramdisk consisting only of the busybox and few libraries)? Can you maybe send your ramdisk.cpio or I can send you mine for comparison?

    Two more things that look suspicious in Appendix D:

    1) Is it correct that /linuxrc points to sbin/init script (instead of bin/busybox)?

    2) In Edit inittab sub-section the explanation is a bit cryptic:

    Edit the file buildroot/output/target/etc/inittab and remove (or comment out) all lines beginning with ::sysinit: down to the line ::sysinit:/bin/mount -o remount,rw /
    The ramdisk init will take care of those things.

    First, there are no lines starting with ::sysinit: in my inittab, only null:sysinit: – is it correct?
    Second, it is not clear if the lines to remove include “::sysinit:/bin/mount -o remount,rw /” or not.
    Also, can it be that the order of lines changes in inittab depending on buildroot configuration?

    It would be better to write explicitly which lines to remove, .e.g those which mount /dev and /proc filesystems.

    Regards,
    Danil

    #38129

    Sean
    Moderator

    Danil,

    OK, thanks for the update. I’m out of the office this week in US so different time zone – I’ve asked the guys back in the UK to look into it and assist you. They’ve done some investigative work on it today and should get back to you shortly.

    Thanks for your patience.

    Regards,

    Sean.

    #38130

    Sean
    Moderator

    Danil,

    Good spot – looks like this one has slipped through the net – apologies. Thank you for your thought and detailed reports.

    Summary:
    Step 8 on page 53 of the ref manual calls for the ramdisk.cpio archive to be compressed – this worked on the 2.6 kernels, however the 3.x kernels (SDK 1r9) compress the ramdisk according to Kconfig options. Omitting this step will ensure that the kernel boots.

    The edit should be as follows. In step 2f, replacing: find . | cpio --quiet -o -H newc | gzip -9 -c > ${KERNEL}/arch/metag/boot ramdiskwith: find . | cpio --quiet -o -H newc > ${KERNEL}/arch/metag/boot ramdisk

    Regarding your other points:
    1. linuxrc should not point to sbin/init – it should be removed entirely. The linuxrc file is used by initrd initial ramdisk scheme, whereas we employ the initramfs initial ramdisk scheme.

    2. Thank you for your feedback on this section – I have passed on your suggestion.

    Regards,

    Sean.

    #38131

    Thanks a lot, Sean!
    Now it works perfectly.
    With this minimal ramdisk the board boots much faster than with my “bloated” ramdisk 🙂

Viewing 8 posts - 1 through 8 (of 8 total)
You must be logged in to reply to this topic.