Advanced OS Customizations & Bootloaders

Automating Android Custom ROM Boot: GRUB2 Scripting for One-Click OS Selection

Google AdSense Native Placement - Horizontal Top-Post banner

Introduction: Streamlining Your Multi-ROM Android Experience

For enthusiasts who frequently test or maintain multiple Android Custom ROMs on a single device, the process of switching between them often involves repetitive manual steps: rebooting to recovery, flashing a new ROM, wiping data, and then rebooting. While advanced recovery solutions like TWRP offer multi-boot capabilities, integrating Android ROMs into a Linux-based GRUB2 bootloader environment can unlock a level of automation and one-click convenience previously unseen. This guide delves into leveraging GRUB2 scripting to create a dynamic boot menu, allowing you to select and boot your desired Android Custom ROM with the ease of a traditional multi-OS setup.

This advanced technique is particularly useful for developers, ROM testers, or power users who manage devices with multiple partitions dedicated to different Android builds (e.g., AOSP, LineageOS, Pixel Experience). By the end of this tutorial, you’ll have a GRUB2 configuration that can intelligently detect and present your installed Android ROMs for seamless, automated booting.

Understanding Android Boot Process and GRUB2 Integration

Before diving into scripting, it’s crucial to understand how Android boots and where GRUB2 fits in. Traditional Linux distributions boot a kernel and an initial ramdisk (initrd). Android, however, uses a specialized boot.img file, which is essentially a concatenation of the kernel image, a ramdisk image, and a few other header details. This boot.img is typically located on a dedicated boot partition.

GRUB2, as a powerful bootloader, can initiate the boot process for various operating systems. While it natively understands Linux kernels, directly booting an Android boot.img requires a bit more finesse. We’ll utilize GRUB2’s loopback and chainloader commands, combined with custom scripting, to unpack or point to the necessary components within the boot.img or its partition.

Prerequisites for GRUB2 Android Boot Automation

  • A Linux Host System: This setup assumes your primary bootloader is GRUB2, likely running on a Linux distribution installed alongside or before your Android partitions.
  • Rooted Android Device/System: You’ll need access to the Android file system, often requiring root to identify partitions and potentially extract boot images.
  • Multiple Android Custom ROMs: These ROMs should be installed on separate partitions or distinct logical volumes on your device’s storage.
  • GRUB2 Installed and Configured: Ensure GRUB2 is already your primary bootloader.
  • Basic GRUB2 Knowledge: Familiarity with /etc/grub.d/ and update-grub is beneficial.

Identifying Android Partitions and Boot Images

The first step is to locate where your Android ROMs reside on disk. This involves identifying the dedicated boot and system partitions for each Android installation. We’ll use standard Linux disk utilities for this.

Step 1: Discovering Disk Layout

Boot into your Linux host system. Open a terminal and use lsblk or fdisk -l to list all storage devices and their partitions. Pay close attention to partition sizes and types, especially any labeled as ‘Android’ or ‘Linux’ that correspond to your custom ROM installations.

sudo fdisk -l

Or for a more human-readable tree view:

lsblk -o NAME,SIZE,FSTYPE,MOUNTPOINT,LABEL

Identify the partitions corresponding to your Android installations. For example, you might see /dev/sda5, /dev/sda6, etc., each containing a different Android ROM.

Step 2: Locating the Boot Image or Android Rootfs

Once you’ve identified the partitions, you need to find the boot.img for each ROM. Often, Android installations have a dedicated boot partition. If not, the kernel and ramdisk components are typically within the root file system. For simplicity, we’ll assume a dedicated boot partition or the ability to mount the Android system partition to locate the necessary kernel and ramdisk.

Mount one of your Android system partitions (e.g., /dev/sdaX) to inspect its contents:

sudo mount /dev/sdaX /mnt/android_rom1ls -l /mnt/android_rom1/boot.img # Check if boot.img is directly present

If boot.img is not directly visible, you might need to identify the kernel and ramdisk paths, which are often found in /kernel or /boot directories within the system partition, or sometimes directly at the root of the system partition. Modern GRUB2 can often boot a boot.img directly using the loopback command.

GRUB2 Configuration Fundamentals for Custom Entries

