version 1.4

1. Partition Introduction

1.1. SPI-NOR Flash Basic Partition

ALKAID will print the layout of all partitions after the make image is completed:

  • IPL

    After the CPU is powered on, the rom code is the first to run. The code is stored in a special ROM and is read-only. After the ROM code runs, read the location of the NOR Flash 0 address, which is the location where the IPL file is stored. The main function of IPL is to do some basic hardware initialization, such as setting the current DDR parameters, or GPIO/IIC related.


    IPL initializes the common hardware module. In IPL_CUST, the executable binary file of the customized board hardware is initialized according to the actual situation of the board, such as customized GPIO pins and IIC config.

  • MXPT

    Partition to configure the related binary files.


    UBOOT binary files storage partition.


    UBOOT environment variables storage partition.

  • LOGO

    Used on the NVR device to store the config related to the boot logo.

It is not recommended to change the content in the BOOT partition of SPI-NOR. Inconsistent with the released public board may cause the system to fail to boot.

BOOT is in the position of mtd block0 of linux, corresponding to the device node /dev/mtdblock0.

The SYS partition is the collective name of the partition after the BOOT partition, which can be modified. According to the actual usage, it can be divided into four categories:


    Store the binary files of the kernel.


  • miservice

    It is a partition defined by the public board, which is used to store mi libraries and some config files. The file system defaults to jiffs2.

  • customer

    Custom partition.

1.2. SPI-NAND Flash Basic Partition

Layout example:

  • CIS

    It is a unique partition of SPI-NAND, which is stored in the location of flash 0 address.

    1. spinand info

      Save the basic information of spinand, which can be changed according to the type of spinand, such as block page count, block count, etc.;

    2. partinifo

      Save the partition information, which is read by the rom code. The rom code obtains the location of the IPL by reading the correct spinand parameters and partition information to run the entire system.

  • IPL

    The function of the IPL partition is the same as that of the SPI-NOR partition, but as can be seen from the above figure, IPL saves one copy for each block on the spi-nand, a total of six copies, the purpose is to make a backup to prevent bad blocks.


    Its function is the same as SPI-NOR, there are two partitions, IPL_CUS0 and IPL_CUS1, each of which contains three copies of IPL_CUS data.


    UBOOT binary files storage partition. There are two partitions, one copy of data in each partition.

  • ENV

    UBOOT environment variables storage partition.

  • LOGO

    Used on the NVR device, it stores the config related to the boot logo.

The above is the partition information related to BOOT and cannot be modified arbitrarily.


    Store the binary files of the kernel.


  • UBI

    The content of UBI is not shown in the partition table above. UBI will create multiple sub-partitions in ubifs format, and users can create according to needs. Spinand's miservice partition is placed in UBI.

1.3. MISERVICE Partition

After the contents of the MISERVICE partition are mounted to the root directory /config/, the file paths in the bold font below must be consistent, otherwise the system may not start.

└── config

├── board.ini ---->Save the current board information

├── config_tool ---->APP for mi sys initializing mmap memory

├── dump_config -> config_tool ---->APP for dumping config, config_tool symbol link

├── dump_mmap -> config_tool ---->APP for dump mmap, config_tool symbol link

├── fbdev.ini ---->Framebuffer config, it can be deleted if no need for fbdev.

├── iqfile

│   ├── imx307_iqfile.bin

│   ├── iqfile0.bin -> imx307_iqfile.bin ---->Sensor IQ related bin

│   ├── iqfile1.bin -> imx307_iqfile.bin

│   ├── iqfile2.bin -> imx307_iqfile.bin

│   ├── iqfile3.bin -> imx307_iqfile.bin

│   └── isp_api.xml

├── mmap.ini ---->Mmap. Refer to Memory Layout for Mmap.

├── model ----> Module related configuration,which can be deleted.

│   ├── Customer_1.ini

│   ├── Customer_2.ini

│   └── Customer_auto_test.ini

├── modules ---->System KO storage path.

│   └── 4.9.84

│   ├── cifs.ko


├── pq ---->NVR shows it is related to PQ.

│   ├── Bandwidth_RegTable.bin

│   ├── Main.bin

│   └── Main_Ex.bin

├── terminfo ---->Console display related.

│   └── v

│   ├── vt100


└── venc_fw ---->Encoder的firmware

└── chagall.bin

