lk2nd Bootloader Documentation

repository·main·Indexed 18 days ago

https://github.com/msm8916-mainline/lk2nd

A custom bootloader for Qualcomm-based smartphones, tablets, smartwatches, and SBCs. lk2nd provides a unified Android Fastboot interface, automatic hardware detection, and support for booting various operating systems via Android boot images or extlinux.conf. It can operate as a secondary bootloader (lk2nd) packed into a boot image or as a primary bootloader (lk1st) for SBCs. Key features include AVB1 signing, secondary CPU core support, and customizable build flags for debug logging and memory limits.

Tokens
13.7K
Snippets
39
Records
68
Agent score
70%

What's inside lk2nd

  1. What is lk2nd and how does it work?

    main

    lk2nd is a custom bootloader for Qualcomm-based devices (smartphones, tablets, smartwatches, and SBCs). It provides a unified Android Fastboot interface, automatic hardware detection, and additional features like file system booting and secondary CPU core support. It operates in two distinct modes:

    • lk2nd (Secondary Bootloader): Used for devices where the stock bootloader cannot be replaced. It is packed into an Android boot image and loaded by the stock bootloader. The OS kernel can be placed in the boot partition (with a 512 KiB offset) or stored in an ext2 file system.
    • lk1st (Primary Bootloader): Used for Single Board Computers (SBCs) or expert users where lk2nd acts as the first bootloader in the chain.
  2. Understand the lk2nd device-tree (DT) model

    main

    lk2nd uses a custom device-tree (DT) format to store per-device configurations. This custom format allows multiple devices to share a single DT file by using a specific layout that distinguishes between the requirements of the previous bootloader and the requirements of lk2nd.

    Note: This format is not compatible with industry-standard DT bindings used by Linux, although it attempts to maintain similarity where possible.

    DT Layout

    An lk2nd DT file consists of two main parts:

    1. Root node (/): Contains properties required by the previous bootloader (e.g., qcom,msm-id, qcom,board-id) to boot the image. lk2nd generally ignores this data.
    2. lk2nd node (&lk2nd): Contains all device-specific information used by lk2nd. This can be a single top-level node if the DT file only supports one device, or a collection of subnodes if the file supports multiple devices.
    / {
    	qcom,msm-id = <QCOM_ID_MSM8916 0>;
    	qcom,board-id = <0xCE08FF01 1>;
    };
    
    &lk2nd {
    	a3lte {
    		model = "Samsung Galaxy A3 (SM-A300F)";
    	};
    };
  3. Understand boot memory limits when using extlinux.conf

    main

    When booting via extlinux.conf, lk2nd allocates a shared memory region for the kernel, initramfs, and devicetree. This memory is limited by nearby reserved regions and varies by platform:

    • msm8960: 128 MiB
    • All other platforms: 50 MiB

    Important Considerations:

    • Booting will fail if the combined size of the kernel (after self-decompression), initramfs, and devicetree exceeds this limit.
    • For ARM 32-bit and older 64-bit kernels that do not specify decompression memory requirements, lk2nd places the initramfs and devicetree at the end of the boot memory to maximize the contiguous space available for kernel decompression.
  4. Configure display panel selection

    main

    To handle devices with multiple possible display modules, use the panel node. lk2nd can detect the panel and patch the OS device-tree with the correct compatible value.

    Standard Panel Matching

    List all possible panels under a panel node. Use the lk2nd,match-panel property in the device node to enable this matching.

    Sony LCDID ADC Matching

    For Sony devices that use an lcdid_adc parameter, define the panel by providing the expected ADC range via the sony,lcd-id-adc property.

    /* Device node matching */
    	gt58lte {
    		lk2nd,match-panel;
    		panel {
    			compatible = "wingtech,wt88047-panel", "lk2nd,panel";
    			qcom,mdss_dsi_r69431_720p_video {
    				compatible = "wingtech,sharp-r69431";
    			};
    		};
    	};
    
    /* Sony specific ADC matching */
    	sony_device {
    		panel {
    			compatible = "sony,aries-panel", "lk2nd,panel";
    			novatek_jdi_720p_cmd {
    				compatible = "sony,novatek-jdi-720p-cmd";
    				sony,lcd-id-adc = <0x109618 0x12c898>;
    			};
    		};
    	};
  5. Install build requirements for lk2nd

    main

    To build lk2nd, you must install several dependencies depending on your Linux distribution. Core requirements include make, Python 3, an ARM (32-bit) GCC toolchain, the Device Tree Compiler (dtc), libfdt, and GNU tar.

    # Example for Debian/Ubuntu
    apt install arm-none-eabi-gcc dtc libfdt-dev tar python3
  6. Install lk2nd on your device

    main

    To install lk2nd, download the lk2nd.img from the Releases page and flash it using your device's stock flashing interface.

    Using Fastboot

    fastboot flash boot lk2nd.img

    Using Samsung Heimdall

    heimdall flash --BOOT lk2nd.img

    Using EDL

    edl w boot lk2nd.img

    Fastboot Workarounds

    If you encounter the error fastboot: error: Couldn't parse partition size '0x', try these alternatives:

    • fastboot flash:raw boot lk2nd.img
    • fastboot boot lk2nd.img, then fastboot flash lk2nd lk2nd.img
    # Standard Fastboot installation
    fastboot flash boot lk2nd.img
  7. Discover available lk2nd fastboot OEM commands

    main

    lk2nd implements a subset of the standard fastboot protocol and includes several custom oem commands for debugging and development. Because availability depends on the specific build of lk2nd, you should check which commands are supported on your device by running:

    fastboot oem help
  8. Customize lk2nd menu navigation and keys

    main

    You can customize how users interact with the lk2nd boot menu using the following properties in the device node:

    • lk2nd,single-key-navigation: Used for devices like smartwatches with only one button. It enables navigation via short/long presses.
    • lk2nd,menu-key-strings: Provides custom text hints for navigation. The first string is for navigation (e.g., "Volume Down"), and the second is for selection (e.g., "Volume Up").

    Default behavior: If not set, the menu shows "Volume keys to navigate. Power key to select."

    	my_device {
    		lk2nd,single-key-navigation;
    		lk2nd,menu-key-strings = "Volume Down", "Volume Up";
    	};
  9. Install minimal DTBO for newer devices

    main

    Newer devices supported by lk2nd (specifically those using SDM429, SDM439, or SDM632 SoCs) require a custom, minimal DTBO (Device Tree Blob Overlay) partition image.

    Why this is required: Without this minimal overlay, the bootloader attempts to patch lk2nd's device trees using the stock overlay. Because the stock overlay references hardware nodes that no longer exist in the lk2nd environment, the boot process will fail.

    How to install:

    1. Download the appropriate overlay from the dtbo-lk2nd releases.
    2. Flash the downloaded image to the dtbo partition of your device.

    Devices requiring this (examples):

    • Fossil Gen 6 (hoki)
    • HMD Global Nokia 4.2 (panther)
    • Lenovo Tab M10 HD (TB-X505X)
    • Redmi 7A (pine)
    • Redmi 8 (olive)
    • Motorola Moto G7 series
    • OPPO Realme 2 / C1
    • Vsmart Joy 3
  10. Configure device nodes in lk2nd

    main

    Each device node within the &lk2nd section defines how lk2nd identifies and interacts with the hardware.

    Required Properties

    • model: The marketing name of the device (e.g., "Samsung Galaxy A3"). Do not use the name found in downstream Linux DTs.
    • compatible: A list of compatible strings for the device.
    • lk2nd,dtb-files (optional): A list of possible device-tree names. Do not include the qcom/ prefix or .dtb suffix; lk2nd adds these automatically.

    Matching Devices

    If a DT file contains multiple devices, use one of these properties to tell lk2nd which device it is running on by matching against the previous bootloader's cmdline:

    • lk2nd,match-bootloader: Matches the android.bootloader= argument using an expression.
    • lk2nd,match-cmdline: Matches the entire cmdline using an expression.
    • lk2nd,match-device: Matches the android.device= argument.
    	gt58lte {
    		model = "Samsung Galaxy Tab A 8.0 (LTE, SM-T355)";
    		compatible = "samsung,gt58lte", "samsung,gt58";
    		lk2nd,dtb-files = "msm8916-samsung-gt58";
    		lk2nd,match-bootloader = "A300F*";
    	};
  11. Use lk2nd via Fastboot and Recovery

    main

    lk2nd implements the standard Android fastboot protocol.

    Booting Modes

    • Fastboot Mode: Press Volume Down while booting.
    • Recovery Mode: Press Volume Up while booting.

    Note: If your stock bootloader uses the same key combinations, wait until the screen turns on or the device vibrates before pressing the volume keys to ensure the stock bootloader ignores them.

    Flashing and Updating

    • Update lk2nd: You can update lk2nd directly from its own fastboot interface: fastboot flash lk2nd lk2nd.img
    • Flash OS Kernel: To flash your actual OS boot image without overwriting lk2nd, use the boot partition with a 512 KiB offset: fastboot flash boot boot.img
    # Update lk2nd directly
    fastboot flash lk2nd lk2nd.img
    
    # Flash the OS boot image (uses 512 KiB offset to avoid overwriting lk2nd)
    fastboot flash boot boot.img
  12. Port a new device to lk2nd

    main

    To add support for a new device to lk2nd, you must implement a new Device Tree Source (DTS) entry. Follow these steps:

    1. Select a Target: Consult targets.md to identify the correct SoC target for your device.
    2. Implement DTS: Create the new entry following the lk2nd DTS format and bindings defined in dt-bindings.md.
    3. Verify Bindings: Ensure all hardware nodes and properties adhere to the project's specific binding requirements.