GRUB2 loads its configuration from /boot/grub/grub.cfg, which is typically generated by scripts in /etc/grub.d/. To add custom entries, we usually create a new script (e.g., 40_custom or our own named script) in /etc/grub.d/.

Basic GRUB2 Menu Entry Structure

A typical GRUB2 menu entry for a Linux system looks like this:

menuentry 'My Linux OS' {set root='(hd0,msdos1)'linux /boot/vmlinuz-x.x.x-generic root=/dev/sda1 roquiet splashinitrd /boot/initrd.img-x.x.x-generic}

For Android, we need to adapt this, primarily focusing on correctly loading the kernel and ramdisk from the boot.img or its partition.

Scripting for Dynamic Android Boot with GRUB2

Now, let’s create a custom GRUB2 script in /etc/grub.d/ that will dynamically add menu entries for our Android ROMs. We’ll name it 40_android_roms.

Step 1: Create the Custom GRUB2 Script

sudo nano /etc/grub.d/40_android_roms

Add the following content. This script iterates through predefined Android partition paths and attempts to boot them. You’ll need to customize the ANDROID_ROMS array with your specific partition paths.

#!/bin/sh -egrubecho "Adding Android Custom ROMs to GRUB menu..."ANDROID_ROMS=(  "(hd0,gpt5)/boot.img:/Android ROM 1 (LineageOS)"  "(hd0,gpt6)/boot.img:/Android ROM 2 (AOSP)"  "(hd0,gpt7)/boot.img:/Android ROM 3 (PixelExperience)")for ROM_ENTRY in "${ANDROID_ROMS[@]}"; do  ROM_PATH=$(echo "$ROM_ENTRY" | cut -d':' -f1)  ROM_LABEL=$(echo "$ROM_ENTRY" | cut -d':' -f2)  echo "Adding $ROM_LABEL to GRUB..."  cat << EOFmenuentry "$ROM_LABEL" {set root='$ROM_PATH'# Attempt to boot boot.img directly if supported by your GRUB2 version# This might require GRUB2's 'loopback' module to be loaded automatically# or manually via 'insmod loopback' (though usually not needed for boot.img)search --no-floppy --fs-uuid --set=root UUID_OF_ANDROID_PARTITION  # Replace with actual UUIDif [ -f /boot.img ]; then    linux /boot.img    # If boot.img is not directly bootable, you might need to extract kernel/ramdisk    # Example: unpack boot.img manually and point to kernel/ramdisk    # linux /path/to/extracted/kernel # root=/dev/sdaX (or UUID) androidboot.hardware=universal # Add kernel params    # initrd /path/to/extracted/ramdiskelif [ -f /kernel ]; then # Fallback for ROMs without a boot.img at root    linux /kernel root=/dev/sdaX androidboot.hardware=universal  # Adjust root/hardware    initrd /ramdisk # Assuming ramdisk is also at root of partitionelse    echo "Warning: Could not find boot.img or kernel/ramdisk on $ROM_PATH"    # Fallback to chainloading if a specific bootloader is installed on the partition    # chainloader +1fi# Example for GRUB2 with loopback.cfg for boot.img (more modern approach)set root='(hd0,gpt5)' # Adjust to your actual partition# If you have specific kernel parameters, add them heredevicetree /dtb_path/if neededinsmod part_gptinsmod ext2# Optional: for specific Android versions or devices, you might need specific kernel parametersset kparams="androidboot.selinux=permissive androidboot.warm_reset=0"# Try to load boot.img and get kernel/ramdisk from itloopback l (hd0,gpt5)/boot.img # Replace (hd0,gpt5) with correct partition# grub-mkimage can create a core.img with specific modules like 'android' to parse boot.img# If your GRUB supports it, 'androidboot' module might be available# linux (l)/kernel root=/dev/sdaX $kparams # If kernel is inside boot.img chainloader (l)+1 # This might work for some boot.img to pass control to its internal bootloaderfi}EOFdone

