• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Startup
2
3
4## Context Structure
5
6The following figure shows the context structure of the Startup subsystem.
7
8  **Figure 1** Context structure of the Startup subsystem
9
10  ![context-structure-of-the-Startup-subsystem](figures/context-structure-of-the-Startup-subsystem.png)
11
12When the system is powered on, the kernel loads and starts services and applications as follows:
13
141. The kernel loads the init process, which is specified by `cmdline` of the kernel when the bootloader starts the kernel.
152. After the init process is started, `tmpfs` and `procfs` are mounted and basic `dev` nodes are created to establish a basic root file system.
163. The init process starts the ueventd process to listen for device hot-swap events in the kernel and creates `dev` nodes for related devices as well as partitions for the block device.
174. After mounting partitions (`system` and `vendor`) of the block device, the init process scans for the init startup script of each system service and starts the respective system ability (SA).
185. Each SA registers with the samgr process, which serves as the service registration center. The samgr process assigns each SA with an ID, which will be used by an application to access the desired SA.
196. The foundation process implements application lifecycle management. It is a special SA service process that provides the user program management framework and basic services.
207. For an application, loading of the JS running environment involves a great deal of preparations. To reduce the application startup time, the appspawn process directly spawns an application process once receiving an application startup request from the foundation process.
21
22
23The Startup subsystem consists of the following modules:
24
25- init Module
26
27  This module corresponds to the init process, which is the first user-space process started after the kernel is initialized. After the init process starts, it reads and parses the `init.cfg` file. Based on the parsing result, the init module executes the commands listed in Table 2 in [Job Management](../subsystems/subsys-boot-init-jobs.md#available-apis) and starts the key system service processes in sequence with corresponding permissions granted.
28
29- ueventd module
30
31  This module listens for **netlink** events about hot plug of kernel device drivers and dynamically manages the `dev` node of the corresponding device based on the event type.
32
33- appspawn Module
34
35  This module spawns application processes upon receiving commands from the foundation, configures permissions for new processes, and calls the entry function of the application framework.
36
37- bootstrap Module
38
39  This module provides entry identifiers for starting services and features. When samgr is started, the entry function identified by bootstrap is called and system services are started.
40
41- syspara
42
43  This module provides APIs for obtaining device information, such as the product name, brand name, and manufacturer name, based on the OpenHarmony Product Compatibility Specifications (PCS). It also provides APIs for setting and obtaining system attributes.
44
45
46## Constraints
47
48  The source code directory of the Startup subsystem varies according to the platform.
49
50  **Table 1** Directories and applicable platforms of the Startup subsystem
51
52| Name| Applicable Platform|
53| -------- | -------- |
54| base/startup/appspawn_lite | Small-system devices (reference memory ≥ 1 MiB), for example, Hi3516D V300 and Hi3518E V300|
55| base/startup/bootstrap_lite | Mini-system devices (reference memory ≥ 128 KiB), for example, Hi3861 V100|
56| base/startup/init | Small-system devices (reference memory ≥ 1 MiB), for example, Hi3516D V300 and Hi3518E V300|
57| base/startup/syspara_lite | - Mini-system devices (reference memory ≥ 128 KiB), for example, Hi3861 V100<br>- Small-system devices (reference memory ≥ 1 MiB), for example, Hi3516D V300 and Hi3518E V300|
58
59- init module
60  - To start a system service, you first need to write a boot script file named `init.cfg`, in which you define the service name, path of executable files, permissions, etc.
61  - The boot script of each system service is installed in the `/system/etc/init` directory. The init process scans this directory for the boot script to execute.
62
63- When porting a new chip platform, you need to add the `/vendor/etc/init/init.{hardware}.cfg` file that contains the platform-level initialization configuration. This file is used to implement platform-level initialization, for example, installing the ko driver and configuring information on the related `/proc` nodes.
64
65  > **NOTE**
66  >
67  > The configuration file `init.cfg` must be in JSON format.
68
69- bootstrap module: The zInit code must be configured in the link script.
70
71## Boot Process for the OpenHarmony Standard System
72
73By default, the OpenHarmony standard system supports the images listed in the following table.
74
75| Image    | Mount Point | Description                                                |
76| ------------ | ------- | ---------------------------------------------------- |
77| boot.img     | NA      | Kernel and ramdisk image, which is the first image loaded by the bootloader.     |
78| system.img   | /system | System component image, which stores chip-irrelevant platform services.        |
79| vendor.img   | /vendor | Chip component image, which stores chip-related hardware abstraction services.          |
80| updater.img  | /       | Updater image, which is used for system updating. This image is not loaded during normal startup.|
81| userdata.img | /data   | Writable user data image.                                |
82
83On each development board, you need to partition the memory to store the preceding images. When the SoC starts, the bootloader loads the images as follows:
84
85- Initializes hardware such as the ROM and RAM, and loads the partition table information.
86- Loads the `boot.img` file based on the partition table and parses and loads the `ramdisk.img` file to the memory.
87- Prepares the partition table information and ramdisk address and enters the kernel, so that the kernel loads the the ramdisk image and starts the init process.
88- Waits until the init process prepares the initial file system and mounts `required.fstab` (including `system.img` and `vendor.img`) to the file system.
89- Scans the boot scripts in the `etc/init` directory in `system.img` and `vendor.img` and runs each boot command.
90
91### U-Boot Process
92
93[U-Boot](https://elinux.org/U-Boot) is used as an example to describe the key image loading process. When U-Boot starts the system, it passes the boot information to the system by using `bootargs`.
94
95- `boot.img` loading and parsing
96
97  - `boot.img` format
98
99    `boot.img` building and loading varies depending on the platform. The implementation on mainstream OpenHarmony platforms is as follows:
100
101    - Hi3516DV300
102
103      On this platform, the `boot.img` file uses the flattened image tree (FIT) format. It is generated by the Mkimage tool by packing the `ramdisk.img` files, which are packed by using `zImage-dtb` or `cpio` during kernel building, based on the information in the `its` file.
104
105      The related files and tool are described as follows:
106
107      1. `its` file
108
109         An image source file that describes the information about the image to be generated. You need to create the file, for example, the `ohos.its` file on the Hi3516 platform.
110
111      2. Mkimage packaging tool
112
113         A tool that parses `its` files and packs the corresponding images based on the image configuration to generate an `itb` file, that is, `boot.img`.
114
115      3. `ramdisk` image
116
117         A `ramdisk.img` file packed by using `cpio`.
118
119      4. `zImage-dtb` image
120
121         An image that contains the compressed kernel image and device description file image.
122
123    - rk3568
124
125      On this platform, the `boot.img` file is named `boot_linux.img`. The packaged files are different from those on the Hi3516D V300 platform.
126
127      1. Image
128
129         Image file generated after kernel building.
130
131      2. toybrick.dtb
132
133         A file that is similar to the device description file image generated through `dts` building.
134
135      3. ramdisk.img
136
137         A `ramdisk.img` file packed by using `cpio`.
138
139  - U-Boot loading
140
141    The ramdisk boot process is supported. In this scenario, you need to modify the product configuration file in `productdefine` and enable ramdisk generation by setting `enable_ramdisk`. The ramdisk processing method varies according to the platform. Take the Hi3516D V300 platform as an example. You need to change the original U-Boot parameter to `root=/dev/ram0 initrd=0x84000000,0x292e00`.
142
143
144- Kernel start
145
146  When U-Boot starts the kernel, it can pass key information to the kernel through `bootargs`. The information varies according to the platform. The main fields are described in the table below.
147
148  | Name       | Example                                                        | Description                                                        |
149  | ----------- | ------------------------------------------------------------ | ------------------------------------------------------------ |
150  | initrd      | 0x84000000,0x292e00                                          | For details, see the kernel documentation:<br>[ramfs-rootfs-initramfs.rst](https://gitee.com/openharmony/kernel_linux_5.10/blob/master/Documentation/filesystems/ramfs-rootfs-initramfs.rst)<br>[initrd.rst](https://gitee.com/openharmony/kernel_linux_5.10/blob/master/Documentation/admin-guide/initrd.rst) |
151  | init        | /init                                                        |                                                              |
152  | blkdevparts | mmcblk0:1M(boot),15M(kernel),200M(system),200M(vendor),<br>2M(misc),20M(updater),-(userdata) | Partition table information. The kernel creates physical partitions based on the information.                |
153  | hardware    | Hi3516D V300, rk3568, etc.                                                 | (Mandatory information) Hardware platform.|
154  | root        | /dev/ram0 (Hi3516DV00), root=PARTUUID=614e0000-0000 rw (rk3568)                                                   | Boot device loaded by the kernel.|
155  | rootfstype  | ext4                                                         | Type of the root file system.|
156  | default_boot_device | soc/10100000.himci.eMMC | (Recommended information) Default boot device. In the first phase of the boot process, a soft link will be created for the `required` partition device based on this field.|
157  | ohos.required_mount.xxx | /dev/block/platform/soc/10100000.himci.eMMC/by-name/xxx@/usr@ext4@ro,barrier=1@wait,required |  The fstab information is first read from cmdline. If this fails, the system will try to read the information from the `fstab.required` file.|
158
159- Mounting of `required` partitions
160
161  A `required` partition is one that is essential for system boot. It must be mounted before level-2 boot. For mandatory images like system and vendor images, the corresponding block device files must be created before mounting. This is usually done based on the **uevent** messages reported by the kernel. The init process needs to know the main device directory of the storage device. The bootloader process passes the primary device directory of the storage device to the init process through `default_boot_device`.
162
163  Currently, the init process obtains `required` partition information in two ways. The init process first reads the `required` partition information through `bootargs` in `/proc/cmdline`. If the attempt fails, the init process reads the `fstab.required` file in the ramdisk image.
164
165    - Logic of block device creation
166
167      - Preparation
168
169        1. The init process reads the `fstab.required` file from `cmdline`. If the attempt fails, the init process reads the `fstab.required` file to obtain `PARTNAME` of the block devices that must be mounted, for example, `system` or `vendor`.
170        2. Create a socket for receiving **uevent** messages reported by the kernel and read `default_boot_device` from `/proc/cmdline`.
171        3. Traverse the `/sys/devices` directory with the fstab information and socket handle to get the kernel prepared for reporting **uevent** messages.
172
173      - Trigger event
174
175        1. Use **ueventd** to trigger the kernel to report a **uevent** message.
176        2. Check whether `partitionName` in the **uevent** message matches with device information in the `fstab.required` file.
177        3. If they match, format the device node path and proceed with device node creation.
178
179      - Creating Nodes
180
181        1. Format the path of the soft link to be created for required block device nodes. A soft link helps facilitate access to device nodes in user mode and improve their readability.
182        2. Create device nodes based on the primary and secondary device numbers passed in the **uevent** message, and the device node path and soft link path obtained in the previous steps. Meanwhile, create a soft link for them.
183
184      Up to now, the creation of block device nodes is complete.
185
186    - Mapping with `default_boot_device`
187
188      The kernel writes `bootargs` information to `/proc/cmdline`. The information includes `default_boot_device`, which specifies the primary device directory required for system boot. The content prefixed with `ohos.required_mount.` is the partition mounting information required for system boot. It should be the same as that in the `fstab.required` file. In addition, the block device node in the partition mounting information should be a device node pointed by the soft link under `by-name` in the `default_boot_device` directory. For example, if the value of `default_boot_device` is `soc/10100000.himci.eMMC`, then the value of `ohos.required_mount.system` contains `/dev/block/platform/soc/10100000.himci.eMMC/by-name/system`, which is the soft link pointing to the system device node.
189
190      During creation of a block device node, the device path will be matched against the value of `default_boot_device`. If the matching is successful, a soft link pointing to the real block device node will be created in `/dev/block/by-name`. In this way, device node access is made irrelevant to the chip platform.
191
192    - Example
193
194      This example assumes the `system` partition as the `required` partition on the Hi3516D V300 platform to illustrate the boot process. During this process, the init process reads the `fstab.required` file, creates a block device node, and mounts it to the `required` partition. The following provides the key code snippets and log information as reference for debugging.
195
196      > **NOTE**
197      >
198      > The code snippets below are exhibited in the logical sequence. They are not neighboring to each other in the source code.
199
200      1. Obtain `required` partition device information.
201          ```
202          Fstab* LoadRequiredFstab(void)
203          {
204              Fstab *fstab = NULL;
205              fstab = LoadFstabFromCommandLine();
206              if (fstab == NULL) {
207                  INIT_LOGI("Cannot load fstab from command line, try read from fstab.required");
208                  const char *fstabFile = "/etc/fstab.required";
209                  if (access(fstabFile, F_OK) != 0) {
210                      fstabFile = "/system/etc/fstab.required";
211                  }
212                  INIT_ERROR_CHECK(access(fstabFile, F_OK) == 0, abort(), "Failed get fstab.required");
213                  fstab = ReadFstabFromFile(fstabFile, false);
214              }
215              return fstab;
216          }
217          ```
218          The preceding code provides two methods for the init process to obtain the fstab information. First, the init process calls `LoadFstabFromCommandLine()` to read the fstab information from `cmdline`. If the attempt fails, the init process outputs log information and continues to read the `fstab.required` file for the fstab information.
219
220          For the `system` partition, the key information read from `devices` is as follows:
221          ```
222          /dev/block/platform/fe310000.sdhci/by-name/system
223          ```
224
225      2. Create a socket and trigger the kernel to report a **uevent** message.
226         ```
227         static int StartUeventd(char **requiredDevices, int num)
228         {
229             INIT_ERROR_CHECK(requiredDevices != NULL && num > 0, return -1, "Failed parameters");
230             int ueventSockFd = UeventdSocketInit();
231             if (ueventSockFd < 0) {
232                 INIT_LOGE("Failed to create uevent socket");
233                 return -1;
234             }
235             RetriggerUevent(ueventSockFd, requiredDevices, num);
236             close(ueventSockFd);
237             return 0;
238         }
239         ```
240
241      3. Read information from `cmdline` to obtain `default_boot_device`.
242         ```
243         char *buffer = ReadFileData("/proc/cmdline");
244         int ret = GetProcCmdlineValue("default_boot_device", buffer, bootDevice, CMDLINE_VALUE_LEN_MAX);
245         INIT_CHECK_ONLY_ELOG(ret == 0, "Failed get default_boot_device value from cmdline");
246         ```
247         In this example, the value of `default_boot_device` is `soc/10100000.himci.eMMC`. The value is stored in the global variable `bootDevice` and will be matched with the path of the `system` partition device when a soft link is created.
248
249      4. Process the **uevent** message of the `required` partition device.
250         ```
251         if (uevent->partitionName == NULL) {
252             INIT_LOGI("Match with %s for %s", devices[i], uevent->syspath);
253             deviceName = strstr(devices[i], "/dev/block");
254             INIT_INFO_CHECK(deviceName != NULL, continue,
255                 "device %s not match \"/dev/block\".", devices[i]);
256             deviceName += sizeof("/dev/block") - 1;
257             INIT_INFO_CHECK(strstr(uevent->syspath, deviceName) != NULL, continue,
258                 "uevent->syspath %s not match deviceName %s", uevent->syspath, deviceName);
259             HandleBlockDeviceEvent(uevent);
260             break;
261         } else if (strstr(devices[i], uevent->partitionName) != NULL) {
262             INIT_LOGI("Handle block device partitionName %s", uevent->partitionName);
263             HandleBlockDeviceEvent(uevent);
264             break;
265         }
266         ```
267         In this step, the device information in `devices` is matched with the **uevent** message reported by the kernel. The value of `uevent -> partitionName` should be `system` for the **uevent** message of the `system` partition device. If the value matches the `/dev/block/platform/fe310000.sdhci/by-name/system` field in `devices`, the **uevent** message of the `system` partition device will be processed.
268
269      5. Create the `required` partition device node and the corresponding soft link.
270
271         The first thing is to format the path of the corresponding soft link. In this step, the value of `default_boot_device` in `bootargs` will be matched with the path of the required device node in the **uevent** message, so as to create a platform-irrelevant soft link that points to the device node. The key code is as follows:
272         ```
273         if (STRINGEQUAL(bus, "/sys/bus/platform")) {
274             INIT_LOGV("Find a platform device: %s", parent);
275             parent = FindPlatformDeviceName(parent);
276             if (parent != NULL) {
277                 BuildDeviceSymbolLinks(links, linkNum, parent, uevent->partitionName, uevent->deviceName);
278             }
279             linkNum++;
280             if ((parent != NULL) && STRINGEQUAL(parent, bootDevice)) {
281                 BuildBootDeviceSymbolLink(links, linkNum, uevent->partitionName);
282                 linkNum++;
283             }
284         }
285         ```
286         The key variables in the code are as follows:
287
288         - `bus`: a string that saves the path of the bus connected to the current device.
289         - `parent`: a string that stores the device path obtained from `uevent -> syspath` in the **uevent** message.
290         - `links`: a pointer to the memory that stores the soft link path.
291         - `bootDevice`: a string that stores the value of `default_boot_device` in `bootargs`.
292         According to the code, the corresponding soft link is created for the device only when the type of the connected bus is `platform`. The path of the soft link is as follows:
293         ```
294         /dev/block/platform/soc/10100000.himci.eMMC/by-name
295         ```
296         A platform-irrelevant soft link is created only when the device path matches that in `bootDevice`.
297
298         For the **system** partition device, the path is as follows:
299         ```
300         /sys/devices/platform/soc/10100000.himci.eMMC/mmc_host/mmc0/mmc0:0001/block/mmcblk0/mmcblk0p5
301         ```
302         Therefore, when processing the **uevent** message of the device, the init process compares the device path with that in `bootDevice`, that is, `soc/10100000.himci.eMMC`. If they match, a soft link will be created as follows:
303         ```
304         /dev/block/by-name/system
305         ```
306
307         After the soft link path is formatted, the init process creates the device node and soft link based on the information in the **uevent** message. Up to now, the creation of a device node for the `system` partition is complete.
308
309      6. Mount the `required` partition.
310
311         After a device node is created, mount it to the corresponding partition. The code is as follows:
312         ```
313          int MountRequiredPartitions(const Fstab *fstab)
314          {
315              INIT_ERROR_CHECK(fstab != NULL, return -1, "Failed fstab is NULL");
316              int rc;
317              INIT_LOGI("Mount required partitions");
318              rc = MountAllWithFstab(fstab, 1);
319              return rc;
320          }
321         ```
322         Therefore, when "Mount required partitions" is displayed, the `required` partition device is ready for mounting. During the mounting process, the following key information is printed:
323         ```
324         BEGET_LOGE("Unsupported file system \" %s \"", item->fsType);
325         ```
326         The current file system type is not supported.
327         ```
328         BEGET_LOGE("Cannot get stat of \" %s \", err = %d", target, errno);
329         ```
330         The attempt to obtain the mount point directory has failed.
331         ```
332         BEGET_LOGE("Failed to create dir \" %s \", err = %d", target, errno);
333         ```
334         The attempt to create the mount point directory has failed.
335         ```
336         BEGET_LOGI("Mount %s to %s successful", item->deviceName, item->mountPoint);
337         ```
338         The device is successfully mounted. The output also contains the name of the mounted device and information about the mount point.
339
340- Mounting of the `vendor` partition
341
342After mounting required partitions, the init process scans each script file in the `vendor` partition. The initialization scripts related to the chip or development board is named in the format of `/vendor/etc/init.{ohos.boot.hardware}.cfg`. Wherein, `/vendor/etc/fstab.{ohos.boot.hardware}` represents the extended mount partition file; `hardware` is sourced from `bootargs`, which is passed from the bootloader to the kernel.
343
344
345### Boot Loading Without ramdisk
346
347Certain development boards do not use the ramdisk boot mode. For these boards, the boot process is implemented by directly loading the `system.img` file through the kernel. In such case, you need to modify the product configuration file in `productdefine`. Specifically, you need to turn off the `enable_ramdisk` switch to disable ramdisk generation so that the init process does not boot from ramdisk to system.
348
349The boot loading process in this scenario is similar to that in the preceding section. The only difference is as follows: If ramdisk is used, the init process mounts `system.img` to the `/usr` directory and then switches to the `/usr` directory using `chroot`. If ramdisk is not used, the init process directly runs the `init.cfg` file.
350
351For the boot loading process without ramdisk, that is, system as root, the block device where the root file system is located is passed to the kernel through `bootargs`, for example, `root=/dev/mmcblk0p5, rootfstype=ext4`. During initialization of the root file system, the kernel parses the `root` field in `bootargs` to complete mounting of the root file system.
352
353
354### Partition A/B Booting
355
356Currently, OpenHarmony supports booting from partitions A and B (active and standby system partitions), both of which are configured in the same device storage. During the booting process, the system partition to load is determined based on the slot of the active partition. Partition A/B booting is supported only for the `system` and `chipset` partitions.
357
358- bootslots
359
360  Number of the supported boot partitions. If `bootslots` is set to `2`, the system can boot from both system partitions A and B. If `bootslots` is set to `1`, partition A/B booting is not supported and the system can boot only from the default system partition.
361
362  In the initial phase of init process startup, the system reads the `bootslots` value to determine whether partition A/B booting is supported. If yes, the system continues to determine the system partition to mount. If not, the system mounts the system partition based on the default fstab. The API for the init process to obtain the `bootslots` value is as follows:
363  ```
364  int GetBootSlots(void)
365  {
366      int bootSlots = GetSlotInfoFromParameter("bootslots");
367      BEGET_CHECK_RETURN_VALUE(bootSlots <= 0, bootSlots);
368      BEGET_LOGI("No valid slot value found from parameter, try to get it from cmdline");
369      return GetSlotInfoFromCmdLine("bootslots");
370  }
371  ```
372  After normal system startup, you can obtain the `bootslots` value from the system parameter `ohos.boot.bootslots` to check whether the current system supports partition A/B booting. The command for obtaining `ohos.boot.bootslots` is as follows:
373  ```
374  param get ohos.boot.bootslots
375  ```
376
377- currentslot
378
379  Current system partition, for example, partition A or partition B. The value of `currentslot` is a number. For example, `1` indicates partition A, and `2` indicates partition B.
380
381  In the initial phase of startup, the init process determines whether the system supports partition A/B booting based on `bootslots`. If the system does not support partition A/B booting, the init process directly boots from the default system partition instead of obtaining the `currentslot` value. If the system supports partition A/B booting, the init process obtains the `currentslot` value and determines whether partition A or partition B is the current system partition. The API for the init process to obtain the `currentslot` value is as follows:
382  ```
383  int GetCurrentSlot(void)
384  {
385      // get current slot from parameter
386      int currentSlot = GetSlotInfoFromParameter("currentslot");
387      BEGET_CHECK_RETURN_VALUE(currentSlot <= 0, currentSlot);
388      BEGET_LOGI("No valid slot value found from parameter, try to get it from cmdline");
389
390      // get current slot from cmdline
391      currentSlot = GetSlotInfoFromCmdLine("currentslot");
392      BEGET_CHECK_RETURN_VALUE(currentSlot <= 0, currentSlot);
393      BEGET_LOGI("No valid slot value found from cmdline, try to get it from misc");
394
395      // get current slot from misc
396      return GetSlotInfoFromMisc(MISC_PARTITION_ACTIVE_SLOT_OFFSET, MISC_PARTITION_ACTIVE_SLOT_SIZE);
397  }
398  ```
399
400- Partition A/B Booting Process
401
402  1. Obtain the `currentslot` value to determine whether partition A or partition B is the current system partition.
403  2. Construct new partition mounting configuration based on the original `fstab` file, and add the suffix `_a` or `_b` to the partitions that support partition A/B booting, that is, system and chipset partitions.
404  3. Mount the partition added with the corresponding suffix and enter the second phase of startup. This phase occurs in partition A or B and concludes the partition A/B booting process.
405
406  The API for constructing new partition mounting configuration is as follows:
407  ```
408  static void AdjustPartitionNameByPartitionSlot(FstabItem *item)
409  {
410      BEGET_CHECK_ONLY_RETURN(strstr(item->deviceName, "/system") != NULL ||
411          strstr(item->deviceName, "/chipset") != NULL);
412      char buffer[MAX_BUFFER_LEN] = {0};
413      int slot = GetCurrentSlot();
414      BEGET_ERROR_CHECK(slot > 0 && slot <= MAX_SLOT, slot = 1, "slot value %d is invalid, set default value", slot);
415      BEGET_INFO_CHECK(slot > 1, return, "default partition doesn't need to add suffix");
416      BEGET_ERROR_CHECK(sprintf_s(buffer, sizeof(buffer), "%s_%c", item->deviceName, 'a' + slot - 1) > 0,
417          return, "Failed to format partition name suffix, use default partition name");
418      free(item->deviceName);
419      item->deviceName = strdup(buffer);
420      BEGET_LOGI("partition name with slot suffix: %s", item->deviceName);
421  }
422  ```
423
424- Development Example
425
426  The following uses the rk3568 platform as an example to illustrate how to change from default partition booting to partition A/B booting.
427
428  1. Burn the original image, and view the device information of each partition.
429
430      ![Original partition](figures/ABStartup_1.png)
431
432      Use the original image to construct images of the partitions used for partition A/B booting, and test the partition A/B booting function.
433      - Copy the `system` and `vendor` images, and add the suffix `_b` to them.
434      - Add partitions `system_b` and `vendor_b` to the partition table in the `parameter.txt` file.
435
436  2. Burn the images of the partitions used for partition A/B booting.
437
438     - Import the partition configuration to the rk3568 burning tool, and select the `parameter.txt` file containing the `system_b` and `vendor_b` partitions.
439     - Select images (including `system_b` and `vendor_b` images) based on the new partition table configuration, and then burn the images.
440
441  3. After the configuration is complete, perform the following:
442
443      1. Run the `cat /proc/cmdline` command. If the command output contains `bootslot=2`, the system supports partition A/B booting.
444
445          ![cmdline](figures/ABStartup_2.png)
446      2. Run the `param get ohos.boot.bootslot` command. If the command output contains `2`, the `bootslot` information is successfully written to the `parameter.txt` file.
447
448      3. Run the `ls -l /dev/block/by-name` command. If the command output contains `system_b` and `vendor_b`, device nodes are successfully created in partition B.
449
450          ![Device information](figures/ABStartup_3.png)
451
452      4. Run the `df -h` command to check the partitions mounted to the system.
453
454          ![Partition information](figures/ABStartup_4.png)
455
456          As shown in the figure, partition `mmcblk0p6` is mounted to the root file system (represented by a slash), and partition `mmcblk0p7` is mounted to `/vendor`. Based on the command output in step 3, `mmcblk0p6` is the `system` partition, and `mmcblk0p7` is the `vendor` partition. That is, the mounted partitions are the default partitions, that is, `system` and `vendor` partitions without suffixes. In other words, partition A is the default partition.
457
458          Next, let's try booting from partition B.
459
460          1. Run the `partitionslot setactive 2` command to set the slot of the active partition to `2`, that is, the slot of partition B.
461
462             ![Partition slot configuration](figures/ABStartup_5.png)
463
464          2. Run the `partitionslot getslot` command to check the configured slot.
465
466             ![View Slot](figures/ABStartup_6.png)
467
468             If `current slot: 2` is `2`, the slot of the active partition is successfully set to `2`.
469
470          3. Upon restarting, run the `df -h` command to check the partitions mounted to the system.
471
472             According to the command output, partition `mmcblk0p11` is mounted to the root file system, and partition `mmcblk0p12` is mounted to `/vendor`.
473
474             ![Mounting information](figures/ABStartup_7.png)
475
476          4. Run the `ls -l /dev/block/by-name` command again.
477
478             ![New device information](figures/ABStartup_8.png)
479
480          `mmcblk0p11` corresponds to `system_b`, and `mmcblk0p12` corresponds to `vendor_b`. That is, the system is successfully booted from partition B.
481