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  与{ref}`list_entry() <_list_entry>`相同 158 159### `list_first_entry_or_null(ptr, type, member)` 160 161#### 描述 162 163  获取链表中的第一个元素。若链表为空,则返回NULL。 164 165#### 参数 166 167  与{ref}`list_entry() <_list_entry>`相同 168 169### `list_last_entry(ptr, type, member)` 170 171#### 描述 172 173  获取链表中的最后一个元素。请注意,该宏要求链表非空,否则会出错。 174 175#### 参数 176 177  与{ref}`list_entry() <_list_entry>`相同 178 179### `list_last_entry_or_full(ptr, type, member)` 180 181#### 描述 182 183  获取链表中的最后一个元素。若链表为空,则返回NULL。 184 185#### 参数 186 187  与{ref}`list_entry() <_list_entry>`相同 188 189(_list_next_entry)= 190### `list_next_entry(pos, member)` 191 192#### 描述 193 194  获取链表中的下一个元素 195 196#### 参数 197 198**pos** 199 200  指向当前的外层结构体的指针 201 202**member** 203 204  链表结构体在外层结构体内的变量名 205 206### `list_prev_entry(pos, member)` 207 208#### 描述 209 210  获取链表中的上一个元素 211 212#### 参数 213 214  与{ref}`list_next_entry() <_list_next_entry>`相同 215 216(_list_for_each)= 217### `list_for_each(ptr, head)` 218 219#### 描述 220 221  遍历整个链表(从前往后) 222 223#### 参数 224 225**ptr** 226 227  指向List结构体的指针 228 229**head** 230 231  指向链表头结点的指针(struct List*) 232 233### `list_for_each_prev(ptr, head)` 234 235#### 描述 236 237  遍历整个链表(从后往前) 238 239#### 参数 240 241  与{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  从前往后遍历整个链表(支持删除当前链表结点) 249 250  该宏通过暂存中间变量,防止在迭代链表的过程中,由于删除了当前ptr所指向的链表结点从而造成错误. 251 252#### 参数 253 254**ptr** 255 256  指向List结构体的指针 257 258**n** 259 260  用于存储临时值的List类型的指针 261 262**head** 263 264  指向链表头结点的指针(struct List*) 265 266### `list_for_each_prev_safe(ptr, n, head)` 267 268#### 描述 269 270  从后往前遍历整个链表.(支持删除当前链表结点) 271 272  该宏通过暂存中间变量,防止在迭代链表的过程中,由于删除了当前ptr所指向的链表结点从而造成错误. 273 274#### 参数 275 276  与{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  从头开始迭代给定类型的链表 284 285#### 参数 286 287**pos** 288 289  指向特定类型的结构体的指针 290 291**head** 292 293  指向链表头结点的指针(struct List*) 294 295**member** 296 297  struct List在pos的结构体中的成员变量名 298 299### `list_for_each_entry_reverse(pos, head, member)` 300 301#### 描述 302 303  逆序迭代给定类型的链表 304 305#### 参数 306 307  与{ref}`list_for_each_entry() <_list_for_each_entry>`相同 308 309### `list_for_each_entry_safe(pos, n, head, member)` 310 311#### 描述 312 313  从头开始迭代给定类型的链表(支持删除当前链表结点) 314 315#### 参数 316 317**pos** 318 319  指向特定类型的结构体的指针 320 321**n** 322 323  用于存储临时值的,和pos相同类型的指针 324 325**head** 326 327  指向链表头结点的指针(struct List*) 328 329**member** 330 331  struct List在pos的结构体中的成员变量名 332 333### `list_prepare_entry(pos, head, member)` 334 335#### 描述 336 337  为{ref}`list_for_each_entry_continue() <_list_for_each_entry_continue>`准备一个'pos'结构体 338 339#### 参数 340 341**pos** 342 343  指向特定类型的结构体的,用作迭代起点的指针 344 345**head** 346 347  指向要开始迭代的struct List结构体的指针 348 349**member** 350 351  struct List在pos的结构体中的成员变量名 352 353(_list_for_each_entry_continue)= 354### `list_for_each_entry_continue(pos, head, member)` 355 356#### 描述 357 358  从指定的位置的【下一个元素开始】,继续迭代给定的链表 359 360#### 参数 361 362**pos** 363 364  指向特定类型的结构体的指针。该指针用作迭代的指针。 365 366**head** 367 368  指向要开始迭代的struct List结构体的指针 369 370**member** 371 372  struct List在pos的结构体中的成员变量名 373 374### `list_for_each_entry_continue_reverse(pos, head, member)` 375 376#### 描述 377 378  从指定的位置的【上一个元素开始】,【逆序】迭代给定的链表 379 380#### 参数 381 382  与{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  从指定的位置开始,继续迭代给定的链表 389 390#### 参数 391 392  与{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  从指定的位置的【下一个元素开始】,继续迭代给定的链表.(支持删除当前链表结点) 400 401#### 参数 402 403**pos** 404 405  指向特定类型的结构体的指针。该指针用作迭代的指针。 406 407**n** 408 409  用于存储临时值的,和pos相同类型的指针 410 411**head** 412 413  指向要开始迭代的struct List结构体的指针 414 415**member** 416 417  struct List在pos的结构体中的成员变量名 418 419### `list_for_each_entry_safe_continue_reverse(pos, n, head, member)` 420 421#### 描述 422 423  从指定的位置的【上一个元素开始】,【逆序】迭代给定的链表。(支持删除当前链表结点) 424 425#### 参数 426 427  与{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  从指定的位置开始,继续迭代给定的链表.(支持删除当前链表结点) 434 435#### 参数 436 437  与{ref}`list_for_each_entry_safe_continue() <_list_for_each_entry_safe_continue>`的相同 438 439--- 440 441## 基础C函数库 442 443  内核编程与应用层编程不同,你将无法使用LibC中的函数来进行编程。为此,内核实现了一些常用的C语言函数,并尽量使其与标准C库中的函数行为相近。值得注意的是,这些函数的行为可能与标准C库函数不同,请在使用时仔细阅读以下文档,这将会为你带来帮助。 444 445### 字符串操作 446 447#### `int strlen(const char *s)` 448 449##### 描述 450 451  测量并返回字符串长度。 452 453##### 参数 454 455**src** 456 457  源字符串 458 459#### `long strnlen(const char *src, unsigned long maxlen)` 460 461##### 描述 462 463  测量并返回字符串长度。当字符串长度大于maxlen时,返回maxlen 464 465##### 参数 466 467**src** 468 469  源字符串 470 471**maxlen** 472 473  最大长度 474 475#### `long strnlen_user(const char *src, unsigned long maxlen)` 476 477##### 描述 478 479  测量并返回字符串长度。当字符串长度大于maxlen时,返回maxlen。 480 481  该函数会进行地址空间校验,要求src字符串必须来自用户空间。当源字符串来自内核空间时,将返回0. 482 483##### 参数 484 485**src** 486 487  源字符串,地址位于用户空间 488 489**maxlen** 490 491  最大长度 492 493#### `char *strncpy(char *dst, const char *src, long count)` 494 495##### 描述 496 497  拷贝长度为count个字节的字符串,返回dst字符串 498 499##### 参数 500 501**src** 502 503  源字符串 504 505**dst** 506 507  目标字符串 508 509**count** 510 511  要拷贝的源字符串的长度 512 513#### `char *strcpy(char *dst, const char *src)` 514 515##### 描述 516 517  拷贝源字符串,返回dst字符串 518 519##### 参数 520 521**src** 522 523  源字符串 524 525**dst** 526 527  目标字符串 528 529#### `long strncpy_from_user(char *dst, const char *src, unsigned long size)` 530 531##### 描述 532 533  从用户空间拷贝长度为count个字节的字符串到内核空间,返回拷贝的字符串的大小 534 535  该函数会对字符串的地址空间进行校验,防止出现地址空间越界的问题。 536 537##### 参数 538 539**src** 540 541  源字符串 542 543**dst** 544 545  目标字符串 546 547**size** 548 549  要拷贝的源字符串的长度 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  第一个字符串 570 571**SecondPart** 572 573  第二个字符串 574 575#### `printk(const char* fmt, ...)` 576 577##### 描述 578 579  该宏能够在控制台上以黑底白字格式化输出字符串. 580 581##### 参数 582 583**fmt** 584 585  源格式字符串 586 587**...** 588 589  可变参数 590 591#### `printk_color(unsigned int FRcolor, unsigned int BKcolor, const char* fmt, ...)` 592 593##### 描述 594 595  在控制台上以指定前景色和背景色格式化输出字符串. 596 597##### 参数 598 599**FRcolor** 600 601  前景色 602 603**BKcolor** 604 605  背景色 606 607**fmt** 608 609  源格式字符串 610 611**...** 612 613  可变参数 614 615#### `int vsprintf(char *buf, const char *fmt, va_list args)` 616 617##### 描述 618 619  按照fmt格式化字符串,并将结果输出到buf中,返回写入buf的字符数量。 620 621##### 参数 622 623**buf** 624 625  输出缓冲区 626 627**fmt** 628 629  源格式字符串 630 631**args** 632 633  可变参数列表 634 635#### `int sprintk(char *buf, const char *fmt, ...)` 636 637##### 描述 638 639  按照fmt格式化字符串,并将结果输出到buf中,返回写入buf的字符数量。 640 641##### 参数 642 643**buf** 644 645  输出缓冲区 646 647**fmt** 648 649  源格式字符串 650 651**...** 652 653  可变参数 654 655### 内存操作 656 657#### `void *memcpy(void *dst, const void *src, uint64_t size)` 658 659##### 描述 660 661  将内存从src处拷贝到dst处。 662 663##### 参数 664 665**dst** 666 667  指向目标地址的指针 668 669**src** 670 671  指向源地址的指针 672 673**size** 674 675  待拷贝的数据大小 676 677#### `void *memmove(void *dst, const void *src, uint64_t size)` 678 679##### 描述 680 681  与`memcpy()`类似,但是在源数据区域与目标数据区域之间存在重合时,该函数能防止数据被错误的覆盖。 682 683##### 参数 684 685**dst** 686 687  指向目标地址的指针 688 689**src** 690 691  指向源地址的指针 692 693**size** 694 695  待拷贝的数据大小 696