2. Partition Change

2.1. Note

The partitions on spi-nor flash and spi-nand flash can be classified into two categories:

  • Recommended unchanged boot

  • Variable sys

The partition changes introduced in this chapter are all on the sys part, including how to configure scripts to change the partition order, how to package partitions, and how to generate burning scripts. If user has a set of packaging and burning procedures, please ignore this chapter. Note: The files marked in bold font in the miservice partition need to be placed in the specified path for the system to run. Therefore, when creating the partition, be sure to create /config/ in the root directory and place the relevant files in this path.

2.2. Script Architecture

Partition changes are divided into partition production/packaging and partition burning script production.

In the two branches in the figure below, the left is the partition production and packaging process; the right is the partition burning script production process which supports tftp upgrade scripts, but does not support usb upgrade script production.

  • xxx.partition.config:

    It is the general partition configuration information script, which has many copies. All the codes related to partition adjustment are implemented here. Each different chip, spinand partition, and spinor partition have its own partition config file.

    Find the partition config file used by the project through build config, such as the build config used by a project:


    In this configuration script, the variable IMAGE_CONFIG can find the used partition config script.

    The storage path of the partition config script of this project:


    It can be seen that this is a spinor flash partition config script file.

    Use variable to define BOOT partition and SYS partition in the partition config file:

        mxp$(BOOTTAB) = ”xxx”
        mxp$(SYSTAB) = ”xxx”
        cis$(BOOTTAB) = xxx
        cis $(SYSTAB) = xxx

    In the config script, each partition is represented by a set of variables. The above mxp and cis are special partition variables, which store a set of specified partition config (raw data). Special partitions are generated by special commands, please refer to Special Partition.


    ROOTFS and miservice partition production script. The project uses project/mage/configs/$(CHIP)/


    Script for producing spi-nand and burning spi-nor. The project uses project/mage/configs/$(CHIP)/ and project/mage/configs/$(CHIP)/


    Partition packaging script, the path is project/mage/

2.3. Partition Location Change

2.3.1. Spinor Flash

Just change the position before and after the partition defined in mxp$(SYSTAB), the syntax format is the same as the mtdpart used in linux uboot.

mxp$(SYSTAB) = "$(kernel$(PATSIZE))(KERNEL),$(rootfs$(PATSIZE))(rootfs),$(miservice$(PATSIZE))(miservice),$(customer$(PATSIZE))(customer)"

The partition information of kernel and rootfs are separated by ’, ’.

2.3.2. Spinand flash

Just change the location before and after the partition defined in cis $(SYSTAB). The syntax format is the same as the mtdpart used in linux uboot, and the value of this variable will also be saved in the environment variable in uboot.

cis$(SYSTAB) = $(kernel$(MTDPART)),$(rootfs$(MTDPART)),-(UBI)

The partition information of kernel and rootfs are separated by ’, ’.

2.4. Add/Modify/Delete jiffs2 partition

The flash of spinor uses jiffs2 as the readable and writable partition file system. The relevant config of the customer partition is defined as follows:

customer$(RESOUCE)   = $(OUTPUTDIR)/customer

customer$(FSTYPE)    = jffs2

customer$(PATSIZE)   = 0x6B0000

customer$(MOUNTTG)   = /customer

customer$(MOUNTPT)   = mtd:customer

customer$(OPTIONS)   = rw
  • customer$(RESOUCE)

    It indicates the location where the partition resource file is placed, and respectively add necessary files to the path, and package the folder into a bin file.

  • customer$(FSTYPE)

    Packaged file system type.

  • customer$(PATSIZE)

    Partition size.

  • customer$(MOUNTTG)、customer$(MOUNTPT)、customer$(OPTIONS)

    It indicates the path and parameters of the partition that needs to be mounted after the board is running, which will be processed in

2.4.1. Modify Partition

To modify the partition, please change the value of the above variables.

2.4.2. Add Partition

  1. Suppose you add a partition named aaa, and configure its size and other information.

    aaa$(RESOUCE)   = $(OUTPUTDIR)/aaa
    aaa$(FSTYPE)    = jffs2
    aaa$(PATSIZE)   = 0x6B0000
    aaa$(MOUNTTG)   = /aaa
    aaa$(MOUNTPT)   = mtd:aaa
    aaa$(OPTIONS)   = rw
  2. After the partition-related variables are configured, specify their placement in mxp$(SYSTAB) = ”xxx”.

  3. Add "aaa" at the end of the variable "IMAGE_LIST".

  4. Add "aaa" at the end of the variable "USR_MOUNT_BLOCKS" indicating the node that needs to be mounted.

