How to build Little Kernel for SD card boot?

Hi,

I’m currently trying the new Yocto Rocko feature using an additional SD card image. I was able to adapt the my machine conf and the WKS file according to my needs. Our board is almost compatible with Variscite SD410.

Using LK from ‘firmware-qcom-dragonboard410c-bootloader-sdcard’ works well. However, I have various extensions/changes in my custom LK build for eMMC. And I need them also when booting from SD card.

Using my custom LK loads the boot image from eMMC instead of loading it from SD card though SBL1 and LK are running from SD card.

I’m using LK source base from here:

https://git.linaro.org/landing-teams/working/qualcomm/lk.git

I’m building platform msm8916.

The code tries to init slot 1 (eMMC) first and if it fails it tries slot 2 (external uSD):

https://git.linaro.org/landing-teams/working/qualcomm/lk.git/tree/target/msm8916/init.c#n107

In the SDHCI driver it tries to inititialize the ‘internal MMC’ and if it fails it tries to initialize the ‘SD card’:

https://git.linaro.org/landing-teams/working/qualcomm/lk.git/tree/platform/msm_shared/mmc_sdhci.c#n1494

The code referenced above seems not to be the base for the LK contained in the ‘firmware-qcom-dragonboard410c-bootloader-sdcard’ which obviously loads the boot image from SD card.

Hence, there must be another initialization sequence for the ‘SD card aware’ LK.

The boot messages from that bootloader tell me that MMC slot 2 is enforced for the first code snipped and the ‘internal MMC’ initialization failure resulting in ‘trying for SD card’ is also valid for the SD boot case:

[10] [10] platform_init()
[10] [10] target_init()
[20] [20] initialising mmc_slot =2
[30] [30] Error: Command timeout error
[30] [30] Failure getting OCR response from MMC Card
[30] [30] MMC card failed to respond, try for SD card
[200] [200] Done initialization of the card

I tried enforce MMC slot 2 too:

...
void target_sdc_init()
{
    ...
#if 0
    /* Try slot 1*/
    config.slot         = 1;
    config.sdhc_base    = mmc_sdhci_base[config.slot - 1];
    config.pwrctl_base  = mmc_pwrctl_base[config.slot - 1];
    config.pwr_irq      = mmc_sdc_pwrctl_irq[config.slot - 1];
    config.hs400_support = 0;

    if (!(dev = mmc_init(&config))) {
#endif
    /* Try slot 2 */
	    config.slot         = 2;
	    config.max_clk_rate = MMC_CLK_200MHZ;
	    config.sdhc_base    = mmc_sdhci_base[config.slot - 1];
	    config.pwrctl_base  = mmc_pwrctl_base[config.slot - 1];
	    config.pwr_irq      = mmc_sdc_pwrctl_irq[config.slot - 1];

	    if (!(dev = mmc_init(&config))) {
                    dprintf(CRITICAL, "mmc init failed!");
			ASSERT(0);
		    }
    #if 0
	    }
    #endif
    }
    ...

The LK never reaches ‘[200] [200] Done initialization of the card’ with the above hack.

Is the initialization sequence from the above firmware LK available?

@anon91830841 Can you help?

Best regards
-Carsten

I found that

card->ext_csd

is accessed though

MMC_CARD_MMC(card)

is not true:

https://git.linaro.org/landing-teams/working/qualcomm/lk.git/tree/platform/msm_shared/mmc_sdhci.c#n237
https://git.linaro.org/landing-teams/working/qualcomm/lk.git/tree/platform/msm_shared/mmc_sdhci.c#n1675

Guarding this code lines with

if (MMC_CARD_MMC(card)) {
   ...
}

solves the problem.

Another issue was that I had to initialize

config.bus_width = DATA_BUS_WIDTH_4BIT;

for the uSD slot.

Will provide a patch on Monday.

Best regards
-Carsten

hi,

if you look at each build we make, e.g.

http://snapshots.linaro.org/96boards/dragonboard410c/linaro/rescue/latest/

You will find in the header at the top, a link to the LK commit we use for each build variant. e.g. for “SD Linux boot” it will point to here:

