How can I boot into Arch Linux using initramfs, in Ubuntu's grub?

I have two hard drives, with two corresponding Grubs. One is from Arch Linux, and the other is from Ubuntu. Using Arch's grub, I can boot into either distribution. However, using Ubuntu's grub, I can see both Arch and Ubuntu, but cannot boot into Arch. I get the error:

Kernel offset
End kernel panic. Not syncing: VFS.
Unable to mount root fs on unknown-block.

I compared grub.cfg for both distributions. In Ubuntu's grub, I can see an entry for Arch, with the following line.

initrd /boot/intel-ucode.img

I changed it to follow Arch's grub.cfg:

initrd /boot/intel-ucode.img /boot/initramfs-linux.img

Now I can boot into Arch from Ubuntu's grub. It appears that Ubuntu is not appending this required option by default. How can I make Ubuntu automatically create the correct entry?

Edit

I'm updating Arch's grub with grub-mkconfig -o /boot/grub/grub.cfg. In Ubuntu, I've tried both update-grub and the raw command above (which it is aliased to).

Edit 2

The uncommented lines of /etc/default/grub

GRUB_DEFAULT="saved"
GRUB_SAVEDEFAULT="true"
GRUB_HIDDEN_TIMEOUT_QUIET="true"
GRUB_TIMEOUT="3"
GRUB_DISTRIBUTOR="`lsb_release -i -s 2> /dev/null || echo Debian`"
GRUB_CMDLINE_LINUX_DEFAULT=""
GRUB_CMDLINE_LINUX=""

Solution 1:

Actually, there are two files that need to be modified to solve this problem. I've tested this on my Lubuntu 16.04.1 and Manjaro Linux.

In Ubuntu:

1) File /usr/lib/linux-boot-probes/mounted/40grub2 there is a function parse_grub_menu that doesn't handle all initrd parameters. You need to modify 'case "$1" in ... initrd)':

a) remove assignment

initrd="$(echo "$2" ...)"

b) add two lines in place of the removed one:

shift 1
initrd="$(echo "$@" | sed 's/(.*)//')"

2) File /etc/grub.d/30_os-prober within a for loop fix the assignment of LINITRD:

for LINUX in ${LINUXPROBED}; do
...
    LINITRD="`echo ${LINUX} | cut -d ':' -f 5 | tr '^' ' '`"

The first fix takes all available initrd info for Manjaro into account. The second fix cleans up the generated initrd line by changing some '^' characters to spaces.

Solution 2:

I'm running Manjaro and Arch but, ironically, Manjaro will make a similar mistake as Ubuntu. So perhaps the following patch in 30_os_prober can still help someone.

After:

LINITRD="`echo ${LINUX} | cut -d ':' -f 5 | tr '^' ' '`"

Add:

if [ "${OS}" = "Arch Linux" ] ; then
  LINITRD="/boot/intel-ucode.img ${LINITRD}"
fi