2.4.3. Delete Partition

Reverse the operation of adding partition.

2.4.4. Burning Script

The system will automatically generate it in according to the partition config.

2.5. Add/Modify/Delete Squashfs Partition

Squashfs partition changes and jiffs2 partition changes are mainly different in xxx$(FSTYPE). Except for the rootfs partition, the miservice partition is made into squashfs as follows:

miservice$(RESOUCE)   = $(OUTPUTDIR)/tvconfig/config

miservice$(FSTYPE)    = squashfs

miservice$(PATSIZE)   = 0x180000

miservice$(MOUNTTG)  = /config

miservice$(MOUNTPT)  = /dev/mtdblock3

miservice$(OPTIONS)   = ro

If you are using spinand's partition configuration script, place the partition in cis$(SYSTAB) = xxx.

Like the jiffs2 partition, the system will automatically generate a burning script in according to the partition config.

2.6. Add/Modify/Delete UBIFS Partition

UBIFS partition is used as a readable and writable partition file system on spinand.

All partitions of BIFS belong to a sub-partition in the mtd block of UBI. A common UBI partition variable is set as follows:

miservice$(RESOUCE)   = $(OUTPUTDIR)/miservice/config

miservice$(FSTYPE)    = ubifs

miservice$(PATSIZE)   = 0xA00000

miservice$(MOUNTTG)  = /config

miservice$(MOUNTPT)  = ubi0:miservice

miservice$(OPTIONS)   = rw

Different from jiffs2 partition change, ubifs partition does not need to add mtdpart information, that is, there is no need to add partition location in cis$(SYSTAB)= xxx.

2.7. Special Partition

Kernel, uboot, IPL, and logo are special partitions without special file system. Makefile scripts cannot be used for centralized processing. They must be processed by case.

Therefore, to add a special partition, you need to understand the following steps.

2.7.1. Kernel Partition

The script command for partition packaging needs to be written in

Kernel partition packaging commands:

    @echo [[$@]]
    cp -rvf $($(patsubst %_nofsimage,%,$@)$(RESOUCE)) (IMAGEDIR)/$(patsubst %_nofsimage,%,$@)

Write the commands generated by the partition burning script in script

