4.4.2. Integrating User Software into System Image
During development, it is often necessary to directly include certain configuration files or completed programs into the system image, so that these files or programs can be used directly on the target device when it runs. This chapter details two commonly used methods for integrating user software and files into the system image:
Adding files to the
systempartition of the root file systemThis method is suitable for files that need to be deployed alongside system files, such as system libraries or system configuration files. By placing files in the
systempartition, they can be loaded and used immediately upon device boot.Creating a new dedicated partition to store custom files
By creating a new partition and storing custom files or programs within it, greater flexibility and modularity can be achieved. The new partition generates an independent image file, making management and updates easier, while also avoiding any impact on the root file system.
Each method has its own characteristics, and the appropriate integration approach can be selected based on requirements to optimize development and deployment workflows. The following sections describe both methods in detail.
4.4.2.1. Adding Files to the system Partition of the Root File System
Integrating user-defined files into the root file system is very simple. Just copy the prepared files into the directory system/buildroot/prebuilt/boot-utils-runtime. During compilation of the system image, all contents in this directory will be automatically packaged into the system partition without requiring additional steps. The build script responsible for merging these files is located in the BSP source code at build/mk_system.sh, with the implementation shown below:
function build_unpack()
{
... (omitted) ...
# Merge auto-start configuration items
if [ -d "${SYSTEM_ORIG_DIR}/boot-utils-runtime" ]; then
rm -rf "${SYSTEM_BUILD_DIR}"/etc/dropbear
cp -arf --remove-destination ${SYSTEM_ORIG_DIR}/boot-utils-runtime/* "${SYSTEM_BUILD_DIR}"
fi
}
Notes:
The actual size of the
systempartition may vary depending on the software version. If the added files cause the total size of the partition to exceed its predefined capacity, image generation will fail. To avoid this issue, the size of thesystempartition can be adjusted by modifying the partition table. For detailed instructions, refer to Partition Configuration.
Before proceeding, confirm the capacity limit of the system partition and ensure that the added files do not exceed available space.
4.4.2.2. Creating a Dedicated Partition for Custom Files
To manage programs or configuration files more flexibly, a new dedicated partition can be created specifically for storing such content. This approach is particularly suitable for scenarios where programs need to be independently compiled, managed, and upgraded. This section uses the configuration of an app partition as an example to illustrate the procedure (the app partition is supported by default).
Notes
Regarding the Last Partition in the Partition Table
If the newly added partition is placed after the last partition in the partition table (e.g., after the
userdatapartition), note the following behaviors:During system startup, the
U-Bootstage automatically extends the last partition to the end of the physical storage device (e.g., eMMC or NAND Flash) to maximize storage utilization.On first boot, if the kernel detects that the last partition is unformatted or lacks a valid file system, it will automatically perform formatting.
Default Settings for the
userdataPartitionDuring system image generation, the
userdatapartition is typically the last partition, contains no data, and is set to a small size (default 50MB) to reduce image size.After booting,
U-Bootautomatically expands theuserdatapartition to occupy the remaining storage space, and the system formats this partition upon first entry.If adding a new partition after
userdata, adjust the size ofuserdataaccordingly to meet actual requirements.
About Empty Partitions
If the new partition is empty (no valid data, such as
userdataorprivate) during image creation, it must be formatted during the first system boot.The formatting logic can be referenced from the
/etc/init.d/S65mountallscript. Add the new partition name to theforce_format_part_listvariable, for example:force_format_part_list="app userdata log private"
Implementation Steps
1. Modify the Partition Table
Define the new partition in the partition table. For example, in device/horizon/x5/board_cfg/soc/x5-soc-debug-gpt.json, add the following configuration:
"app": {
"fs_type": "ext4",
"part_type": "GOLDEN",
"size": "700m"
},
fs_type: File system type of the partition, set toext4.size: Size of the partition, in MB (example:700m).
For more information about partition table configuration, please refer to Partition Configuration.
2. Prepare Partition Content
Create a directory (e.g., app) to store the partition’s files and add required files. For example, add a startup script named startup.sh:
# Execute the following commands under the BSP source root directory
mkdir app
cd app
echo "#!/bin/sh" > startup.sh
echo 'echo "This is the test code"' >> startup.sh
chmod 777 startup.sh
This step can be skipped if the new partition is intended to be empty. In the current system, the startup.sh scripts under /app and /userdata are invoked during system startup by the /etc/init.d/S99auto_startup service.
3. Verify and Generate Partition Image
Refer to the following build command to generate the image based on the partition directory content, for example:
./build/mk_app.sh
The generated image file will be located at out/product/app.img. This step can be skipped if the new partition is empty.
4. Integrate Build Script
Add partition build logic into xbuild.sh:
Add the partition option in
avail_func:avail_func=("all" "lunch" "miniboot" "uboot" "factory" "boot" "hbre" "system" "app" "pack" "otapackage")
Define the
build_appfunction:function build_app { is_exist=$(get_part_exist app) if [ "$is_exist" = "0" ]; then return fi build_component "app" "${HR_LOCAL_DIR}/mk_app.sh" "$@" }Include the
apppartition in the overall build logic:if [ -d "${HR_TOP_DIR}/app" ]; then build_app "$opt" fi
After adding the above code, you can compile and generate app.img using ./bd.sh app or ./mk_app.sh.
5. Automatically Mount the New Partition
After adding a new partition to the system, to ensure it is automatically mounted at boot time, add the corresponding mount configuration in the file system/buildroot/prebuilt/boot-utils-runtime/etc/hb-fstab. For example, the mount configuration for the new app partition is as follows:
/dev/block/platform/by-name/app /app ext4 defaults 0 1
Below is the meaning of each field and related notes:
Device Path (
/dev/block/platform/by-name/app)Specifies the path to the partition device.
This path may vary depending on the hardware and partition configuration; ensure it matches the actual device path.
Mount Point (
/app)Specifies the target directory where the partition will be mounted.
At system startup, the partition contents will be mounted under this directory.
Ensure this directory is created during image generation; otherwise, the system may fail to mount the partition, potentially causing boot failure. For example, add directory creation logic in the
build_unpackfunction ofmk_system.sh:mkdir -p ${SYSTEM_BUILD_DIR}/{app,log,userdata,usr/hobot,data,private}
File System Type (
ext4)Specifies the file system type of the partition.
Choose the appropriate value according to the actual file system format (e.g.,
ext4,vfat, etc.).This must match the
fs_typeconfigured in the partition table.
Mount Options (
defaults)Uses default mount options.
defaultsis a predefined set of options that includes:rw(read-write mode): Allows read and write operations on the partition.suid(allow set-user-ID): Allows execution of files with SUID (Set User ID) and SGID (Set Group ID) permissions, enabling certain programs to run with the file owner’s privileges.dev(allow device files): Allows device files (e.g., those in/dev) to exist within the partition.exec(allow execution of files): Allows execution of binaries and scripts within the partition.auto(automatic mounting): Enables automatic mounting of the partition at system startup.nouser(disallow mounting by regular users): Only root or users with specific privileges can mount the partition.async(asynchronous I/O): Enables asynchronous I/O operations, improving performance.
In the
apppartition’s mount configuration, thedefaultsoption means:The device
/dev/block/platform/by-name/appwill be mounted read-write to/app.Files in the partition can have SUID/SGID bits set to support specific program privilege requirements.
Executables in the partition can be run, ensuring application functionality.
The partition will be automatically mounted at boot without manual intervention.
Only root or privileged users can mount the partition, enhancing system security.
I/O operations will be performed asynchronously, improving performance.
The
defaultsoption ensures the partition has basic read, write, and execute permissions upon mount.If custom mount parameters are needed, replace
defaultswith specific options. For example:ro: Mount read-only.rw: Mount read-write (default).noexec: Prohibit execution of binaries in the partition.nosuid: Disallow SUID and SGID flags.
Dump Backup Flag (
0)Indicates whether the partition should be backed up by the
dumputility.Set to
0means no backup, which is the usual setting.
File System Check Order (
1)Specifies the order in which the file system is checked at boot time.
0means no check.Non-zero values indicate check priority, with smaller numbers having higher priority.
6. Package the Partition into the System Image
After completing all configurations, use the build script to generate the partition image and pack the new partition image into the system image.
Run the full build and packaging process using the following command:
./bd.sh
If the new partition is empty (i.e., contains no actual data during image generation, like the userdata partition), you may choose to skip packing its image. In the truncate_fill_image function of the xbuild.sh script, adjust the logic as follows:
# FIXME: If there is actual data in the partition behind the mirror, pack will be skipped.
# Currently skipping log and userdata partitions; should be optimized to identify the last partition with data based on configuration
case "${part_name}" in
log*|userdata*|app*)
rm -f "${HR_TARGET_PRODUCT_DIR}/${part_name}".img
;;
esac
After completing the above steps, the new partition (e.g., app) will be compiled and integrated into the system image.
To verify, check whether the image file out/product/app.img exists, and validate the functionality of the new partition by flashing or booting the system.
Verification
After flashing:
If the user connects to the device via serial console during system startup, the log output
This is the test codeshould appear in the serial logs, indicating that/app/startup.shhas executed.Use
fdisk -lto view the partition table and confirm the existence of theapppartition with a size of700MB(the size must match the actual partition table configuration).Use
mountto confirm the partition is mounted at/app.Use
ls /appto check the partition contents and confirm thatstartup.shexists and is executable.Example output:
# ls /app/ startup.sh lost+found