Important Customizations:

  • `ANDROID_ROMS` Array: Crucially, replace the example paths like `(hd0,gpt5)/boot.img` with the actual GRUB2 partition identifiers and paths to your `boot.img` files. To find your GRUB2 partition identifier, use `sudo grub-probe –target=fs_uuid /dev/sdaX` for UUID or refer to `(hdX,gpty)` where `X` is disk number, `Y` is partition number.
  • Kernel Parameters: Android kernels often require specific parameters (e.g., `androidboot.selinux=permissive`, `androidboot.hardware=universal`, `root=/dev/sdaX` or `root=UUID=`). These vary by device and ROM. You might need to examine your ROM’s `init.rc` or existing boot scripts to determine the correct parameters.
  • `loopback` and `chainloader`: The script provides a generic approach. Modern GRUB2 versions can often use `loopback` to treat `boot.img` as a file system and extract components. Some Android systems might respond well to `chainloader (loop)/boot.img` or `chainloader +1` if the partition has its own mini-bootloader. The most robust method might involve manually extracting the kernel and ramdisk from `boot.img` (e.g., using `abootimg` or `unyaffs`) and pointing GRUB2 directly to them.

For direct `boot.img` booting via `loopback` (if your GRUB2 build supports the ‘android’ module or if the `boot.img` is simple enough):

menuentry "Android ROM via boot.img" {  set root='(hd0,gpt5)' # Your Android system partition  insmod part_gpt  insmod ext2  set bootimg_path="/boot.img" # Path to boot.img on that partition  # Attempt to load using GRUB2's 'android' module if available  # If not, loopback to extract kernel and ramdisk manually (more complex)  if [ -f $bootimg_path ]; then    loopback loop0 $bootimg_path    linux (loop0)/kernel root=/dev/sda5 # Adjust root partition and add kernel params    initrd (loop0)/ramdisk  else    echo "Boot image not found!"    # Fallback or error handling  fi}

The `linux (loop0)/kernel` syntax works if GRUB2’s `loopback` functionality can parse the `boot.img` and expose the kernel and ramdisk as files within the loop device. This often requires specific GRUB2 modules. A safer, but more involved, approach is to extract `kernel` and `ramdisk.img` from `boot.img` beforehand and store them directly in the GRUB2 accessible partition.

Step 2: Make the Script Executable

sudo chmod +x /etc/grub.d/40_android_roms

Step 3: Update GRUB2 Configuration

sudo update-grub

This command will execute all scripts in /etc/grub.d/, including your new `40_android_roms` script, and generate the `grub.cfg` file.

Reboot and Test

Reboot your system. You should now see new entries in your GRUB2 boot menu corresponding to your Android Custom ROMs. Select one and observe if it boots correctly. You might need to iteratively adjust the kernel parameters or partition paths within your `40_android_roms` script based on your device’s specific requirements.

Troubleshooting and Best Practices

  • Incorrect Kernel Parameters: If Android starts but crashes or enters a boot loop, the kernel parameters are likely incorrect. Common parameters to check include `root=`, `androidboot.hardware=`, `console=`, `loglevel=`.
  • Partition Identification: Double-check your GRUB2 partition identifiers (e.g., `(hd0,gpt5)`) and UUIDs. Mismatched identifiers are a common error.
  • `boot.img` Parsing: Not all GRUB2 builds or `boot.img` formats are compatible with direct `loopback` extraction of kernel/ramdisk. If you face issues, consider manually extracting the kernel and ramdisk from `boot.img` using tools like `abootimg` or `unyaffs` on your Linux host, and then point GRUB2 directly to these extracted files.
  • Backup: Always back up your `grub.cfg` and `boot.img` files before making significant changes.

Conclusion

By scripting GRUB2, you transform the cumbersome process of switching between Android Custom ROMs into a streamlined, one-click operation directly from your bootloader. This advanced customization not only saves time but also provides a deeper understanding of the Android boot process and GRUB2’s powerful capabilities. While requiring careful setup and some debugging, the convenience of a dynamic, GRUB2-managed Android multi-boot environment is an invaluable asset for any serious Android enthusiast or developer.

Android Mobile Specs & Compare Directory

Are you researching mobile hardware properties, processor SoCs, GPU chipsets, or RAM configurations? Access our complete specs catalog to compare up to 5 devices side-by-side!

Compare Devices Specs →
Google AdSense Inline Placement - Content Footer banner