1# Dynamic Loading 2 3 4## Basic Concepts 5 6In 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. 7 8The 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. 9 10The 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. 11 12 **Figure 1** LiteOS-M kernel dynamic loading architecture 13 14 ![](figures/liteos-m-kernel-dynamic-loading-architecture.png "liteos-m-kernel-dynamic-loading-architecture") 15 16 17## Working Principles 18 19 20### Exporting the Symbol Table 21 22The 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__**. 23 24 25``` 26typedef struct { 27 CHAR *name; 28 UINTPTR addr; 29} SymInfo; 30 31#define SYM_EXPORT(func) \ 32const SymInfo sym_##func __attribute__((section(".sym."#func))) = { \ 33 .name = #func, \ 34 .addr = (UINTPTR)func \ 35}; 36``` 37 38 **Figure 2** Exported symbol table 39 40 ![](figures/exported-symbol-table-information.png "exported-symbol-table-information") 41 42 43### Loading an ELF File 44 45The **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. 46 47 48``` 49$ readelf -l lib.so 50 51Elf file type is DYN (Shared object file) 52Entry point 0x5b4 53There are 4 program headers, starting at offset 52 54 55Program Headers: 56 Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align 57 EXIDX 0x000760 0x00000760 0x00000760 0x00008 0x00008 R 0x4 58 LOAD 0x000000 0x00000000 0x00000000 0x0076c 0x0076c R E 0x10000LOAD 0x00076c 0x0001076c 0x0001076c 0x0010c 0x00128 RW 0x10000 59 DYNAMIC 0x000774 0x00010774 0x00010774 0x000c8 0x000c8 RW 0x4 60 61 Section to Segment mapping: 62 Segment Sections... 63 00 .ARM.exidx 64 01 .hash .dynsym .dynstr .rel.dyn .rel.plt .init .plt .text .fini .ARM.exidx .eh_frame 65 02 .init_array .fini_array .dynamic .got .data .bss 66 03 .dynamic 67``` 68 69 **Figure 3** Process of loading an ELF file<br> 70 ![](figures/process-of-loading-an-elf-file.png "process-of-loading-an-elf-file") 71 72 73### ELF File Linking 74 75A 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. 76 77 **Figure 4** ELF file linking process 78 79 ![](figures/elf-file-linking-process.png "elf-file-linking-process") 80 81 82## ELF Specifications 83 84 85### ELF Type 86 87When 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. 88 89Example: **arm-none-eabi-gcc -fPIC –shared –o lib.so lib.c** 90 91 92### Options for Linking 93 94- **-nostdlib**: Do not use the lib library in the compiler when linking. 95 96- **-nostartfiles**: Do not use the startup files in the compiler when linking. 97 98- **-fPIC**: compiles location-independent shared libraries. 99 100- **-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. 101 102- **-mcpu=** specifies the CPU architecture. 103 104 105## Constraints 106 107 108- Applications cannot be loaded. Only shared libraries can be loaded. 109- 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). 110- This feature depends on the cross compiler and file system. 111