Creating your own version of the operating system for a smartphone is the highest aerobatics in the world of mobile modding. This process allows you not only to install ready-made solutions like LineageOS, but to completely redesign the logic of the device to suit your needs. You get full control over every bit of code, remove unnecessary software and optimize power consumption at the kernel level.
However, the path from stock firmware to your own build lies through the thorns of complex technical work. You'll have to deal with binaries, shell scripts, and file system structures that change frequently from version to version. Errors at any stage can turn your gadget into a โbrick,โ so preparation and understanding of the architecture Android are critically important before starting work.
In this guide, we will look at the classic method of creating custom firmware based on a stock image. We will not use ready-made automated scripts, as they often hide important details. Instead, you will learn how to manually extract, analyze and modify system partitions, which will give you the fundamental knowledge to create unique assemblies.
Preparing the working environment and tools
Before you begin manipulating firmware files, you need to organize a reliable workspace. An operating system Linuxis ideal for these tasks, in particular distributions based on Ubuntu or Debian. Although there are tools for Windows, the stability of working with ext4 file systems and executable scripts in the Linux environment is incomparably higher.
You will need to install a specialized set of utilities, without which disassembling the image is impossible. The key tool is Android Image Kitchen or its console analogues, such as unpackimg.sh i repackimg.sh. These scripts automate the process of dividing the boot image into_kernel_, ramdisk and the system partition.
You also cannot do without a powerful archiver and hex code editors. Standard 7z or unzip will be needed to work with archives inside the firmware, and hexedit will allow you to make edits to binary files if necessary for security patching or bypassing signature checks.
Use a virtual machine with Linux if you have a main system Windows. This isolates the development environment and prevents driver conflicts when working with connected devices.
Make sure you have enough free space on your computer. Unpacked images of system partitions can take up tens of gigabytes, especially if you are working with firmware containing a full Gapps package. It is recommended to have a reserve of 50-100 GB on disk.
Extracting and analyzing stock firmware
The first step in creating a custom build is obtaining the source material. You need stock firmware (Stock ROM) specifically for your device model. It should be downloaded only from the official websites of manufacturers or trusted resources like Sammobile or Xiaomi Firmware Updaterto avoid malicious modifications.
After downloading the firmware file (usually an archive .zip or file .tar.md5), it must be unpacked. Inside you will find several image files: boot.img, system.img, recovery.img and others. We are primarily interested in boot and system, since they contain the kernel and user part of the system.
โ๏ธ Primary analysis of the firmware
To work with a system image, format conversion is often required. Modern firmware uses the format super or compressed images dat.br. You may need a utility simg2img to convert the .sparse image to .raw so that the file system becomes available for mounting.
โ ๏ธ Attention: Never use firmware from other device models, even if the processors are the same. Differences in drivers and memory layout will lead to an instant bootloop or partition damage EFS, which will make IMEI recovery almost impossible.
Analysis of the structure of the resulting file allows us to understand what we are dealing with. Commands like fdisk -l system.img will show the partition table if the image contains several partitions. It is important to know this before attempting to mount in order to select the correct offset.
Unpacking the boot image and modifying the kernel
The image boot.img contains the kernel (kernel) and the initial disk (ramdisk). This is where the parameters for loading and mounting partitions are configured. To unpack it, use a script unpackimg.shthat will divide the file into its component components.
After unpacking, you will receive a folder with the name of your image, inside which will be the file kernel and folder ramdisk. Modifying the kernel is a task for advanced users, requiring knowledge of compilation for a specific architecture (arm64-v8a). Most often, modders limit themselves to replacing the kernel with a precompiled one, for example, from KernelSU or Magisk.
The main work is carried out in the folder ramdisk. The initialization scripts init.rc and init.usb.rcare stored here. By editing these files in a text editor (for example, VS Code or Notepad++), you can change file permissions, add services, or change the system's boot behavior.
What is init.rc?
This is the script that runs very first after the kernel boots. It mounts partitions, starts key daemons, and sets access rights. An error in the syntax of this file will result in the phone not booting beyond the logo.
If your goal is to obtain superuser rights, the easiest way is to embed binary files into the ramdisk Magisk. This requires adding lines to init.rcthat will start the Magisk service at an early stage of boot, before the system checks the integrity of the partitions.
After making all the changes to the ramdisk and replacing the kernel (if required), you need to put the image back together. A script is used for this. repackimg.sh. It will pack the modified files back into the structure boot.img, respecting the original header and page parameters.
Mounting and editing the system partition
The most extensive part of the work is modifying the partition system. This is where applications, frameworks, and interface resources live. To access the contents of the image, you must mount it into a Linux virtual file system.
Create a mount point with the command mkdir /mnt/system, and then issue the mount command. If the image is in raw format, the command will look simple: mount -o loop system.img /mnt/system. For images with multiple partitions, you may need to specify the offset, which can be found through the utility fdisk.
| File type | Location | Purpose |
|---|---|---|
build.prop |
/system/ | Device properties and Android version |
services.jar |
/system/framework/ | System services and operating logic of the OS |
Settings.apk |
/system/priv-app/ | Settings application |
libart.so |
/system/lib64/ | Android Runtime virtual machine library |
After mounting, you get full access to the files. You can remove system applications (bloatware), replacing them with empty stubs or simply deleting apk files. You can also replace fonts, sounds, and graphic resources in the folder /system/media.
โ ๏ธ Attention: Use extreme caution when deleting system applications. Removing critical components such as Package Installer or SystemUIwill make the interface unable to load. Always make a backup copy of deleted files on your computer before destroying them.
To implement root access at the system level (if you do not use Magisk in boot), you need to copy the binary su to the directory /system/xbin or /system/bin and set execution rights to it chmod 6755. You will also need to install a superuser manager as a system application.
Finished edit, it is important to unmount the partition correctly. Use the command umount /mnt/system. If the system writes that the device is busy, make sure that you close all file managers and terminals working with this folder. Incorrect unmounting can damage the image.
Assembling the firmware and signing images
After modifying all the necessary images (boot and system), the stage of assembling the final package begins. Most often, custom firmware is distributed in the format update.zip, which can be installed through custom recovery (TWRP or OrangeFox).
You will need to create a folder structure that mimics the update file system. Usually these are folders META-INF with installation scripts (updater-script), and folders with the images themselves. The script updater-script contains commands for formatting partitions and writing new images to the device memory.
A critically important step is signing the firmware. The device bootloader verifies the digital signature before installation. If you are creating firmware for installation via custom recovery, the signing requirement is often disabled, but for some devices (especially Xiaomi or Huawei) this is still relevant.
A set of tools are used for signing Android SignApk. You will need two files: a private key (testkey.x509.pem) and a certificate file. The signing process ensures that the file was not damaged during transmission and was actually created by the author.
Custom recovery (TWRP) usually ignores signature verification, which simplifies the installation of homemade assemblies. However, for the unlocked bootloader of some brands, the signature is still required even in recovery mode.
The final archive update.zip is collected via the console command zip -r. It is important to add files without compression (flag -0) for images, since recovery may not correctly unpack compressed binary images during flash.
Testing and debugging a custom build
Before installing the firmware on the main smartphone, it is strongly recommended to test it on emulator or spare device. The emulator Android Studio allows you to load a custom image of the kernel and system, but it does not emulate specific hardware (camera, modem), so a full test is only possible on a real device.
When loading your firmware for the first time, carefully monitor the logs. Connect your phone to your PC and use the utility adb logcat to view the system log in real time. The command adb logcat | grep -i error will help you quickly filter out critical failures.
Frequent problems include a โbootlapโ (cyclic reboot) or lack of network. A bootloop is often caused by errors in access rights (permissions) to files in /system. The lack of a network may be a consequence of modem driver incompatibility if you accidentally touched the section firmware.
โ ๏ธ Attention: If the phone goes into bootlap immediately after the logo, do not panic. Boot into recovery mode and do a data wipe (Factory Reset). Sometimes new firmware conflicts with data from the old version, and a clean installation solves the problem.
The debugging process can take a long time. You will have to repeat the steps cyclically: modification -> assembly -> firmware -> test. Keep a log of changes to understand exactly which edit caused system instability.
Frequently asked questions about creating firmware
Is it possible to create firmware without unlocking the bootloader?
No, it is impossible. The locked bootloader (Locked Bootloader) verifies the digital signature of each downloaded image. If the signature does not match the factory signature (and your custom firmware will not have one), the bootloader will refuse to start the system. First, you need to officially unlock the bootloader through the command fastboot oem unlock or similar.
What file format is best to use for system.img?
For compatibility with old recovery, it is better to use the format raw (uncompressed image). However, it takes up a lot of space. Modern recovery supports formats sparse and compression lz4. It is recommended to use the format that was used in the stock firmware of your device to avoid recording errors.
Why does the camera not work after the firmware?
The camera in Android is closely related to proprietary drivers and libraries located in the vendor and firmware. If your custom firmware is based on stock, but you change the Android or kernel version, the libraries may become incompatible. The solution is to use the stock image vendor.img without changes.
Is it safe to use scripts from the Internet for automatic assembly?
Using ready-made scripts (kitchen) speeds up the process, but carries risks. The script may contain errors or outdated commands that do not work correctly with new versions of Android (12/13/14). To learn and create reliable firmware, it is better to understand each step manually, and enable automation only after debugging the process.