Script commands for producing Kernel partition burning script:


    @echo "aaaabbbaaaaaaa $@"

    @echo "# <- this is for comment / total file size must be less than 4KB" > $(SCRIPTDIR)/[[

    @echo tftp $(TFTPDOWNLOADADDR) kernel >> $(SCRIPTDIR)/[[

    @echo nand erase.part KERNEL >> $(SCRIPTDIR)/[[

    @echo nand write.e $(TFTPDOWNLOADADDR) KERNEL \$${filesize} >> $(SCRIPTDIR)/[[

    @echo nand erase.part RECOVERY >> $(SCRIPTDIR)/[[

    @echo nand write.e $(TFTPDOWNLOADADDR) RECOVERY \$${filesize} >> $(SCRIPTDIR)/[[

    @echo "% <- this is end of file symbol" >> $(SCRIPTDIR)/[[
    @echo kernel-image done!!!

2.7.2. Partition With Backup

In the SPINAND partition, IPL, IPL_CUST, UBOOT partitions generally have multiple backups.

For example, during IPL programming, the data of each IPL will occupy one copy at the beginning of each block. The size of a block is 128kb. Generally, the data of IPL does not exceed 20kb. Assuming that there are six backups of IPL data, the size of the entire IPL partition is equal to 6 blocks. When the partition is packaged, use the dd command to package the IPL partition so that the output bin file can be fully mapped with the IPL partition, and 6 copies of IPL data are distributed at the beginning of each block.

Set the partition with backup, refer to the following code:

ipl$(RESOUCE) = $(PROJ_ROOT)/board/$(CHIP)/boot/ipl/IPL.bin

ipl$(DATASIZE) = 0x20000

ipl$(COPIES) = 6

ipl$(BKCOUNT) = 5

ipl$(PATSIZE) = $(call multiplyhex, $(ipl$(COPIES)), $(ipl$(DATASIZE)))

ipl$(MTDPART) = $(ipl$(DATASIZE))@$(cis$(CISSIZE))(IPL0)$(ipl$(BKCOUNT))

Ipl$(COPIES) means that there are multiple backups of IPL data.

ipl$(DATASIZE) means the size of a piece of data. If the bin file of IPL does not exceed the size of 1 block, it will be counted as 1 block.

ipl$(PATSIZE) is the actual partition size of the IPL. The multiplication in the makefile is the number of backups multiply the data size.

ipl$(BKCOUNT) is a unique data in the PNI data structure. When the system is running and there are no bad blocks, the system uses the first data of IPL by default. But if a bad block is generated at the location of the first data, the ROM code will shift a block to find the IPL. This BKCOUT variable tells ROM code the max number of blocks that can be shifted.

ipl$(MTDPART) is a variable used by pnigenerator to resolve partition configuration. It will be passed to cis$(BOOTTAB) or cis$(SYSTAB). If there is no BKCOUNT, the syntax format conforms to the uboot mtaparts standard. When the variable MTDPARTS is not defined, uboot will parse the value of pni while writting cis command, and convert it to mtdparts string and save it in the environment variable.


After ARM starts, it will enter a fixed ROM CODE:

After the ROM code is started, it will start to the IPL according to the fixed address, but IPL will first find a copy of raw data, which is MXP or PARTINFO.

MXP/PARTINFO saves the config info of the SPINOR/SPINAND partition. There is no concept of mtdpart when arm starts to execute to IPL, so read the content in MXP or PARTINFO to find IPL_CUST or uboot.

In summary, the address of MXP/PARTINFO is fixed.


The partition modification of SPINOR is dynamically generated by mxpgenerator through different parameters passed in and then summarized to MXP_SF.bin. In the ALKAID compilation and packaging environment, is responsible for the packaging steps of the partition, and MXP_SF.bin is generated through a shell script.

mxpgenerator executes the commands:

mxpgenerator "0x10000(IPL),0x10000(IPL_CUST),0x10000(MXPT),0x1F000(UBOOT),0x1000(UBOOT_ENV)" "0x200000(KERNEL),0x400000(rootfs),0x300000(miservice),0x6B0000(customer)" /home/malloc.peng/ALKAID/project/image/output/images/boot/MXP_SF.bin

The three parameters of mxpgenerator: mxpgenerator [v0] [v1] [v2]:

  • [v0]

    The input is the partition config of the BOOT part.

  • [v1]

    The input is the sys partition.

  • [v2]

    Output file path.

mxpgenerator source code path:


Compile with gcc on the server:

gcc mxpgenerator.c –o mxpgenerator


PARTINFO.pni generates PARTINFO.pni through pnigenerator and saves it in the CIS partition, which includes some spinand basic information.


pnigenerator -s 64 -p 2048 -b 64 -k 1024 -u 8 -l 0x20000 -t "0x60000(CIS),0x20000@0x60000(IPL0),0x20000(IPL1),0x20000(IPL2),0x20000(IPL_CUST0),0x20000(IPL_CUST1),0x20000(IPL_CUST2),0x60000(UBOOT0),0x60000(UBOOT1),0x20000(ENV)" -y "0x500000(KERNEL),0x500000(RECOVERY),0x600000(rootfs),-(UBI)" -o /home/malloc.peng/ALKAID/project/image/output/images/boot/PARTINFO.pni

pnigenerator [options]


-s Spare byte count.

-p Page byte count.

-b Block page count.

-k Block count.

-u Unit byte count.

-l Block size.

-t BOOT Part

-y SYS Part

-r Dump pni file

-o Output file path.

pnigenerator source code path:


Compile with gcc on the server:

gcc pnigenerator.c –o pnigenerator

Save the partition information of BOOT part to PARTINFO.bin, and others can be added to mtdparts of uboot.


ONE BIN is based on the packaging script of ALKAID, through the dd command to merge the BOOT PART partition into a bin, and supports the spinand and spinor partition packaging.

The specific method of dd command to merge bin is in project/image/

3.1. Spinor



Compared with ordinary packaging scripts:

  1. Added the partition name that needs to be merged.

    BOOT_IMAGE_LIST = ipl ipl_cust mxp uboot

  2. Delete the merged partition in IMAGE_LIST, and add the merged partition name boot.

    IMAGE_LIST = boot kernel rootfs miservice customer

  3. Add the sstar partition in the config file.

    boot$(RESOUCE) = $(IMAGEDIR)/boot/sstar.bin

    boot$(PATSIZE) = $(shell printf 0x%x $(shell stat -c "%s" $(sstar$(RESOUCE))))

  4. Add the script generated by sstar image and the tftp burning script in and

    @echo [[$@]]
    dd if=/dev/zero of=$(boot$(RESOUCE)) bs=1 count=0

        @echo "# <- this is for comment / total file size must be less than 4KB" > $(SCRIPTDIR)/[[uboot
        @echo mxp UBOOT >> $(SCRIPTDIR)/[[uboot
        @echo sf probe 0 >> $(SCRIPTDIR)/[[uboot
        @echo sf erase \$${sf_part_start} \$${sf_part_size} >> $(SCRIPTDIR)/[[uboot
        @echo tftp $(TFTPDOWNLOADADDR) boot/$(notdir $(uboot$(RESOUCE))) >> $(SCRIPTDIR)/[[uboot
        @echo sf write $(TFTPDOWNLOADADDR) \$${sf_part_start} \$${filesize} >> $(SCRIPTDIR)/[[uboot
    @echo "% <- this is end of file symbol" >> $(SCRIPTDIR)/[[uboot

3.2. Spinand



Compared with ordinary packaging scripts:

  1. Added the partition name that needs to be merged.

    BOOT_IMAGE_LIST = ipl ipl_cust uboot

  2. Delete the merged partition in IMAGE_LIST, and add the merged partition name boot.

    IMAGE_LIST = cis boot kernel rootfs miservice customer

  3. Update MTDPART setting:

    MTDPARTS = "mtdparts=nand0:$(boot$(MTDPART)),$(cis$(SYSTAB))"

  4. Confirm multiple copies of the partition

    ipl_cust$(RESOUCE) = $(PROJ_ROOT)/board/$(CHIP)/boot/ipl-dualos/IPL_CUST.bin
    ipl_cust$(DATASIZE) = 0x20000
    ipl_cust$(COPIES) = 3
    ipl_cust$(BKCOUNT) = 2
    ipl_cust$(PATSIZE) = $(call multiplyhex, $(ipl_cust$(COPIES)), $(ipl_cust$(DATASIZE)))
    ipl_cust$(PATCOUNT) = 2
    ipl_cust$(MTDPART) = $(ipl_cust$(DATASIZE))(IPL_CUST0)$(ipl_cust$(BKCOUNT)),$(ipl_cust$(DATASIZE))(IPL_CUST1)$(ipl_cust$(BKCOUNT))

    Note: PATSIZE depends on the current data size and the number of data contained in a partition.

    For example, the number of data in ipl_cust is six, so COPIES = 6.

    Data is scattered in two partitions (IPL_CUST0/IPC_CUST1), each partition occupies three copies, and each copy is 0x20000, so PATSIZE = 0x20000 * 3 = 0x60000.

  5. Add the boot partition in the config file.

    boot$(RESOUCE) = $(IMAGEDIR)/boot.bin
    boot$(PATSIZE) = $(shell printf 0x%x $(shell stat -c "%s" $(boot$(RESOUCE))))
    boot$(MTDPART) = $(boot$(PATSIZE))@$(cis$(PATSIZE))(BOOT),0x40000(ENV)
  6. Add the script generated by boot image and the tftp burning script in and

  7. After the ipl/uboot merge, the mtd device of the system is reduced. When the partition is mounting, please pay attention to whether the block id corresponds to /dev/mtdblock.

    @echo [[$@]]
    dd if=/dev/zero of=$(boot$(RESOUCE)) bs=1 count=0

    @echo "# <- this is for comment / total file size must be less than 4KB" > $(SCRIPTDIR)/[[
    @echo tftp $(TFTPDOWNLOADADDR) boot.bin >> $(SCRIPTDIR)/[[
    @echo nand erase.part BOOT >> $(SCRIPTDIR)/[[
    @echo nand write.e $(TFTPDOWNLOADADDR) BOOT \$${filesize} >> $(SCRIPTDIR)/[[
    @echo "% <- this is end of file symbol" >> $(SCRIPTDIR)/[[