Re: Dual boot Android or Linux?
Posted: Sun Dec 01, 2019 2:50 pm
New info in from Ben(!) - but I haven't had a chance to follow up yet:
BootShim and BootShimStage2 are currently used for the majority arm32 Windows Phone devices (not including Lumia 950, 950 XL, Elite x3 and Idol 4S) because their stock UEFI is unable to satisfy the Linux boot protocol (the bottom 128MiB memory is occupied, plus different auxiliary processor startup method). Therefore, BootShim and BootShimStage2 do these things:
- Qualcomm UEFI starts (you see the logo), Windows Boot Manager (bootarm.efi / bootmgfw.efi) starts.
Windows Boot Manager selects BootShim as the boot application
- BootShim switches processor context and memory configuration to the UEFI mode (because Windows Boot Manager has its own mode for loading Windows) and loads BootShimStage2
- BootShimStage2 patches Qualcomm UEFI on-the-fly so auxiliary processors won't start.
Fortunately on those arm64 devices including Lumia 950XL, those procedures are not necessary thanks to the advancement of arm64 and PSCI specification. Once you reaches my UEFI implementation, you can boot Linux easily. To boot Linux, you need the following preparation:
- BootShimStage2 loads Little Kernel (the common Android Linux Kernel bootloader) at somewhere higher than 128MB, and it relocates FrameBuffer
Little Kernel kicks in, load Linux Kernel/Initrd/Device Tree and hands off to Linux Kernel
- A decent Linux Kernel. My experiments use Linux 4.18, but I think 4.4 or 4.9 are okay too. Enable CONFIG_EFI=y and CONFIG_EFI_STUB=y in kernel configuration. You might also want to enable a few Qualcomm device drivers as well as EFI FrameBuffer support.
- A device tree file. You can get one from Parallel Universe repository. Compile the device tree file and place dtb in the device.
To recap, the process is similar to booting Windows 10 on ARM on 950XL. It's technically possible to boot Android Linux Kernel on 950XL via GRUB too, but a few things are required to get sort out:
- Use GRUB to load the kernel. You can get a copy of aarch64 GRUB and configuration file from recent CentOS and Fedora arm64 iso. Then you can load Linux in the way similar to traditional x86 PCs. However, you do need "devicetree /some-device-tree-950-xl.dtb" to make device tree get loaded. In addition, you need to turn off ACPI by passing "acpi=off" to Linux Kernel.
- Android relies on a few parameters passed from bootloader to kernel and GRUB cannot automatically adds them. You have to pass them manually in. For details, check apps/aboot/aboot.c in LK.
- MSM8994 uses 3.4 or 3.10 kernel for booting Android. ARM64 EFISTUB is not mature at that time and it might not work properly. Porting drivers to recent kernel versions is feasible but requires a lot of engineering effort.