子张问善人之道。子曰:“不践迹,亦不入于室。” 《论语》:先进篇
百篇博客系列篇.本篇为:
v55.xx 鸿蒙内核源码剖析(重定位篇) | 与世界接轨的对外部发言人
加载运转相关篇为:
- v51.xx 鸿蒙内核源码剖析(ELF格式) | 应用程序进口并不是main
- v53.xx 鸿蒙内核源码剖析(ELF解析) | 你要忘了她姐俩你就不是银
- v54.xx 鸿蒙内核源码剖析(静态链接) | 完好小项目看透静态链接进程
- v55.xx 鸿蒙内核源码剖析(重定位) | 与世界接轨的对外部发言人
- v56.xx 鸿蒙内核源码剖析(进程映像) | ELF是如何被加载运转的?
一个程序从源码到被执行,当中阅历了3个进程:
- 编译:将.c文件编译成.o文件,不关心.o文件之间的联络.
- 静态链接:将一切.o文件合并成一个.so或.out文件,处理一切.o文件节区在方针文件中的布局.
- 动态链接:将.so或a.out文件加载到内存,处理加载文件在的内存中的布局.
什么是重定位
重定位便是把程序的逻辑地址空间变换成内存中的实践物理地址空间的进程。它是完成多道程序在内存中一起运转的根底。重定位有两种,分别是动态重定位与静态重定位。
- 1.静态重定位:即在程序装入内存的进程中完结,是指在程序开端运转前,程序中的各个地址有关的项均已完结重定位,地址变换通常是在装入时一次完结的,以后不再改动,故称为静态重定位。也便是在生成可执行/同享方针文件的一起已完结地址的静态定位,它处理了可执行文件/同享方针文件的内部矛盾.
- 2.动态重定位:它不是在程序装入内存时完结的,而是CPU每次访问内存时 由动态地址变换机构(硬件)自动进行把相对地址转换为绝对地址。动态重定位需求软件和硬件相互配合完结。也便是说可执行文件/同享方针文件的外部矛盾需求外部环境处理,它向外供给了一份入住地球村的交际阐明.即本篇最终部分内容.
重定位十种类型
- 重定位有10种类型,在实践中请对号入座,这些类型部分在本篇能见到,如下:
类型 | 公式 | 具体描绘 |
---|---|---|
R_X86_64_32 | 公式:S+A S:重定项中VALUE成员所指符号的内存地址 A:被重定位处原值,表明”引证符号的内存地址”与S的偏移 |
大局变量,在不加-fPIC编译生成的.o文件中,每个引证处对应一个R_X86_64_32重定位项,非static大局变量,在不加-fPIC编译生成的.so文件中,每个引证处对应一个R_X86_64_32重定位项. |
R_X86_64_PC32 | 公式:S+A-P S:重定项中VALUE成员所指符号的内存地址 A:被重定位处原值,表明”被重定位处”与”下一条指令”的偏移 P:被重定位处的内存地址 |
非static函数,在不加-fPIC编译生成的.o和.so文件中,每个调用途对应一个R_X86_64_PC32重定位项 |
R_X86_64_PLT32 | 公式:L+A-P L:<重定项中VALUE成员所指符号@plt>的内存地址 A:被重定位处原值,表明”被重定位处”相关于”下一条指令”的偏移 P:被重定位处的内存地址 |
非static函数,在加-fPIC编译生成的.o文件中,每个调用途对应一个R_386_PLT32重定位项. |
R_X86_64_RELATIVE | 公式:B+A B:.so文件加载到内存中的基地址 A:被重定位处原值,表明引证符号在.so文件中的偏移 |
static大局变量,在不加-fPIC编译生成的.so文件中,每个引证处对应一个R_X86_64_RELATIVE重定位项. |
R_X86_64_GOT32 | 公式:G G:引证符号的地址指针,相关于GOT的偏移 |
非static大局变量,在加-fPIC编译生成的.o文件中,每个引证处对应一个R_X86_64_GOT32重定位项 |
R_X86_64_GOTOFF | 公式:S-GOT S:重定项中VALUE成员所指符号的内存地址 GOT:运转时,.got段的完毕地址 |
static大局变量,在加-fPIC编译生成的.o文件中,每个引证处对应一个R_X86_64_GOTOFF重定位项. |
R_X86_64_GOLB_DAT | 公式:S S:重定项中VALUE成员所指符号的内存地址 |
非static大局变量,在加-fPIC编译生成的.so文件中,每个引证处对应一个R_X86_64_GOLB_DAT重定位项. |
R_X86_64_COPY | 公式:无 | .out中使用extern引证.so中的变量,每个引证处对应一个R_X86_64_COPY重定位项. |
R_X86_64_JUMP_SLOT | 公式:S(与R_386_GLOB_DAT的公式一样,但关于动态ld,R_386_JMP_SLOT类型与R_386_RELATIVE等价) S:重定项中VALUE成员所指符号的内存地址 |
非static函数,在加-fPIC编译生成的.so文件中,每个调用途对应一个R_X86_64_JMP_SLOT重定位项. |
R_X86_64_GOTPC | 公式:GOT+A-P GOT:运转时,.got段的完毕地址 A:被重定位处原值,表明”被重定位处”在机器码中的偏移 P:被重定位处的内存地址 |
大局变量,在加-fPIC编译生成的.o文件中,会额定生成R_X86_64_PC32和R_X86_64_GOTPC重定位项,非static函数,在加-fPIC编译生成的.o文件中,也会额定 生成R_X86_64_PC32和R_X86_64_GOTPC重定位项. |
解读
- fPIC的全称是 Position Independent Code, 用于生成方位无关代码。
objdump指令
objdump指令是Linux下的反汇编方针文件或者可执行文件的指令,它以一种可阅读的格式让你更多地了解二进制文件可能带有的附加信息.本篇将用它阐明静态重定位的完成细节和动态重定位前置条件预备.先整体走读下objdump
指令
root@5e3abe332c5a:/home/docker/test4harmony/54# objdump
Usage: objdump <option(s)> <file(s)>
Display information from object <file(s)>.
At least one of the following switches must be given:
-a, --archive-headers Display archive header information
-f, --file-headers Display the contents of the overall file header
-p, --private-headers Display object format specific file header contents
-P, --private=OPT,OPT... Display object format specific contents
-h, --[section-]headers Display the contents of the section headers
-x, --all-headers Display the contents of all headers
-d, --disassemble Display assembler contents of executable sections
-D, --disassemble-all Display assembler contents of all sections
--disassemble=<sym> Display assembler contents from <sym>
-S, --source Intermix source code with disassembly
--source-comment[=<txt>] Prefix lines of source code with <txt>
-s, --full-contents Display the full contents of all sections requested
-g, --debugging Display debug information in object file
-e, --debugging-tags Display debug information using ctags style
-G, --stabs Display (in raw form) any STABS info in the file
-W[lLiaprmfFsoRtUuTgAckK] or
--dwarf[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,
=frames-interp,=str,=loc,=Ranges,=pubtypes,
=gdb_index,=trace_info,=trace_abbrev,=trace_aranges,
=addr,=cu_index,=links,=follow-links]
Display DWARF info in the file
--ctf=SECTION Display CTF info from SECTION
-t, --syms Display the contents of the symbol table(s)
-T, --dynamic-syms Display the contents of the dynamic symbol table
-r, --reloc Display the relocation entries in the file
-R, --dynamic-reloc Display the dynamic relocation entries in the file
@<file> Read options from <file>
-v, --version Display this program's version number
-i, --info List object formats and architectures supported
-H, --help Display this information
objdump -S ./obj/main.o
main.o是个可重定位文件,通过 readelf 可知
root@5e3abe332c5a:/home/docker/test4harmony/54# readelf -h ./obj/main.o
ELF Header:
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
Class: ELF64
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: REL (Relocatable file)
Machine: Advanced Micro Devices X86-64
Version: 0x1
Entry point address: 0x0
root@5e3abe332c5a:/home/docker/test4harmony/54# objdump -S ./obj/main.o
./obj/main.o: file format elf64-x86-64
Disassembly of section .text:
0000000000000000 <main>:
#include <stdio.h>
#include "part.h"
extern int g_int;
extern char *g_str;
int main() {
0: f3 0f 1e fa endbr64
4: 55 push %rbp
5: 48 89 e5 mov %rsp,%rbp
8: 48 83 ec 10 sub $0x10,%rsp
int loc_int = 53;
c: c7 45 f4 35 00 00 00 movl $0x35,-0xc(%rbp)
char *loc_str = "harmony os";
13: 48 8d 05 00 00 00 00 lea 0x0(%rip),%rax # 1a <main+0x1a>
1a: 48 89 45 f8 mov %rax,-0x8(%rbp)
printf("main 开端 - 大局 g_int = %d, 大局 g_str = %s.\n", g_int, g_str);
1e: 48 8b 15 00 00 00 00 mov 0x0(%rip),%rdx # 25 <main+0x25>
25: 8b 05 00 00 00 00 mov 0x0(%rip),%eax # 2b <main+0x2b>
2b: 89 c6 mov %eax,%esi
2d: 48 8d 3d 00 00 00 00 lea 0x0(%rip),%rdi # 34 <main+0x34>
34: b8 00 00 00 00 mov $0x0,%eax
39: e8 00 00 00 00 callq 3e <main+0x3e>
func_int(loc_int);
3e: 8b 45 f4 mov -0xc(%rbp),%eax
41: 89 c7 mov %eax,%edi
43: e8 00 00 00 00 callq 48 <main+0x48>
func_str(loc_str);
48: 48 8b 45 f8 mov -0x8(%rbp),%rax
4c: 48 89 c7 mov %rax,%rdi
4f: e8 00 00 00 00 callq 54 <main+0x54>
printf("main 完毕 - 大局 g_int = %d, 大局 g_str = %s.\n", g_int, g_str);
54: 48 8b 15 00 00 00 00 mov 0x0(%rip),%rdx # 5b <main+0x5b>
5b: 8b 05 00 00 00 00 mov 0x0(%rip),%eax # 61 <main+0x61>
61: 89 c6 mov %eax,%esi
63: 48 8d 3d 00 00 00 00 lea 0x0(%rip),%rdi # 6a <main+0x6a>
6a: b8 00 00 00 00 mov $0x0,%eax
6f: e8 00 00 00 00 callq 74 <main+0x74>
return 0;
74: b8 00 00 00 00 mov $0x0,%eax
79: c9 leaveq
7a: c3 retq
解读
- 注意那些
00 00 00 00
部分,这些都是编译器暂时无法确认的内容.肉眼计算下此刻OFFSET
偏移位为0x16
,0x21
,即下表内容
objdump -r ./obj/main.o
root@5e3abe332c5a:/home/docker/test4harmony/54# objdump -r ./obj/main.o
./obj/main.o: file format elf64-x86-64
RELOCATION RECORDS FOR [.text]:
OFFSET TYPE VALUE
0000000000000016 R_X86_64_PC32 .rodata-0x0000000000000004
0000000000000021 R_X86_64_PC32 g_str-0x0000000000000004
0000000000000027 R_X86_64_PC32 g_int-0x0000000000000004
0000000000000030 R_X86_64_PC32 .rodata+0x000000000000000c
000000000000003a R_X86_64_PLT32 printf-0x0000000000000004
0000000000000044 R_X86_64_PLT32 func_int-0x0000000000000004
0000000000000050 R_X86_64_PLT32 func_str-0x0000000000000004
0000000000000057 R_X86_64_PC32 g_str-0x0000000000000004
000000000000005d R_X86_64_PC32 g_int-0x0000000000000004
0000000000000066 R_X86_64_PC32 .rodata+0x0000000000000044
0000000000000070 R_X86_64_PLT32 printf-0x0000000000000004
解读
-
0x16
,0x21
对应的这些值都是 0,也便是说关于编译器不能确认的地址都这设置为空(0x000000),一起编译器都生成一一对应的记载,该记载告知链接器在进行链接时要批改这条指令中函数的内存地址,并告知是什么重定位类型,要去哪里找数据填充. -
外部大局变量重定位
g_str
,g_int
0000000000000021 R_X86_64_PC32 g_str-0x0000000000000004 0000000000000027 R_X86_64_PC32 g_int-0x0000000000000004 --- 1e: 48 8b 15 00 00 00 00 mov 0x0(%rip),%rdx # 25 <main+0x25> 25: 8b 05 00 00 00 00 mov 0x0(%rip),%eax # 2b <main+0x2b>
编译器连g_str在哪个.o文件都不知道,当然更不知道g_str运转时的地址,所以在g.o文件中设置一个重定位,要求后续进程依据”S(g_str内存地址)-A(0x04)”,修正main.o镜像中0x21偏移处的值.
-
函数重定位,重定位类型为
R_X86_64_PLT32
000000000000003a R_X86_64_PLT32 printf-0x0000000000000004 0000000000000044 R_X86_64_PLT32 func_int-0x0000000000000004 0000000000000050 R_X86_64_PLT32 func_str-0x0000000000000004 0000000000000070 R_X86_64_PLT32 printf-0x0000000000000004 --- 39: e8 00 00 00 00 callq 3e <main+0x3e> 43: e8 00 00 00 00 callq 48 <main+0x48>
相同编译器连“func_int
,
printf`在哪个.o文件都不知道,当然更不知道它们的运转时的地址,所以在main.o文件中设置一个重定位,后续将 修正main.o镜像中3a偏移处的值. -
另一部分数据由本.o自己供给,如下
objdump -sj .rodata ./obj/main.o
root@5e3abe332c5a:/home/docker/test4harmony/54# objdump -sj .rodata ./obj/main.o
./obj/main.o: file format elf64-x86-64
Contents of section .rodata:
0000 6861726d 6f6e7920 6f730000 00000000 harmony os......
0010 6d61696e 20e5bc80 e5a78b20 2d20e585 main ...... - ..
0020 a8e5b180 20675f69 6e74203d 2025642c .... g_int = %d,
0030 20e585a8 e5b18020 675f7374 72203d20 ...... g_str =
0040 25732e0a 00000000 6d61696e 20e7bb93 %s......main ...
0050 e69d9f20 2d20e585 a8e5b180 20675f69 ... - ...... g_i
0060 6e74203d 2025642c 20e585a8 e5b18020 nt = %d, ......
0070 675f7374 72203d20 25732e0a 00 g_str = %s...
解读
- 内部变量重定位.
由于是局部变量,编译器知道数据放在了13: 48 8d 05 00 00 00 00 lea 0x0(%rip),%rax # 1a <main+0x1a> --- 0000000000000016 R_X86_64_PC32 .rodata-0x0000000000000004
.rodata
区,要求后续进程依据 “S(main.o镜像中.rodata的内存地址)-A(0x04)”,修正main.o镜像中0x16偏移处的值.
再剖析通过静态链接之后的可执行文件
objdump -S ./bin/weharmony
root@5e3abe332c5a:/home/docker/test4harmony/54# objdump -S ./bin/weharmony
Disassembly of section .text:
0000000000001188 <func_str>:
void func_str(char *str) {
1188: f3 0f 1e fa endbr64
118c: 55 push %rbp
118d: 48 89 e5 mov %rsp,%rbp
1190: 48 83 ec 10 sub $0x10,%rsp
1194: 48 89 7d f8 mov %rdi,-0x8(%rbp)
g_str = str;
1198: 48 8b 45 f8 mov -0x8(%rbp),%rax
119c: 48 89 05 75 2e 00 00 mov %rax,0x2e75(%rip) # 4018 <g_str>
printf("func_str g_str = %s.\n", g_str);
11a3: 48 8b 05 6e 2e 00 00 mov 0x2e6e(%rip),%rax # 4018 <g_str>
11aa: 48 89 c6 mov %rax,%rsi
11ad: 48 8d 3d 83 0e 00 00 lea 0xe83(%rip),%rdi # 2037 <_IO_stdin_used+0x37>
11b4: b8 00 00 00 00 mov $0x0,%eax
11b9: e8 92 fe ff ff callq 1050 <printf@plt>
11be: 90 nop
11bf: c9 leaveq
11c0: c3 retq
00000000000011c1 <main>:
#include <stdio.h>
#include "part.h"
extern int g_int;
extern char *g_str;
int main() {
11c1: f3 0f 1e fa endbr64
11c5: 55 push %rbp
11c6: 48 89 e5 mov %rsp,%rbp
11c9: 48 83 ec 10 sub $0x10,%rsp
int loc_int = 53;
11cd: c7 45 f4 35 00 00 00 movl $0x35,-0xc(%rbp)
char *loc_str = "harmony os";
11d4: 48 8d 05 75 0e 00 00 lea 0xe75(%rip),%rax # 2050 <_IO_stdin_used+0x50>
11db: 48 89 45 f8 mov %rax,-0x8(%rbp)
printf("main 开端 - 大局 g_int = %d, 大局 g_str = %s.\n", g_int, g_str);
11df: 48 8b 15 32 2e 00 00 mov 0x2e32(%rip),%rdx # 4018 <g_str>
11e6: 8b 05 24 2e 00 00 mov 0x2e24(%rip),%eax # 4010 <g_int>
11ec: 89 c6 mov %eax,%esi
11ee: 48 8d 3d 6b 0e 00 00 lea 0xe6b(%rip),%rdi # 2060 <_IO_stdin_used+0x60>
11f5: b8 00 00 00 00 mov $0x0,%eax
11fa: e8 51 fe ff ff callq 1050 <printf@plt>
func_int(loc_int);
11ff: 8b 45 f4 mov -0xc(%rbp),%eax
1202: 89 c7 mov %eax,%edi
1204: e8 40 ff ff ff callq 1149 <func_int>
func_str(loc_str);
1209: 48 8b 45 f8 mov -0x8(%rbp),%rax
120d: 48 89 c7 mov %rax,%rdi
1210: e8 73 ff ff ff callq 1188 <func_str>
printf("main 完毕 - 大局 g_int = %d, 大局 g_str = %s.\n", g_int, g_str);
1215: 48 8b 15 fc 2d 00 00 mov 0x2dfc(%rip),%rdx # 4018 <g_str>
121c: 8b 05 ee 2d 00 00 mov 0x2dee(%rip),%eax # 4010 <g_int>
1222: 89 c6 mov %eax,%esi
1224: 48 8d 3d 6d 0e 00 00 lea 0xe6d(%rip),%rdi # 2098 <_IO_stdin_used+0x98>
122b: b8 00 00 00 00 mov $0x0,%eax
1230: e8 1b fe ff ff callq 1050 <printf@plt>
return 0;
1235: b8 00 00 00 00 mov $0x0,%eax
123a: c9 leaveq
123b: c3 retq
123c: 0f 1f 40 00 nopl 0x0(%rax)
root@5e3abe332c5a:/home/docker/test4harmony/54# objdump -s ./bin/weharmony
...省掉部分
Contents of section .plt.got:
1040 f30f1efa f2ff25ad 2f00000f 1f440000 ......%./....D..
Contents of section .plt.sec:
1050 f30f1efa f2ff2575 2f00000f 1f440000 ......%u/....D..
Contents of section .data:
4000 00000000 00000000 08400000 00000000 .........@......
4010 33000000 00000000 08200000 00000000 3........ ......
Contents of section .rodata:
2000 01000200 00000000 68656c6c 6f20776f ........hello wo
2010 726c6400 00000000 66756e63 5f696e74 rld.....func_int
2020 20675f69 6e74203d 2025642c 746d7020 g_int = %d,tmp
2030 3d202564 2e0a0066 756e635f 73747220 = %d...func_str
2040 675f7374 72203d20 25732e0a 00000000 g_str = %s......
2050 6861726d 6f6e7920 6f730000 00000000 harmony os......
2060 6d61696e 20e5bc80 e5a78b20 2d20e585 main ...... - ..
2070 a8e5b180 20675f69 6e74203d 2025642c .... g_int = %d,
2080 20e585a8 e5b18020 675f7374 72203d20 ...... g_str =
2090 25732e0a 00000000 6d61696e 20e7bb93 %s......main ...
20a0 e69d9f20 2d20e585 a8e5b180 20675f69 ... - ...... g_i
20b0 6e74203d 2025642c 20e585a8 e5b18020 nt = %d, ......
20c0 675f7374 72203d20 25732e0a 00 g_str = %s...
解读
- main.o中被重定位的部分不再是
00 00 00 00
都已经有了实践的数据,例如:
对应的char *loc_str = "harmony os"; 11d4: 48 8d 05 75 0e 00 00 lea 0xe75(%rip),%rax # 2050 <_IO_stdin_used+0x50>
# 2050 <_IO_stdin_used+0x50>
地址数据正是.rodata
2050方位的harmony os
- 看main()中的
1209: 48 8b 45 f8 mov -0x8(%rbp),%rax 120d: 48 89 c7 mov %rax,%rdi 1210: e8 73 ff ff ff callq 1188 <func_str>
callq 1188
1188
正是func_str
的进口地址void func_str(char *str) { 1188: f3 0f 1e fa endbr64
- 看大局变量
g_str``g_int
对应的链接地址0x4018
和0x4010
由1215: 48 8b 15 fc 2d 00 00 mov 0x2dfc(%rip),%rdx # 4018 <g_str> 121c: 8b 05 ee 2d 00 00 mov 0x2dee(%rip),%eax # 4010 <g_int>
.data
区供给4000 00000000 00000000 08400000 00000000 .........@...... 4010 33000000 00000000 08200000 00000000 3........ ......
0x4010
= 0x33 = 51 - main函数中调用
printf
代码为callq 1050
内容由1230: e8 1b fe ff ff callq 1050 <printf@plt>
.plt.sec
区供给,并反汇编该区为
注意Contents of section .plt.sec: 1050 f30f1efa f2ff2575 2f00000f 1f440000 ......%u/....D.. Disassembly of section .plt.sec: 0000000000001050 <printf@plt>: 1050: f3 0f 1e fa endbr64 1054: f2 ff 25 75 2f 00 00 bnd jmpq *0x2f75(%rip) # 3fd0 <printf@GLIBC_2.2.5> 105b: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1)
3fd0
,需求运转时环境供给,加载器动态重定位完成. - 总结下来便是 weharmony 已完结了一切.o文件的静态重定位部分, 组合成一个新的可执行文件,其中只还有动态链接部分没有完结,由于那需求运转时重定位地址.如下:
objdump -R ./bin/weharmony
root@5e3abe332c5a:/home/docker/test4harmony/54# objdump -R ./bin/weharmony
./bin/weharmony: file format elf64-x86-64
DYNAMIC RELOCATION RECORDS
OFFSET TYPE VALUE
0000000000003db8 R_X86_64_RELATIVE *ABS*+0x0000000000001140
0000000000003dc0 R_X86_64_RELATIVE *ABS*+0x0000000000001100
0000000000004008 R_X86_64_RELATIVE *ABS*+0x0000000000004008
0000000000004018 R_X86_64_RELATIVE *ABS*+0x0000000000002008
0000000000003fd8 R_X86_64_GLOB_DAT _ITM_deregisterTMCloneTable
0000000000003fe0 R_X86_64_GLOB_DAT __libc_start_main@GLIBC_2.2.5
0000000000003fe8 R_X86_64_GLOB_DAT __gmon_start__
0000000000003ff0 R_X86_64_GLOB_DAT _ITM_registerTMCloneTable
0000000000003ff8 R_X86_64_GLOB_DAT __cxa_finalize@GLIBC_2.2.5
0000000000003fd0 R_X86_64_JUMP_SLOT printf@GLIBC_2.2.5
解读
- 这是
weharmony
对运转时环境提交的一份交际阐明,有了它就能够与世界接轨,入住地球村. - 这份阐明其他部分很陌生,看个熟悉的
3fd0
,其动态链接重定位类型为R_X86_64_JUMP_SLOT
,它在告知动态加载器,在运转时环境中找到printf
并完结动态重定位.
百万汉字注解.精读内核源码
四大码仓同步注解内核源码, >> 检查 gitee 仓库
百篇博客剖析.深挖内核地基
给鸿蒙内核源码加注释进程中,整理出以下文章。内容立足源码,常以日子场景打比方尽可能多的将内核知识点置入某种场景,具有画面感,容易理解回忆。说他人能听得懂的话很重要! 百篇博客绝不是百度教条式的在说一堆诘屈聱牙的概念,那没什么意思。更希望让内核变得绘声绘色,倍感亲切.的确有难度,自不量力,但已经出发,回头已是不可能的了。 :P
与代码有bug需不断debug一样,文章和注解内容会存在不少讹夺之处,请多包容,但会重复批改,继续更新,.xx
代表修正的次数,精雕细琢,要言不烦,力求打造精品内容。
编译构建 | 根底工具 | 加载运转 | 进程办理 |
---|---|---|---|
编译环境 编译进程 环境脚本 构建工具 gn应用 忍者ninja |
双向链表 位图办理 用栈方式 定时器 原子操作 时间办理 |
ELF格式 ELF解析 静态链接 重定位 进程映像 |
进程办理 进程概念 Fork 特殊进程 进程回收 信号出产 信号消费 Shell编辑 Shell解析 |
进程通讯 | 内存办理 | 来龙去脉 | 使命办理 |
自旋锁 互斥锁 进程通讯 信号量 事情操控 消息行列 |
内存分配 内存办理 内存汇编 内存映射 内存规则 物理内存 |
总目录 调度故事 内存主奴 源码注释 源码结构 静态站点 |
时钟使命 使命调度 使命办理 调度行列 调度机制 线程概念 并发并行 体系调用 使命切换 |
文件体系 | 硬件架构 | ||
文件概念 文件体系 索引节点 挂载目录 根文件体系 字符设备 VFS 文件句柄 管道文件 |
汇编根底 汇编传参 作业形式 寄存器 反常接收 汇编汇总 中止切换 中止概念 中止办理 |
鸿蒙研讨站 | 每天死磕一点点,原创不易,欢迎转载,但请注明出处。