将 HarmonyOS | 鸿蒙 研究到底 < 国内 | 国外 >
百篇博客系列篇.本篇为:
下图是一个可执行文件编译,链接的过程.
本篇将通过一个完整的小工程来阐述ELF编译,链接过程,并分析.o和bin文件中各区,符号表之间的关系.从一个崭新的视角去看中间过程,阅读之前建议先看
先得有个小工程,麻雀虽小,但五脏俱全,标准的文件夹和Makefile结构,如下:
|-bin 可执行文件
|- weharmony
|-include 头文件
|- part.h
|-obj 目标文件
|- main.o
|- part.o
|-src 源文件
|- main.c
|- part.c
Makefile
看到 .c .h .o 就感觉特别的亲切 : ),项目很简单,但具有代表性,有全局变量/函数,extern
,多文件链接,和动态链接库的printf
,用cat命令看看三个文件内容.
root@5e3abe332c5a:/home/docker/test4harmony/54# cat ./src/main.c
#include
#include "part.h"
extern int g_int;
extern char *g_str;
int main() {
int loc_int = 53;
char *loc_str = "harmony os";
printf("main 开始 - 全局 g_int = %d, 全局 g_str = %s.\n", g_int, g_str);
func_int(loc_int);
func_str(loc_str);
printf("main 结束 - 全局 g_int = %d, 全局 g_str = %s.\n", g_int, g_str);
return 0;
}
root@5e3abe332c5a:/home/docker/test4harmony/54# cat ./src/part.c
#include
#include "part.h"
int g_int = 51;
char *g_str = "hello world";
void func_int(int i) {
int tmp = i;
g_int = 2 * tmp ;
printf("func_int g_int = %d,tmp = %d.\n", g_int,tmp);
}
void func_str(char *str) {
g_str = str;
printf("func_str g_str = %s.\n", g_str);
}
root@5e3abe332c5a:/home/docker/test4harmony/54# cat ./include/part.h
#ifndef _PART_H_
#define _PART_H_
void func_int(int i);
void func_str(char *str);
#endif
Makefile
采用标准写法,关于makefile系列篇会在编译过程篇中详细说明,此处先看点简单的.
root@5e3abe332c5a:/home/docker/test4harmony/54# cat Makefile
DIR_INC = ./include
DIR_SRC = ./src
DIR_OBJ = ./obj
DIR_BIN = ./bin
SRC = $(wildcard ${
DIR_SRC}/*.c)
OBJ = $(patsubst %.c,${DIR_OBJ}/%.o,$(notdir ${SRC}))
TARGET = weharmony
BIN_TARGET = ${DIR_BIN}/${TARGET}
CC = gcc
CFLAGS = -g -Wall -I${DIR_INC}
${BIN_TARGET}:${OBJ}
$(CC) $(OBJ) -o $@
${DIR_OBJ}/%.o:${DIR_SRC}/%.c
$(CC) $(CFLAGS) -c $< -o $@
.PHONY:clean
clean:
find ${DIR_OBJ} -name *.o -exec rm -rf {}
root@5e3abe332c5a:/home/docker/test4harmony/54# make
gcc -g -Wall -I./include -c src/part.c -o obj/part.o
gcc -g -Wall -I./include -c src/main.c -o obj/main.o
gcc ./obj/part.o ./obj/main.o -o bin/weharmony
root@5e3abe332c5a:/home/docker/test4harmony/54# ./bin/weharmony
main 开始 - 全局 g_int = 51, 全局 g_str = hello world.
func_int g_int = 106,tmp = 53.
func_str g_str = harmony os.
main 结束 - 全局 g_int = 106, 全局 g_str = harmony os.
结果很简单,没什么好说的.
准备工作完成,开始了真正的分析. 因为命令输出内容太多,本篇做了精简,去除了干扰项.对这些命令还不行清楚的请翻看系列篇其他文章,此处不做介绍,阅读本篇需要一定的基础.
root@5e3abe332c5a:/home/docker/test4harmony/54# readelf -S ./obj/main.o
There are 22 section headers, starting at offset 0x1498:
Section Headers:
[Nr] Name Type Address Offset
Size EntSize Flags Link Info Align
[ 0] NULL 0000000000000000 00000000
0000000000000000 0000000000000000 0 0 0
[ 1] .text PROGBITS 0000000000000000 00000040
000000000000007b 0000000000000000 AX 0 0 1
[ 2] .rela.text RELA 0000000000000000 00000c80
0000000000000108 0000000000000018 I 19 1 8
[ 3] .data PROGBITS 0000000000000000 000000bb
0000000000000000 0000000000000000 WA 0 0 1
[ 4] .bss NOBITS 0000000000000000 000000bb
0000000000000000 0000000000000000 WA 0 0 1
[ 5] .rodata PROGBITS 0000000000000000 000000c0
000000000000007d 0000000000000000 A 0 0 8
......
root@5e3abe332c5a:/home/docker/test4harmony/54# readelf -s ./obj/main.o
Symbol table '.symtab' contains 22 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 0 FILE LOCAL DEFAULT ABS main.c
2: 0000000000000000 0 SECTION LOCAL DEFAULT 1
...
15: 0000000000000000 123 FUNC GLOBAL DEFAULT 1 main
16: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND g_str
17: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND g_int
18: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND _GLOBAL_OFFSET_TABLE_
19: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND printf
20: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND func_int
21: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND func_str
解读
编译 main.c 后 main.o 告诉了链接器以下信息
(Type=FILE)
(Type=FUNC)
,并且这是一个全局函数,(Bind = GLOBAL , Vis = DEFAULT
,全局的意思就是可以被外部文件所引用.g_str
,printf
,func_int
,…,都是需要外部提供,并未在本文件中定义的符号 (Ndx = UND , Type = NOTYPE)
,至于怎么顺藤摸瓜找到这些符号那我不管,.o文件是独立存在,它只是告诉你我用了哪些东西,但我也不知道在哪里.printf
和func_int
对它来说一视同仁,都是外部链接符号,没有特殊对待.root@5e3abe332c5a:/home/docker/test4harmony/54# readelf -S ./obj/part.o
[ 1] .text PROGBITS 0000000000000000 00000040
0000000000000078 0000000000000000 AX 0 0 1
[ 2] .rela.text RELA 0000000000000000 00000cf0
00000000000000c0 0000000000000018 I 21 1 8
[ 3] .data PROGBITS 0000000000000000 000000b8
0000000000000004 0000000000000000 WA 0 0 4
[ 4] .bss NOBITS 0000000000000000 000000bc
0000000000000000 0000000000000000 WA 0 0 1
[ 5] .rodata PROGBITS 0000000000000000 000000c0
0000000000000045 0000000000000000 A 0 0 8
[ 6] .data.rel.local PROGBITS 0000000000000000 00000108
0000000000000008 0000000000000000 WA 0 0 8
......
root@5e3abe332c5a:/home/docker/test4harmony/54# readelf -s ./obj/part.o
Symbol table '.symtab' contains 22 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 0 FILE LOCAL DEFAULT ABS part.c
2: 0000000000000000 0 SECTION LOCAL DEFAULT 1
...
16: 0000000000000000 4 OBJECT GLOBAL DEFAULT 3 g_int
17: 0000000000000000 8 OBJECT GLOBAL DEFAULT 6 g_str
18: 0000000000000000 52 FUNC GLOBAL DEFAULT 1 func_int
19: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND _GLOBAL_OFFSET_TABLE_
20: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND printf
21: 0000000000000034 57 FUNC GLOBAL DEFAULT 1 func_str
解读
编译 part.c 后part.o告诉了链接器以下信息
(Type=FILE)
func_int
,func_str
(Type=FUNC)
,并且都是全局函数,(Bind = GLOBAL , Vis = DEFAULT
,全局的意思就是可以被外部文件所引用.g_int
,g_str
(Type=OBJECT)
,并且都是全局对象,同样可以被外部使用.printf
,_GLOBAL_OFFSET_TABLE_
,都是需要外部提供,并未在本文件中定义的符号 (Ndx = UND , Type = NOTYPE)
tmp
并没有出现在符号表中.因为符号表相当于外交部,只有对外的内容.func_int
,func_str
在1区代码区.text
.g_int
在3区.data
数据区, 打开3区,发现了 0x33 就是源码中 int g_int = 51;的值 root@5e3abe332c5a:/home/docker/test4harmony/54# readelf -x 3 ./obj/part.o
Hex dump of section '.data':
0x00000000 33000000 3...
g_str
在6区,.data.rel.local
数据区,打开6区看结果 root@5e3abe332c5a:/home/docker/test4harmony/54# readelf -x 6 ./obj/part.o
Hex dump of section '.data.rel.local':
NOTE: This section has relocations against it, but these have NOT been applied to this dump.
0x00000000 00000000 00000000 ........
并未发现 char *g_str = “hello world”;的身影,反而抛下一句话 NOTE: This section has relocations against it, but these have NOT been applied to this dump.翻译过来是 注意:此部分已针对它进行重定位,但是尚未将其应用于此转储. 最后在5区 '.rodata’找到了 hello world
root@5e3abe332c5a:/home/docker/test4harmony/54# readelf -x 5 ./obj/part.o
Hex dump of section '.rodata':
0x00000000 68656c6c 6f20776f 726c6400 00000000 hello world.....
0x00000010 66756e63 5f696e74 20675f69 6e74203d func_int g_int =
0x00000020 2025642c 746d7020 3d202564 2e0a0066 %d,tmp = %d...f
0x00000030 756e635f 73747220 675f7374 72203d20 unc_str g_str =
0x00000040 25732e0a 00 %s..
至于重定向是如何实现的,在系列篇 重定向篇中已有详细说明,不再此展开说.weharmony
是将 main.o
,part.o
和库文件链接完成后的可执行文件.
root@5e3abe332c5a:/home/docker/test4harmony/54# readelf -S ./bin/weharmony
There are 36 section headers, starting at offset 0x4908:
Section Headers:
[Nr] Name Type Address Offset
Size EntSize Flags Link Info Align
......
[16] .text PROGBITS 0000000000001060 00001060
0000000000000255 0000000000000000 AX 0 0 16
[17] .fini PROGBITS 00000000000012b8 000012b8
000000000000000d 0000000000000000 AX 0 0 4
[18] .rodata PROGBITS 0000000000002000 00002000
00000000000000cd 0000000000000000 A 0 0 8
......
[25] .data PROGBITS 0000000000004000 00003000
0000000000000020 0000000000000000 WA 0 0 8
[26] .bss NOBITS 0000000000004020 00003020
0000000000000008 0000000000000000 WA 0 0 1
root@5e3abe332c5a:/home/docker/test4harmony/54# readelf -s ./bin/weharmony
Symbol table '.dynsym' contains 7 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_deregisterTMCloneTab
2: 0000000000000000 0 FUNC GLOBAL DEFAULT UND printf@GLIBC_2.2.5 (2)
3: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __libc_start_main@GLIBC_2.2.5 (2)
4: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
5: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_registerTMCloneTable
6: 0000000000000000 0 FUNC WEAK DEFAULT UND __cxa_finalize@GLIBC_2.2.5 (2)
Symbol table '.symtab' contains 75 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000318 0 SECTION LOCAL DEFAULT 1
2: 0000000000000338 0 SECTION LOCAL DEFAULT 2
3: 0000000000000358 0 SECTION LOCAL DEFAULT 3
....
33: 0000000000000000 0 FILE LOCAL DEFAULT ABS crtstuff.c
34: 0000000000001090 0 FUNC LOCAL DEFAULT 16 deregister_tm_clones
35: 00000000000010c0 0 FUNC LOCAL DEFAULT 16 register_tm_clones
36: 0000000000001100 0 FUNC LOCAL DEFAULT 16 __do_global_dtors_aux
37: 0000000000004020 1 OBJECT LOCAL DEFAULT 26 completed.8060
38: 0000000000003dc0 0 OBJECT LOCAL DEFAULT 22 __do_global_dtors_aux_fin
39: 0000000000001140 0 FUNC LOCAL DEFAULT 16 frame_dummy
40: 0000000000003db8 0 OBJECT LOCAL DEFAULT 21 __frame_dummy_init_array_
41: 0000000000000000 0 FILE LOCAL DEFAULT ABS part.c
42: 0000000000000000 0 FILE LOCAL DEFAULT ABS main.c
43: 0000000000000000 0 FILE LOCAL DEFAULT ABS crtstuff.c
44: 000000000000225c 0 OBJECT LOCAL DEFAULT 20 __FRAME_END__
45: 0000000000000000 0 FILE LOCAL DEFAULT ABS
46: 0000000000003dc0 0 NOTYPE LOCAL DEFAULT 21 __init_array_end
47: 0000000000003dc8 0 OBJECT LOCAL DEFAULT 23 _DYNAMIC
48: 0000000000003db8 0 NOTYPE LOCAL DEFAULT 21 __init_array_start
49: 00000000000020c0 0 NOTYPE LOCAL DEFAULT 19 __GNU_EH_FRAME_HDR
50: 0000000000003fb8 0 OBJECT LOCAL DEFAULT 24 _GLOBAL_OFFSET_TABLE_
51: 0000000000001000 0 FUNC LOCAL DEFAULT 12 _init
52: 00000000000012b0 5 FUNC GLOBAL DEFAULT 16 __libc_csu_fini
53: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_deregisterTMCloneTab
54: 0000000000004000 0 NOTYPE WEAK DEFAULT 25 data_start
55: 0000000000004020 0 NOTYPE GLOBAL DEFAULT 25 _edata
56: 00000000000012b8 0 FUNC GLOBAL HIDDEN 17 _fini
57: 0000000000000000 0 FUNC GLOBAL DEFAULT UND printf@@GLIBC_2.2.5
58: 0000000000004010 4 OBJECT GLOBAL DEFAULT 25 g_int
59: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __libc_start_main@@GLIBC_
60: 0000000000004000 0 NOTYPE GLOBAL DEFAULT 25 __data_start
61: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
62: 0000000000004008 0 OBJECT GLOBAL HIDDEN 25 __dso_handle
63: 0000000000004018 8 OBJECT GLOBAL DEFAULT 25 g_str
64: 0000000000002000 4 OBJECT GLOBAL DEFAULT 18 _IO_stdin_used
65: 0000000000001240 101 FUNC GLOBAL DEFAULT 16 __libc_csu_init
66: 0000000000001149 52 FUNC GLOBAL DEFAULT 16 func_int
67: 0000000000004028 0 NOTYPE GLOBAL DEFAULT 26 _end
68: 0000000000001060 47 FUNC GLOBAL DEFAULT 16 _start
69: 000000000000117d 57 FUNC GLOBAL DEFAULT 16 func_str
70: 0000000000004020 0 NOTYPE GLOBAL DEFAULT 26 __bss_start
71: 00000000000011b6 123 FUNC GLOBAL DEFAULT 16 main
72: 0000000000004020 0 OBJECT GLOBAL HIDDEN 25 __TMC_END__
73: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_registerTMCloneTable
74: 0000000000000000 0 FUNC WEAK DEFAULT UND __cxa_finalize@@GLIBC_2.2
解读
链接后的可执行文件 weharmony
将告诉加载器以下信息
Type = FILE
Type = FUNC
func_str,func_int,_start,mainType = OBJECT
g_int,g_str,…它将这些数据统一归到了25区.root@5e3abe332c5a:/home/docker/test4harmony/54# readelf -x 25 ./bin/weharmony
Hex dump of section '.data':
0x00004000 00000000 00000000 08400000 00000000 .........@......
0x00004010 33000000 00000000 08200000 00000000 3........ ......
是不是和part.o一样也被放在了.rodata
区,再反查 18区,果然发了 main.c和part.c的数据都放在了这里.root@5e3abe332c5a:/home/docker/test4harmony/54# readelf -x 18 ./bin/weharmony
Hex dump of section '.rodata':
0x00002000 01000200 00000000 68656c6c 6f20776f ........hello wo
0x00002010 726c6400 00000000 66756e63 5f696e74 rld.....func_int
0x00002020 20675f69 6e74203d 2025642c 746d7020 g_int = %d,tmp
0x00002030 3d202564 2e0a0066 756e635f 73747220 = %d...func_str
0x00002040 675f7374 72203d20 25732e0a 00000000 g_str = %s......
0x00002050 6861726d 6f6e7920 6f730000 00000000 harmony os......
0x00002060 6d61696e 20e5bc80 e5a78b20 2d20e585 main ...... - ..
0x00002070 a8e5b180 20675f69 6e74203d 2025642c .... g_int = %d,
0x00002080 20e585a8 e5b18020 675f7374 72203d20 ...... g_str =
0x00002090 25732e0a 00000000 6d61696e 20e7bb93 %s......main ...
0x000020a0 e69d9f20 2d20e585 a8e5b180 20675f69 ... - ...... g_i
0x000020b0 6e74203d 2025642c 20e585a8 e5b18020 nt = %d, ......
0x000020c0 675f7374 72203d20 25732e0a 00 g_str = %s...
printf
的变化,从Type = NOTYPE
变成了Type = FUNC
,告诉了后续的动态链接这是个函数 57: 0000000000000000 0 FUNC GLOBAL DEFAULT UND printf@@GLIBC_2.2.5
但是内容依然是Ndx=UND
,weharmony也提供不了,内容需要运行时环境提供.并在需要动态链接表中也已经注明了内容清单,运行环境必须提供以下内容才能真正跑起来weharmony.Symbol table '.dynsym' contains 7 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_deregisterTMCloneTab
2: 0000000000000000 0 FUNC GLOBAL DEFAULT UND printf@GLIBC_2.2.5 (2)
3: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __libc_start_main@GLIBC_2.2.5 (2)
4: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
5: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_registerTMCloneTable
6: 0000000000000000 0 FUNC WEAK DEFAULT UND __cxa_finalize@GLIBC_2.2.5 (2)
本例在windows环境中一般是跑不起来的.除非提供对应的运行时环境.在加注过程中,整理出以下文章.内容立足源码,常以生活场景打比方尽可能多的将内核知识点置入某种场景,具有画面感,容易理解记忆.说别人能听得懂的话很重要! 百篇博客绝不是百度教条式的在说一堆诘屈聱牙的概念,那没什么意思.更希望让内核变得栩栩如生,倍感亲切.确实有难度,自不量力,但已经出发,回头已是不可能的了.
与代码有bug需不断debug一样,文章和注解内容会存在不少错漏之处,但会反复修正,持续更新,.xx
代表修改的次数,精雕细琢,言简意赅,力求打造精品内容.
v54.xx 鸿蒙内核源码分析(静态链接篇) | 完整小项目看透静态链接过程 | 51 .c .h .o
v53.xx 鸿蒙内核源码分析(ELF解析篇) | 你要忘了她姐俩你就不是银 | 51 .c .h .o
v52.xx 鸿蒙内核源码分析(静态站点篇) | 五一哪也没去就干了这事 | 51 .c .h .o
v51.xx 鸿蒙内核源码分析(ELF格式篇) | 应用程序入口并不是main | 51 .c .h .o
v50.xx 鸿蒙内核源码分析(编译环境篇) | 编译鸿蒙看这篇或许真的够了 | 51 .c .h .o
v49.xx 鸿蒙内核源码分析(信号消费篇) | 谁让CPU连续四次换栈运行 | 51 .c .h .o
v48.xx 鸿蒙内核源码分析(信号生产篇) | 年过半百,依然活力十足 | 51 .c .h .o
v47.xx 鸿蒙内核源码分析(进程回收篇) | 临终前如何向老祖宗托孤 | 51 .c .h .o
v46.xx 鸿蒙内核源码分析(特殊进程篇) | 龙生龙凤生凤老鼠生儿会打洞 | 51 .c .h .o
v45.xx 鸿蒙内核源码分析(Fork篇) | 一次调用,两次返回 | 51 .c .h .o
v44.xx 鸿蒙内核源码分析(中断管理篇) | 江湖从此不再怕中断 | 51 .c .h .o
v43.xx 鸿蒙内核源码分析(中断概念篇) | 海公公的日常工作 | 51 .c .h .o
v42.xx 鸿蒙内核源码分析(中断切换篇) | 系统因中断活力四射 | 51 .c .h .o
v41.xx 鸿蒙内核源码分析(任务切换篇) | 看汇编如何切换任务 | 51 .c .h .o
v40.xx 鸿蒙内核源码分析(汇编汇总篇) | 汇编可爱如邻家女孩 | 51 .c .h .o
v39.xx 鸿蒙内核源码分析(异常接管篇) | 社会很单纯,复杂的是人 | 51 .c .h .o
v38.xx 鸿蒙内核源码分析(寄存器篇) | 小强乃宇宙最忙存储器 | 51 .c .h .o
v37.xx 鸿蒙内核源码分析(系统调用篇) | 开发者永远的口头禅 | 51 .c .h .o
v36.xx 鸿蒙内核源码分析(工作模式篇) | CPU是韦小宝,七个老婆 | 51 .c .h .o
v35.xx 鸿蒙内核源码分析(时间管理篇) | 谁是内核基本时间单位 | 51 .c .h .o
v34.xx 鸿蒙内核源码分析(原子操作篇) | 谁在为原子操作保驾护航 | 51 .c .h .o
v33.xx 鸿蒙内核源码分析(消息队列篇) | 进程间如何异步传递大数据 | 51 .c .h .o
v32.xx 鸿蒙内核源码分析(CPU篇) | 整个内核就是一个死循环 | 51 .c .h .o
v31.xx 鸿蒙内核源码分析(定时器篇) | 哪个任务的优先级最高 | 51 .c .h .o
v30.xx 鸿蒙内核源码分析(事件控制篇) | 任务间多对多的同步方案 | 51 .c .h .o
v29.xx 鸿蒙内核源码分析(信号量篇) | 谁在负责解决任务的同步 | 51 .c .h .o
v28.xx 鸿蒙内核源码分析(进程通讯篇) | 九种进程间通讯方式速揽 | 51 .c .h .o
v27.xx 鸿蒙内核源码分析(互斥锁篇) | 比自旋锁丰满的互斥锁 | 51 .c .h .o
v26.xx 鸿蒙内核源码分析(自旋锁篇) | 自旋锁当立贞节牌坊 | 51 .c .h .o
v25.xx 鸿蒙内核源码分析(并发并行篇) | 听过无数遍的两个概念 | 51 .c .h .o
v24.xx 鸿蒙内核源码分析(进程概念篇) | 进程在管理哪些资源 | 51 .c .h .o
v23.xx 鸿蒙内核源码分析(汇编传参篇) | 如何传递复杂的参数 | 51 .c .h .o
v22.xx 鸿蒙内核源码分析(汇编基础篇) | CPU在哪里打卡上班 | 51 .c .h .o
v21.xx 鸿蒙内核源码分析(线程概念篇) | 是谁在不断的折腾CPU | 51 .c .h .o
v20.xx 鸿蒙内核源码分析(用栈方式篇) | 程序运行场地由谁提供 | 51 .c .h .o
v19.xx 鸿蒙内核源码分析(位图管理篇) | 谁能一分钱分两半花 | 51 .c .h .o
v18.xx 鸿蒙内核源码分析(源码结构篇) | 内核每个文件的含义 | 51 .c .h .o
v17.xx 鸿蒙内核源码分析(物理内存篇) | 怎么管理物理内存 | 51 .c .h .o
v16.xx 鸿蒙内核源码分析(内存规则篇) | 内存管理到底在管什么 | 51 .c .h .o
v15.xx 鸿蒙内核源码分析(内存映射篇) | 虚拟内存虚在哪里 | 51 .c .h .o
v14.xx 鸿蒙内核源码分析(内存汇编篇) | 谁是虚拟内存实现的基础 | 51 .c .h .o
v13.xx 鸿蒙内核源码分析(源码注释篇) | 鸿蒙必定成功,也必然成功 | 51 .c .h .o
v12.xx 鸿蒙内核源码分析(内存管理篇) | 虚拟内存全景图是怎样的 | 51 .c .h .o
v11.xx 鸿蒙内核源码分析(内存分配篇) | 内存有哪些分配方式 | 51 .c .h .o
v10.xx 鸿蒙内核源码分析(内存主奴篇) | 皇上和奴才如何相处 | 51 .c .h .o
v09.xx 鸿蒙内核源码分析(调度故事篇) | 用故事说内核调度过程 | 51 .c .h .o
v08.xx 鸿蒙内核源码分析(总目录) | 百万汉字注解 百篇博客分析 | 51 .c .h .o
v07.xx 鸿蒙内核源码分析(调度机制篇) | 任务是如何被调度执行的 | 51 .c .h .o
v06.xx 鸿蒙内核源码分析(调度队列篇) | 内核有多少个调度队列 | 51 .c .h .o
v05.xx 鸿蒙内核源码分析(任务管理篇) | 任务池是如何管理的 | 51 .c .h .o
v04.xx 鸿蒙内核源码分析(任务调度篇) | 任务是内核调度的单元 | 51 .c .h .o
v03.xx 鸿蒙内核源码分析(时钟任务篇) | 触发调度谁的贡献最大 | 51 .c .h .o
v02.xx 鸿蒙内核源码分析(进程管理篇) | 谁在管理内核资源 | 51 .c .h .o
v01.xx 鸿蒙内核源码分析(双向链表篇) | 谁是内核最重要结构体 | 51 .c .h .o
看系列篇文章会常看到 51 .c .h .o
,希望这对大家阅读不会造成影响.
分别对应以下四个站点的首个字符,感谢这些站点一直以来对系列篇的支持和推荐,尤其是 oschina gitee ,很喜欢它的界面风格,简洁大方,让人感觉到开源的伟大!
而巧合的是.c .h .o
是C语言的头/源/目标文件,这就很有意思了,冥冥之中似有天数,将这四个宝贝以这种方式融合在一起. 51 .c .h .o
, 我要CHO ,嗯嗯,hin 顺口 : )
百万汉字注解 >> 精读鸿蒙源码,中文注解分析, 深挖地基工程,大脑永久记忆,四大码仓每日同步更新< gitee | github | csdn | coding >
百篇博客分析 >> 故事说内核,问答式导读,生活式比喻,表格化说明,图形化展示,主流站点定期更新中< 51cto | csdn | harmony | osc >
热爱是所有的理由和答案 - turing
原创不易,欢迎转载,但麻烦请注明出处.