1e41f4b71Sopenharmony_ci# Dynamic Loading 2e41f4b71Sopenharmony_ci 3e41f4b71Sopenharmony_ci 4e41f4b71Sopenharmony_ci## Basic Concepts 5e41f4b71Sopenharmony_ci 6e41f4b71Sopenharmony_ciIn small devices with limited hardware resources, dynamic algorithm deployment capability is required to allow multiple algorithms to be deployed at the same time. The LiteOS-M kernel uses the Executable and Linkable Format (ELF) loading because it is easy to use and compatible with a wide variety of platforms. 7e41f4b71Sopenharmony_ci 8e41f4b71Sopenharmony_ciThe LiteOS-M provides APIs similar to **dlopen** and **dlsym**. Apps can load and unload required algorithm libraries by using the APIs provided by the dynamic loading module. As shown in the following figure, the app obtains the corresponding information output through the API required by the third-party algorithm library. The third-party algorithm library depends on the basic APIs provided by the kernel, such as **malloc**. After the app loads the API and relocates undefined symbols, it can call the API to complete the function. 9e41f4b71Sopenharmony_ci 10e41f4b71Sopenharmony_ciThe dynamic loading component supports only the Arm architecture. In addition, the signature and source of the shared library to be loaded must be verified to ensure system security. 11e41f4b71Sopenharmony_ci 12e41f4b71Sopenharmony_ci **Figure 1** LiteOS-M kernel dynamic loading architecture 13e41f4b71Sopenharmony_ci 14e41f4b71Sopenharmony_ci  15e41f4b71Sopenharmony_ci 16e41f4b71Sopenharmony_ci 17e41f4b71Sopenharmony_ci## Working Principles 18e41f4b71Sopenharmony_ci 19e41f4b71Sopenharmony_ci 20e41f4b71Sopenharmony_ci### Exporting the Symbol Table 21e41f4b71Sopenharmony_ci 22e41f4b71Sopenharmony_ciThe kernel needs to proactively expose the API required by the dynamic library when the shared library calls a kernel API, as shown in the following figure. This mechanism compiles the symbol information to the specified section and calls the **SYM_EXPORT** macro to export information of the specified symbol. The symbol information is described in the structure **SymInfo**, which includes the symbol name and address information. The macro **SYM_EXPORT** imports the symbol information to the **.sym.*** section by using **__attribute__**. 23e41f4b71Sopenharmony_ci 24e41f4b71Sopenharmony_ci 25e41f4b71Sopenharmony_ci``` 26e41f4b71Sopenharmony_citypedef struct { 27e41f4b71Sopenharmony_ci CHAR *name; 28e41f4b71Sopenharmony_ci UINTPTR addr; 29e41f4b71Sopenharmony_ci} SymInfo; 30e41f4b71Sopenharmony_ci 31e41f4b71Sopenharmony_ci#define SYM_EXPORT(func) \ 32e41f4b71Sopenharmony_ciconst SymInfo sym_##func __attribute__((section(".sym."#func))) = { \ 33e41f4b71Sopenharmony_ci .name = #func, \ 34e41f4b71Sopenharmony_ci .addr = (UINTPTR)func \ 35e41f4b71Sopenharmony_ci}; 36e41f4b71Sopenharmony_ci``` 37e41f4b71Sopenharmony_ci 38e41f4b71Sopenharmony_ci **Figure 2** Exported symbol table 39e41f4b71Sopenharmony_ci 40e41f4b71Sopenharmony_ci  41e41f4b71Sopenharmony_ci 42e41f4b71Sopenharmony_ci 43e41f4b71Sopenharmony_ci### Loading an ELF File 44e41f4b71Sopenharmony_ci 45e41f4b71Sopenharmony_ciThe **LOAD** section to be loaded to the memory can be obtained based on the ELF file handle and the section offset of the program header table. Generally, there are two sections: read-only and read-write. You can run the **readelf -l** command to view the LOAD section information of the ELF file. The physical memory is requested according to the related alignment attributes. Then, a code section or a data segment is written into the memory based on the loading base address and an offset of each section. 46e41f4b71Sopenharmony_ci 47e41f4b71Sopenharmony_ci 48e41f4b71Sopenharmony_ci``` 49e41f4b71Sopenharmony_ci$ readelf -l lib.so 50e41f4b71Sopenharmony_ci 51e41f4b71Sopenharmony_ciElf file type is DYN (Shared object file) 52e41f4b71Sopenharmony_ciEntry point 0x5b4 53e41f4b71Sopenharmony_ciThere are 4 program headers, starting at offset 52 54e41f4b71Sopenharmony_ci 55e41f4b71Sopenharmony_ciProgram Headers: 56e41f4b71Sopenharmony_ci Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align 57e41f4b71Sopenharmony_ci EXIDX 0x000760 0x00000760 0x00000760 0x00008 0x00008 R 0x4 58e41f4b71Sopenharmony_ci LOAD 0x000000 0x00000000 0x00000000 0x0076c 0x0076c R E 0x10000LOAD 0x00076c 0x0001076c 0x0001076c 0x0010c 0x00128 RW 0x10000 59e41f4b71Sopenharmony_ci DYNAMIC 0x000774 0x00010774 0x00010774 0x000c8 0x000c8 RW 0x4 60e41f4b71Sopenharmony_ci 61e41f4b71Sopenharmony_ci Section to Segment mapping: 62e41f4b71Sopenharmony_ci Segment Sections... 63e41f4b71Sopenharmony_ci 00 .ARM.exidx 64e41f4b71Sopenharmony_ci 01 .hash .dynsym .dynstr .rel.dyn .rel.plt .init .plt .text .fini .ARM.exidx .eh_frame 65e41f4b71Sopenharmony_ci 02 .init_array .fini_array .dynamic .got .data .bss 66e41f4b71Sopenharmony_ci 03 .dynamic 67e41f4b71Sopenharmony_ci``` 68e41f4b71Sopenharmony_ci 69e41f4b71Sopenharmony_ci **Figure 3** Process of loading an ELF file<br> 70e41f4b71Sopenharmony_ci  71e41f4b71Sopenharmony_ci 72e41f4b71Sopenharmony_ci 73e41f4b71Sopenharmony_ci### ELF File Linking 74e41f4b71Sopenharmony_ci 75e41f4b71Sopenharmony_ciA relocation table is obtained by using a **.dynamic** section of the ELF file. Each entry that needs to be relocated in the table is traversed. Then, the symbol is searched, based on the symbol name that needs to be relocated, in the shared library and the exported symbol table provided by the kernel. The relocation information is updated based on the symbol found. 76e41f4b71Sopenharmony_ci 77e41f4b71Sopenharmony_ci **Figure 4** ELF file linking process 78e41f4b71Sopenharmony_ci 79e41f4b71Sopenharmony_ci  80e41f4b71Sopenharmony_ci 81e41f4b71Sopenharmony_ci 82e41f4b71Sopenharmony_ci## ELF Specifications 83e41f4b71Sopenharmony_ci 84e41f4b71Sopenharmony_ci 85e41f4b71Sopenharmony_ci### ELF Type 86e41f4b71Sopenharmony_ci 87e41f4b71Sopenharmony_ciWhen compiling a shared library, you can add **-fPIC** (a compilation option) to compile location-independent code. The shared library file type is **ET_DYN**, which can be loaded to any valid address range. 88e41f4b71Sopenharmony_ci 89e41f4b71Sopenharmony_ciExample: **arm-none-eabi-gcc -fPIC –shared –o lib.so lib.c** 90e41f4b71Sopenharmony_ci 91e41f4b71Sopenharmony_ci 92e41f4b71Sopenharmony_ci### Options for Linking 93e41f4b71Sopenharmony_ci 94e41f4b71Sopenharmony_ci- **-nostdlib**: Do not use the lib library in the compiler when linking. 95e41f4b71Sopenharmony_ci 96e41f4b71Sopenharmony_ci- **-nostartfiles**: Do not use the startup files in the compiler when linking. 97e41f4b71Sopenharmony_ci 98e41f4b71Sopenharmony_ci- **-fPIC**: compiles location-independent shared libraries. 99e41f4b71Sopenharmony_ci 100e41f4b71Sopenharmony_ci- **-z max-page-size=4**: sets the number of alignment bytes of the loadable sections in the binary file to **4**. This setting saves memory and can be used for a dynamic library. 101e41f4b71Sopenharmony_ci 102e41f4b71Sopenharmony_ci- **-mcpu=** specifies the CPU architecture. 103e41f4b71Sopenharmony_ci 104e41f4b71Sopenharmony_ci 105e41f4b71Sopenharmony_ci## Constraints 106e41f4b71Sopenharmony_ci 107e41f4b71Sopenharmony_ci 108e41f4b71Sopenharmony_ci- Applications cannot be loaded. Only shared libraries can be loaded. 109e41f4b71Sopenharmony_ci- The shared library to be loaded cannot depend on the libc library or other shared libraries in the compiler. It can depend only on the external APIs provided by the kernel (provided by the exported symbol table). 110e41f4b71Sopenharmony_ci- This feature depends on the cross compiler and file system. 111