I have an Acer Aspire R15 laptop, and I need to have a Linux run from the internal SD card slot. There is no SD card option available in the Boot Options menu.

I have Windows 10 installed on the main SSD, with ~100MB EFI partition (49MB free space). I have installed Arch Linux on SD card, chrooted into it, mounted EFI partition as /efi (leaving /boot on the SD card), added an UEFI record with grub-install --target=x86_64-efi --efi-directory /efi --boot-directory /boot --bootloader-id=ARCH-SD, but the problem is the SD card slot is not reachable on the early boot stage, so GRUB cannot reach /boot to load kernel and initram. I understand I need to have the kernel with "mmc_core mmc_block sdhci sdhci-pci" modules installed (via editing /etc/mkinitcpio.conf to MODULES="mmc_core mmc_block sdhci sdhci-pci" and running mkinitcpio -p linux), and I could have mounted EFI partition to /boot to have it reachable on the early stage, would the EFI partition free space be not that sparse.

So, the question is: is there a way to set up an .efi binary on the EFI partition to have it embedded a minimal kernel with SD card modules installed (disk space usage is the key), with its only purpose to make the SD card reachable, and chainload the full-featured kernel, initram etc on the SD card? Or is there any better other way? Doing so by the means of GRUB/efibootmgr/other_bootloader is preferred (rather than doing lower-level stuff that is error-prone and needs manual support on system updates). Repartitioning the main SSD, or using an USB SD adapter, or whatever similar, is not an option.


Solution: As per @alex-stragies advice, I got it working by setting the boot folder on the Windows partition. The whole sequence is as follows:

  1. Mount the EFI partition to the /efi folder;
  2. Install ntfs-3g package for ntfs support, mount Windows partition to /mnt/Windows/: mount /dev/sdxY /mnt/Windows and make boot directory on it: mkdir /mnt/Windows/boot;
  3. bind the created folder to boot: mount --bind /mnt/Windows/boot /boot;
  4. (optional, yet recommended; needed for system / kernel updates only) add the above to /etc/fstab for persistence, there should be at least 4 mount records: /, /efi, /mnt/Windows, /boot (the latter bound to the boot folder on the previously mounted /mnt/Windows, add bind to its mount options);
  5. edit /etc/mkinitcpio.conf, section "HOOKS", to have block hook to be right after udev and before filesystems (the kernel modules mentioned above turned out unnecessary, SD/MMC card support is added by the block hook), then make an initrd update: mkinitcpio -p linux;
  6. make a GRUB record to UEFI: grub-install --target=x86_64-efi --efi-directory /efi --boot-directory /boot --bootloader-id=LINUX-SD;
  7. update GRUB config: grub-mkconfig -o /boot/grub/grub.cfg;
  8. reboot and choose the added LINUX-SD boot option (usually F8 or F12, or via BIOS/UEFI; might need an explicit boot record confirmation there).

That should be it. The boot chain is as follows: the UEFI shell executes grubx64.efi binary on the EFI partition, it follows the link to the Windows partition with the boot folder, GRUB loads the initrd environment with the kernel (SD card support becomes enabled at this point), the / (root) partition on the SD card is mounted, and the usual boot process continues thereafter.


The standard workaround to have your RootFS on non-bootable storage would be to place the /boot folder somewhere on the SSD. That would not "boot directly of the SD-card", but "Load Kernel+InitRD from SSD, to then mount the Root FS from SD-card".

You could place the /boot/ folder in your windows partition, either "raw", or in a 200MiB loopback-mounted Filesystem image.

Can't speak for Arch, but on a Debian those steps should do it:

  • Add FSTAB entry to automount the windows partition
  • mv /boot /mnt/windows/MyLinuxBoot
  • ln -s /mnt/windows/MyLinuxBoot /boot
  • update-grub

Similar steps should work on Arch.

That should load kernel+initrd from the SSD, and then the initrd has the drivers for the SD-card to load the root FS from the SD-card.

Or you could attempt to fit it all into the EFI partition:

  • move the /boot/grub folder into /boot/efi/grub
  • Symlink /boot/grub back to /boot/efi/grub
  • move kernel and initrd from /boot into /boot/efi/
  • Symlink both of them back to their original location and name
  • run update-grub

You might have to tweak the parameters for initrd creation so as not to include modules for everything under the sun, so that you can fit everything into the remaining space in the EFI partition.

  • Thank you very much, that did it (the /boot folder on the Windows partition). I am updating my post with a thorough step-by-step solution based on your advice. Nevertheless, I will keep the post unsolved for a while, as it seems more of a hack to me other than a proper solution (not to belittle its value as a working method), so other stackers could advise something more universal, consistent and unix-way-ish. Otherwise, I will mark the post solved. Either way, please have my upvote and thankfulness.
    – z0mb1e_kgd
    Jun 7 at 13:46
  • 1
    @z0mb1e_kgd : Not really a "hack", but standard procedure for having your root-fs on non-bootable storage: Just move the /boot folder/partition to a place the system firmware can boot from. Jun 7 at 16:39

I'm adding this second answer, which is a more direct answer to your question, and not just a workaround like my other answer. This one is light on details though, more a "rough travel plan" than a "how-to":

You could also use an intermediate bootloader:

  • Download/compile a bootloader with support for sdhci-pci
  • Install this bootloader in the EFI-partition
  • Configure this intermediate bootloader to chainload either grub, or the kernel directly from SD-card.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.