1# DragonOS内核核心API
2
3## 循环链表管理函数
4
5  循环链表是内核的重要的数据结构之一。包含在`kernel/common/list.h`中。
6
7### `void list_init(struct List *list)`
8
9#### 描述
10
11  初始化一个List结构体,使其prev和next指针指向自身
12
13#### 参数
14
15**list**
16
17  要被初始化的List结构体
18
19### `void list_add(struct List *entry, struct List *node)`
20
21#### 描述
22
23  将node插入到entry的后方
24
25#### 参数
26
27**entry**
28
29  已存在于循环链表中的一个结点
30
31**node**
32
33  待插入的结点
34
35### `void list_append(struct List *entry, struct List *node)`
36
37#### 描述
38
39  将node插入到entry的前方
40
41#### 参数
42
43**entry**
44
45  已存在于循环链表中的一个结点
46
47**node**
48
49  待插入的结点
50
51### `void list_del(struct List *entry)`
52
53#### 描述
54
55  从链表中删除结点entry
56
57#### 参数
58
59**entry**
60
61  待删除的结点
62
63### `list_del_init(struct List *entry)`
64
65#### 描述
66
67  从链表中删除结点entry,并将这个entry使用list_init()进行重新初始化。
68
69#### 参数
70
71**entry**
72
73  待删除的结点
74
75### `bool list_empty(struct List *entry)`
76
77#### 描述
78
79  判断链表是否为空
80
81#### 参数
82
83**entry**
84
85  链表中的一个结点
86
87### `struct List *list_prev(struct List *entry)`
88
89#### 描述
90
91  获取entry的前一个结点
92
93#### 参数
94
95**entry**
96
97  链表中的一个结点
98
99### `struct List *list_next(struct List *entry)`
100
101#### 描述
102
103  获取entry的后一个结点
104
105#### 参数
106
107**entry**
108
109  链表中的一个结点
110
111### `void list_replace(struct List *old, struct List *new)`
112
113#### 描述
114
115  将链表中的old结点替换成new结点
116
117#### 参数
118
119**old**
120
121  要被换下来的结点
122
123**new**
124
125  要被换入链表的新的结点
126
127(_list_entry)=
128
129### `list_entry(ptr, type, member)`
130
131#### 描述
132
133  该宏能通过ptr指向的List获取到List所处的结构体的地址
134
135#### 参数
136
137**ptr**
138
139  指向List结构体的指针
140
141**type**
142
143  要被换入链表的新的结点
144
145**member**
146
147  List结构体在上述的“包裹list结构体的结构体”中的变量名
148
149### `list_first_entry(ptr, type, member)`
150
151#### 描述
152
153  获取链表中的第一个元素。请注意,该宏要求链表非空,否则会出错。
154
155#### 参数
156
157&emsp;&emsp;与{ref}`list_entry() <_list_entry>`相同
158
159### `list_first_entry_or_null(ptr, type, member)`
160
161#### 描述
162
163&emsp;&emsp;获取链表中的第一个元素。若链表为空,则返回NULL。
164
165#### 参数
166
167&emsp;&emsp;与{ref}`list_entry() <_list_entry>`相同
168
169### `list_last_entry(ptr, type, member)`
170
171#### 描述
172
173&emsp;&emsp;获取链表中的最后一个元素。请注意,该宏要求链表非空,否则会出错。
174
175#### 参数
176
177&emsp;&emsp;与{ref}`list_entry() <_list_entry>`相同
178
179### `list_last_entry_or_full(ptr, type, member)`
180
181#### 描述
182
183&emsp;&emsp;获取链表中的最后一个元素。若链表为空,则返回NULL。
184
185#### 参数
186
187&emsp;&emsp;与{ref}`list_entry() <_list_entry>`相同
188
189(_list_next_entry)=
190### `list_next_entry(pos, member)`
191
192#### 描述
193
194&emsp;&emsp;获取链表中的下一个元素
195
196#### 参数
197
198**pos**
199
200&emsp;&emsp;指向当前的外层结构体的指针
201
202**member**
203
204&emsp;&emsp;链表结构体在外层结构体内的变量名
205
206### `list_prev_entry(pos, member)`
207
208#### 描述
209
210&emsp;&emsp;获取链表中的上一个元素
211
212#### 参数
213
214&emsp;&emsp;与{ref}`list_next_entry() <_list_next_entry>`相同
215
216(_list_for_each)=
217### `list_for_each(ptr, head)`
218
219#### 描述
220
221&emsp;&emsp;遍历整个链表(从前往后)
222
223#### 参数
224
225**ptr**
226
227&emsp;&emsp;指向List结构体的指针
228
229**head**
230
231&emsp;&emsp;指向链表头结点的指针(struct List*)
232
233### `list_for_each_prev(ptr, head)`
234
235#### 描述
236
237&emsp;&emsp;遍历整个链表(从后往前)
238
239#### 参数
240
241&emsp;&emsp;与{ref}`list_for_each() <_list_for_each>`相同
242
243(_list_for_each_safe)=
244### `list_for_each_safe(ptr, n, head)`
245
246#### 描述
247
248&emsp;&emsp;从前往后遍历整个链表(支持删除当前链表结点)
249
250&emsp;&emsp;该宏通过暂存中间变量,防止在迭代链表的过程中,由于删除了当前ptr所指向的链表结点从而造成错误.
251
252#### 参数
253
254**ptr**
255
256&emsp;&emsp;指向List结构体的指针
257
258**n**
259
260&emsp;&emsp;用于存储临时值的List类型的指针
261
262**head**
263
264&emsp;&emsp;指向链表头结点的指针(struct List*)
265
266### `list_for_each_prev_safe(ptr, n, head)`
267
268#### 描述
269
270&emsp;&emsp;从后往前遍历整个链表.(支持删除当前链表结点)
271
272&emsp;&emsp;该宏通过暂存中间变量,防止在迭代链表的过程中,由于删除了当前ptr所指向的链表结点从而造成错误.
273
274#### 参数
275
276&emsp;&emsp;与{ref}`list_for_each_safe() <_list_for_each_safe>`相同
277
278(_list_for_each_entry)=
279### `list_for_each_entry(pos, head, member)`
280
281#### 描述
282
283&emsp;&emsp;从头开始迭代给定类型的链表
284
285#### 参数
286
287**pos**
288
289&emsp;&emsp;指向特定类型的结构体的指针
290
291**head**
292
293&emsp;&emsp;指向链表头结点的指针(struct List*)
294
295**member**
296
297&emsp;&emsp;struct List在pos的结构体中的成员变量名
298
299### `list_for_each_entry_reverse(pos, head, member)`
300
301#### 描述
302
303&emsp;&emsp;逆序迭代给定类型的链表
304
305#### 参数
306
307&emsp;&emsp;与{ref}`list_for_each_entry() <_list_for_each_entry>`相同
308
309### `list_for_each_entry_safe(pos, n, head, member)`
310
311#### 描述
312
313&emsp;&emsp;从头开始迭代给定类型的链表(支持删除当前链表结点)
314
315#### 参数
316
317**pos**
318
319&emsp;&emsp;指向特定类型的结构体的指针
320
321**n**
322
323&emsp;&emsp;用于存储临时值的,和pos相同类型的指针
324
325**head**
326
327&emsp;&emsp;指向链表头结点的指针(struct List*)
328
329**member**
330
331&emsp;&emsp;struct List在pos的结构体中的成员变量名
332
333### `list_prepare_entry(pos, head, member)`
334
335#### 描述
336
337&emsp;&emsp;为{ref}`list_for_each_entry_continue() <_list_for_each_entry_continue>`准备一个'pos'结构体
338
339#### 参数
340
341**pos**
342
343&emsp;&emsp;指向特定类型的结构体的,用作迭代起点的指针
344
345**head**
346
347&emsp;&emsp;指向要开始迭代的struct List结构体的指针
348
349**member**
350
351&emsp;&emsp;struct List在pos的结构体中的成员变量名
352
353(_list_for_each_entry_continue)=
354### `list_for_each_entry_continue(pos, head, member)`
355
356#### 描述
357
358&emsp;&emsp;从指定的位置的【下一个元素开始】,继续迭代给定的链表
359
360#### 参数
361
362**pos**
363
364&emsp;&emsp;指向特定类型的结构体的指针。该指针用作迭代的指针。
365
366**head**
367
368&emsp;&emsp;指向要开始迭代的struct List结构体的指针
369
370**member**
371
372&emsp;&emsp;struct List在pos的结构体中的成员变量名
373
374### `list_for_each_entry_continue_reverse(pos, head, member)`
375
376#### 描述
377
378&emsp;&emsp;从指定的位置的【上一个元素开始】,【逆序】迭代给定的链表
379
380#### 参数
381
382&emsp;&emsp;与{ref}`list_for_each_entry_continue() <_list_for_each_entry_continue>`的相同
383
384### `list_for_each_entry_from(pos, head, member)`
385
386#### 描述
387
388&emsp;&emsp;从指定的位置开始,继续迭代给定的链表
389
390#### 参数
391
392&emsp;&emsp;与{ref}`list_for_each_entry_continue() <_list_for_each_entry_continue>`的相同
393
394(_list_for_each_entry_safe_continue)=
395### `list_for_each_entry_safe_continue(pos, n, head, member)`
396
397#### 描述
398
399&emsp;&emsp;从指定的位置的【下一个元素开始】,继续迭代给定的链表.(支持删除当前链表结点)
400
401#### 参数
402
403**pos**
404
405&emsp;&emsp;指向特定类型的结构体的指针。该指针用作迭代的指针。
406
407**n**
408
409&emsp;&emsp;用于存储临时值的,和pos相同类型的指针
410
411**head**
412
413&emsp;&emsp;指向要开始迭代的struct List结构体的指针
414
415**member**
416
417&emsp;&emsp;struct List在pos的结构体中的成员变量名
418
419### `list_for_each_entry_safe_continue_reverse(pos, n, head, member)`
420
421#### 描述
422
423&emsp;&emsp;从指定的位置的【上一个元素开始】,【逆序】迭代给定的链表。(支持删除当前链表结点)
424
425#### 参数
426
427&emsp;&emsp;与{ref}`list_for_each_entry_safe_continue() <_list_for_each_entry_safe_continue>`的相同
428
429### `list_for_each_entry_safe_from(pos, n, head, member)`
430
431#### 描述
432
433&emsp;&emsp;从指定的位置开始,继续迭代给定的链表.(支持删除当前链表结点)
434
435#### 参数
436
437&emsp;&emsp;与{ref}`list_for_each_entry_safe_continue() <_list_for_each_entry_safe_continue>`的相同
438
439---
440
441## 基础C函数库
442
443&emsp;&emsp;内核编程与应用层编程不同,你将无法使用LibC中的函数来进行编程。为此,内核实现了一些常用的C语言函数,并尽量使其与标准C库中的函数行为相近。值得注意的是,这些函数的行为可能与标准C库函数不同,请在使用时仔细阅读以下文档,这将会为你带来帮助。
444
445### 字符串操作
446
447#### `int strlen(const char *s)`
448
449##### 描述
450
451&emsp;&emsp;测量并返回字符串长度。
452
453##### 参数
454
455**src**
456
457&emsp;&emsp;源字符串
458
459#### `long strnlen(const char *src, unsigned long maxlen)`
460
461##### 描述
462
463&emsp;&emsp;测量并返回字符串长度。当字符串长度大于maxlen时,返回maxlen
464
465##### 参数
466
467**src**
468
469&emsp;&emsp;源字符串
470
471**maxlen**
472
473&emsp;&emsp;最大长度
474
475#### `long strnlen_user(const char *src, unsigned long maxlen)`
476
477##### 描述
478
479&emsp;&emsp;测量并返回字符串长度。当字符串长度大于maxlen时,返回maxlen。
480
481&emsp;&emsp;该函数会进行地址空间校验,要求src字符串必须来自用户空间。当源字符串来自内核空间时,将返回0.
482
483##### 参数
484
485**src**
486
487&emsp;&emsp;源字符串,地址位于用户空间
488
489**maxlen**
490
491&emsp;&emsp;最大长度
492
493#### `char *strncpy(char *dst, const char *src, long count)`
494
495##### 描述
496
497&emsp;&emsp;拷贝长度为count个字节的字符串,返回dst字符串
498
499##### 参数
500
501**src**
502
503&emsp;&emsp;源字符串
504
505**dst**
506
507&emsp;&emsp;目标字符串
508
509**count**
510
511&emsp;&emsp;要拷贝的源字符串的长度
512
513#### `char *strcpy(char *dst, const char *src)`
514
515##### 描述
516
517&emsp;&emsp;拷贝源字符串,返回dst字符串
518
519##### 参数
520
521**src**
522
523&emsp;&emsp;源字符串
524
525**dst**
526
527&emsp;&emsp;目标字符串
528
529#### `long strncpy_from_user(char *dst, const char *src, unsigned long size)`
530
531##### 描述
532
533&emsp;&emsp;从用户空间拷贝长度为count个字节的字符串到内核空间,返回拷贝的字符串的大小
534
535&emsp;&emsp;该函数会对字符串的地址空间进行校验,防止出现地址空间越界的问题。
536
537##### 参数
538
539**src**
540
541&emsp;&emsp;源字符串
542
543**dst**
544
545&emsp;&emsp;目标字符串
546
547**size**
548
549&emsp;&emsp;要拷贝的源字符串的长度
550
551#### `int strcmp(char *FirstPart, char *SecondPart)`
552
553##### 描述
554
555  比较两个字符串的大小。
556
557***返回值***
558
559| 情况                      | 返回值 |
560| ----------------------- | --- |
561| FirstPart == SecondPart | 0   |
562| FirstPart > SecondPart  | 1   |
563| FirstPart < SecondPart  | -1  |
564
565##### 参数
566
567**FirstPart**
568
569&emsp;&emsp;第一个字符串
570
571**SecondPart**
572
573&emsp;&emsp;第二个字符串
574
575#### `printk(const char* fmt, ...)`
576
577##### 描述
578
579&emsp;&emsp;该宏能够在控制台上以黑底白字格式化输出字符串.
580
581##### 参数
582
583**fmt**
584
585&emsp;&emsp;源格式字符串
586
587**...**
588
589&emsp;&emsp;可变参数
590
591#### `printk_color(unsigned int FRcolor, unsigned int BKcolor, const char* fmt, ...)`
592
593##### 描述
594
595&emsp;&emsp;在控制台上以指定前景色和背景色格式化输出字符串.
596
597##### 参数
598
599**FRcolor**
600
601&emsp;&emsp;前景色
602
603**BKcolor**
604
605&emsp;&emsp;背景色
606
607**fmt**
608
609&emsp;&emsp;源格式字符串
610
611**...**
612
613&emsp;&emsp;可变参数
614
615#### `int vsprintf(char *buf, const char *fmt, va_list args)`
616
617##### 描述
618
619&emsp;&emsp;按照fmt格式化字符串,并将结果输出到buf中,返回写入buf的字符数量。
620
621##### 参数
622
623**buf**
624
625&emsp;&emsp;输出缓冲区
626
627**fmt**
628
629&emsp;&emsp;源格式字符串
630
631**args**
632
633&emsp;&emsp;可变参数列表
634
635#### `int sprintk(char *buf, const char *fmt, ...)`
636
637##### 描述
638
639&emsp;&emsp;按照fmt格式化字符串,并将结果输出到buf中,返回写入buf的字符数量。
640
641##### 参数
642
643**buf**
644
645&emsp;&emsp;输出缓冲区
646
647**fmt**
648
649&emsp;&emsp;源格式字符串
650
651**...**
652
653&emsp;&emsp;可变参数
654
655### 内存操作
656
657#### `void *memcpy(void *dst, const void *src, uint64_t size)`
658
659##### 描述
660
661&emsp;&emsp;将内存从src处拷贝到dst处。
662
663##### 参数
664
665**dst**
666
667&emsp;&emsp;指向目标地址的指针
668
669**src**
670
671&emsp;&emsp;指向源地址的指针
672
673**size**
674
675&emsp;&emsp;待拷贝的数据大小
676
677#### `void *memmove(void *dst, const void *src, uint64_t size)`
678
679##### 描述
680
681&emsp;&emsp;与`memcpy()`类似,但是在源数据区域与目标数据区域之间存在重合时,该函数能防止数据被错误的覆盖。
682
683##### 参数
684
685**dst**
686
687&emsp;&emsp;指向目标地址的指针
688
689**src**
690
691&emsp;&emsp;指向源地址的指针
692
693**size**
694
695&emsp;&emsp;待拷贝的数据大小
696
697## CRC函数
698
699### 函数列表
700
701**`uint8_t crc7(uint8_t crc, const uint8_t *buffer, size_t len)`**
702
703**`uint8_t crc8(uint8_t crc, const uint8_t *buffer, size_t len)`**
704
705**`uint16_t crc16(uint16_t crc, uint8_t const *buffer, size_t len)`**
706
707**`uint32_t crc32(uint32_t crc, uint8_t const *buffer, size_t len)`**
708
709**`uint64_t crc64(uint64_t crc, uint8_t const *buffer, size_t len)`**
710
711### 描述
712
713&emsp;&emsp;用于计算循环冗余校验码
714
715### 参数说明
716
717**crc**
718
719&emsp;&emsp;传入的CRC初始值
720
721**buffer**
722
723&emsp;&emsp;待处理的数据缓冲区
724
725**len**
726
727&emsp;&emsp;缓冲区大小(字节)
728
729