https://git.linaro.org/landing-teams/working/qualcomm/lk.git/log/?h=release/LA.BR.1.2.7-03810-8x16.0%2Bsdboot

And in this branch you will find the commit that enables SD boot.

Note that (at least for now) for SD boot, there is a custom SBL.mbn file that must be used. That will be fixed in the future (and the same sbl.mbn will be used for emmc or SD boot).

cheers

1 Like

Hi Nicholas,

I am trying to build the little kernel code which is taken from the following release path: “release/LA.BR.1.2.7-03810-8x16.0+rescue”.

I did the compilation by adding the “toolchain” path to “PATH” variable, the build was complete and the following folder is generated “build-msm8916”.

Please guide me the next steps to generate the .mbn files of all the sections.

I saw the console output from jenkins which is done recently by you, from that I understand as after completion of build, you used signlk.sh for signing the emmc_appsboot.mbn.

after that I couldn’t understand, did you ran some other script file for generating the rescue, emmcboot and sdlinux images.

Please help me how you did the above procedure.

One more clarification regarding the GPT tables are different for android, linux, debian, openEmbedded. Any specific reason to maintain like these…

Other .mbn files (hyp.mbn, rpm.mbn, spl1.mbn, tz.mbn) from where these files are generating…

Thanks,

Hi Rajasekhar,

I may help you also a bit:

  1. You can build little kernel either for the external SD card or the internal EMMC. The decision is made in ‘platform/msm8916/rules.mk’:

    ...
    MMC_SLOT         := 2
    ...
    
  2. The name of the output image is always ‘emmc_appsboot.mbn’ no matter how MMC_SLOT is set. So, write it to the ‘aboot’ partition of the device you are using.

  3. Can’t help with signing since I did not use it.

  4. I made my own rescue SD with Yocto. The current 96 board yocto creates a SD card image automatically for Dragonboard 410 using wic tool. You could use it also outside from Yocto but you can check it there how to use it,

  5. hyp.mbn is the Hypervisor image for the Cortex A53 that run on EL2 and tz.mbn is the TrustZone Code that run on EL2. This code is binary only from QCom and it is shipped with the firmware ZIP-File released from time to time from Quallcom.

  6. rpm.mbn is the firmware for the Ressource Power Management Co-Processor (Cortex-M3 core). You may get the code with an NDA from your distributor. I think you just need the binary,

  7. sbl1.mbn is the Second Level Bootloader that runs right before little kernel, You may get the code with an NDA from your distributor. I think you just need the binary.

  8. The different GPTs results from simply the need of different partition schemes. E.g. Android uses a userdata partition and a RAM disk while Yocto doesn’t.

Best regards
-Carsten

Thanks for the information Carsten.

I have few other clarifications for both of you (Carsten & Nicholas)

Do you have a chance to try to replace the APPSBL (emmc_appsboot.mbn) with any other generic boot loader (example u-boot) on dragonbaord-410c. If in case I want to do such change with other application boot loader, what are steps need to follow.

Do you have a chance to try to replace the APPSBL (emmc_appsboot.mbn) with any other generic boot loader (example u-boot) on dragonbaord-410c. If in case I want to do such change with other application boot loader, what are steps need to follow.

The “normal” way to implement u-boot on DB410C is to chain load it from
LK (so u-boot replaces boot.img rather than emmc_appsboot.mbn):

Whilst alternative approach are possible in theory I don’t think anyone
has attempted them (and shared their results) in practice.

Hi Daniel,

Yes I saw that user guide, it is helpful to load the linux image from u-boot. But here we are unnecessarily maintaining the lk and u-boot.

As part of that user guide, we are placing three images in boot partition. u-boot.img, uImage.img, and apq8016-sbc.dtb.

As I understand correctly, it will be an overhead only, if we replace u-boot as an application boot loader which itself will directly load from SBL and it can invoke the respective OS kernel from boot partition.

please correct me if I was wrong.

No, you are not wrong. Alternative approaches, such as copying the board init code into u-boot (and maintaining it), are certainly possible. They just don’t currently exist.

If you want to improve boot time it is probably easier just to remove some or all of the UART chatter as LK does its work. UART prints are very expensive since they usually (busy) wait for the slow UART to do its thing.