From d9ee6ea859b3373778f1bcda953bd97065cfcff4 Mon Sep 17 00:00:00 2001 From: fslongjin Date: Wed, 3 Aug 2022 15:13:01 +0800 Subject: [PATCH] new: string.h --- docs/kernel/core_api/kernel_api.md | 16 +++++ kernel/common/Makefile | 7 +- kernel/common/bitree.c | 3 +- kernel/common/glib.c | 30 +------- kernel/common/glib.h | 88 ----------------------- kernel/common/printk.c | 1 + kernel/common/string.c | 109 +++++++++++++++++++++++++++++ kernel/common/string.h | 53 ++++++++++++++ kernel/exception/irq.c | 1 + kernel/filesystem/VFS/VFS.c | 1 + kernel/process/process.c | 1 + kernel/syscall/syscall.c | 1 + 12 files changed, 191 insertions(+), 120 deletions(-) create mode 100644 kernel/common/string.c create mode 100644 kernel/common/string.h diff --git a/docs/kernel/core_api/kernel_api.md b/docs/kernel/core_api/kernel_api.md index 30f82927..a80a5e38 100644 --- a/docs/kernel/core_api/kernel_api.md +++ b/docs/kernel/core_api/kernel_api.md @@ -170,6 +170,22 @@   要拷贝的源字符串的长度 +#### `char *strcpy(char *dst, const char *src)` + +##### 描述 + +  拷贝源字符串,返回dst字符串 + +##### 参数 + +**src** + +  源字符串 + +**dst** + +  目标字符串 + #### `long strncpy_from_user(char *dst, const char *src, unsigned long size)` ##### 描述 diff --git a/kernel/common/Makefile b/kernel/common/Makefile index 90971214..63c0e225 100644 --- a/kernel/common/Makefile +++ b/kernel/common/Makefile @@ -10,7 +10,7 @@ $(kernel_common_subdirs): ECHO $(MAKE) -C $@ all CFLAGS="$(CFLAGS)" ASFLAGS="$(ASFLAGS)" PIC="$(PIC)" -all: glib.o printk.o cpu.o bitree.o kfifo.o wait_queue.o mutex.o wait.o unistd.o $(kernel_common_subdirs) +all: glib.o printk.o cpu.o bitree.o kfifo.o wait_queue.o mutex.o wait.o unistd.o string.o $(kernel_common_subdirs) glib.o: glib.c @@ -38,4 +38,7 @@ wait.o: sys/wait.c gcc $(CFLAGS) -c sys/wait.c -o sys/wait.o unistd.o: unistd.c - gcc $(CFLAGS) -c unistd.c -o unistd.o \ No newline at end of file + gcc $(CFLAGS) -c unistd.c -o unistd.o + +string.o: string.c + gcc $(CFLAGS) -c string.c -o string.o diff --git a/kernel/common/bitree.c b/kernel/common/bitree.c index 6df9b541..bcb21e18 100644 --- a/kernel/common/bitree.c +++ b/kernel/common/bitree.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #define smaller(root, a, b) (root->cmp((a)->value, (b)->value) == -1) @@ -19,7 +20,7 @@ struct bt_root_t *bt_create_tree(struct bt_node_t *node, int (*cmp)(void *a, void *b), int (*release)(void *value)) { if (node == NULL || cmp == NULL) - return -EINVAL; + return (void*)-EINVAL; struct bt_root_t *root = (struct bt_root_t *)kmalloc(sizeof(struct bt_root_t), 0); memset((void *)root, 0, sizeof(struct bt_root_t)); diff --git a/kernel/common/glib.c b/kernel/common/glib.c index 433adbcf..e5ae7aa3 100644 --- a/kernel/common/glib.c +++ b/kernel/common/glib.c @@ -1,31 +1,3 @@ #include "glib.h" +#include "string.h" -/** - * @brief 测量来自用户空间的字符串的长度,会检验地址空间是否属于用户空间 - * @param src - * @param maxlen - * @return long - */ -long strnlen_user(const char *src, unsigned long maxlen) -{ - - unsigned long size = strlen(src); - // 地址不合法 - if (!verify_area((uint64_t)src, size)) - return 0; - - return size <= maxlen ? size : maxlen; -} - -long strnlen(const char *src, unsigned long maxlen) -{ - - if (src == NULL) - return 0; - register int __res = 0; - while (src[__res] != '\0' && __res < maxlen) - { - ++__res; - } - return __res; -} \ No newline at end of file diff --git a/kernel/common/glib.h b/kernel/common/glib.h index 1a79076f..86292f5c 100644 --- a/kernel/common/glib.h +++ b/kernel/common/glib.h @@ -179,28 +179,6 @@ static inline struct List *list_next(struct List *entry) return NULL; } -//计算字符串的长度(经过测试,该版本比采用repne/scasb汇编的运行速度快16.8%左右) -static inline int strlen(const char *s) -{ - if (s == NULL) - return 0; - register int __res = 0; - while (s[__res] != '\0') - { - ++__res; - } - return __res; -} - -/** - * @brief 测量字符串的长度 - * - * @param src 字符串 - * @param maxlen 最大长度 - * @return long - */ -long strnlen(const char *src, unsigned long maxlen); - void *memset(void *dst, unsigned char C, ul size) { @@ -265,36 +243,6 @@ static void *memcpy(void *dst, const void *src, long Num) return dst; } -/* - 比较字符串 FirstPart and SecondPart - FirstPart = SecondPart => 0 - FirstPart > SecondPart => 1 - FirstPart < SecondPart => -1 -*/ - -int strcmp(char *FirstPart, char *SecondPart) -{ - register int __res; - __asm__ __volatile__("cld \n\t" - "1: \n\t" - "lodsb \n\t" - "scasb \n\t" - "jne 2f \n\t" - "testb %%al, %%al \n\t" - "jne 1b \n\t" - "xorl %%eax, %%eax \n\t" - "jmp 3f \n\t" - "2: \n\t" - "movl $1, %%eax \n\t" - "jl 3f \n\t" - "negl %%eax \n\t" - "3: \n\t" - : "=a"(__res) - : "D"(FirstPart), "S"(SecondPart) - :); - return __res; -} - // 从io口读入8个bit unsigned char io_in8(unsigned short port) { @@ -536,39 +484,3 @@ static inline uint64_t copy_to_user(void *dst, void *src, uint64_t size) : "memory"); return size; } - -/** - * @brief 测量来自用户空间的字符串的长度,会检验地址空间是否属于用户空间 - * @param src - * @param maxlen - * @return long - */ -long strnlen_user(const char *src, unsigned long maxlen); - -char *strncpy(char *dst, const char *src, long count) -{ - __asm__ __volatile__("cld \n\t" - "1: \n\t" - "decq %2 \n\t" - "js 2f \n\t" - "lodsb \n\t" - "stosb \n\t" - "testb %%al, %%al \n\t" - "jne 1b \n\t" - "rep \n\t" - "stosb \n\t" - "2: \n\t" - : - : "S"(src), "D"(dst), "c"(count) - : "ax", "memory"); - return dst; -} - -long strncpy_from_user(char *dst, const char *src, unsigned long size) -{ - if (!verify_area((uint64_t)src, size)) - return 0; - - strncpy(dst, src, size); - return size; -} \ No newline at end of file diff --git a/kernel/common/printk.c b/kernel/common/printk.c index a2414a80..fb0a32be 100644 --- a/kernel/common/printk.c +++ b/kernel/common/printk.c @@ -10,6 +10,7 @@ #include #include #include "math.h" +#include struct printk_screen_info pos; extern ul VBE_FB_phys_addr; // 由bootloader传来的帧缓存区的物理地址 diff --git a/kernel/common/string.c b/kernel/common/string.c new file mode 100644 index 00000000..15d240f3 --- /dev/null +++ b/kernel/common/string.c @@ -0,0 +1,109 @@ +#include "string.h" +#include "glib.h" + +/** + * @brief 拷贝整个字符串 + * + * @param dst 目标地址 + * @param src 源地址 + * @return char* 目标字符串 + */ +char *strcpy(char *dst, const char *src) +{ + while (*src) + { + *(dst++) = *(src++); + } + *dst = 0; + + return dst; +} + +long strnlen(const char *src, unsigned long maxlen) +{ + + if (src == NULL) + return 0; + register int __res = 0; + while (src[__res] != '\0' && __res < maxlen) + { + ++__res; + } + return __res; +} + +/* + 比较字符串 FirstPart and SecondPart + FirstPart = SecondPart => 0 + FirstPart > SecondPart => 1 + FirstPart < SecondPart => -1 +*/ + +int strcmp(char *FirstPart, char *SecondPart) +{ + register int __res; + __asm__ __volatile__("cld \n\t" + "1: \n\t" + "lodsb \n\t" + "scasb \n\t" + "jne 2f \n\t" + "testb %%al, %%al \n\t" + "jne 1b \n\t" + "xorl %%eax, %%eax \n\t" + "jmp 3f \n\t" + "2: \n\t" + "movl $1, %%eax \n\t" + "jl 3f \n\t" + "negl %%eax \n\t" + "3: \n\t" + : "=a"(__res) + : "D"(FirstPart), "S"(SecondPart) + :); + return __res; +} + +char *strncpy(char *dst, const char *src, long count) +{ + __asm__ __volatile__("cld \n\t" + "1: \n\t" + "decq %2 \n\t" + "js 2f \n\t" + "lodsb \n\t" + "stosb \n\t" + "testb %%al, %%al \n\t" + "jne 1b \n\t" + "rep \n\t" + "stosb \n\t" + "2: \n\t" + : + : "S"(src), "D"(dst), "c"(count) + : "ax", "memory"); + return dst; +} + +long strncpy_from_user(char *dst, const char *src, unsigned long size) +{ + if (!verify_area((uint64_t)src, size)) + return 0; + + strncpy(dst, src, size); + return size; +} + +/** + * @brief 测量来自用户空间的字符串的长度,会检验地址空间是否属于用户空间 + * @param src + * @param maxlen + * @return long + */ +long strnlen_user(const char *src, unsigned long maxlen) +{ + + unsigned long size = strlen(src); + // 地址不合法 + if (!verify_area((uint64_t)src, size)) + return 0; + + return size <= maxlen ? size : maxlen; +} + diff --git a/kernel/common/string.h b/kernel/common/string.h new file mode 100644 index 00000000..1f3244bb --- /dev/null +++ b/kernel/common/string.h @@ -0,0 +1,53 @@ +#pragma once +#include "glib.h" +/** + * @brief 拷贝整个字符串 + * + * @param dst 目标地址 + * @param src 源地址 + * @return char* 目标字符串 + */ +char *strcpy(char *dst, const char *src); + +//计算字符串的长度(经过测试,该版本比采用repne/scasb汇编的运行速度快16.8%左右) +static inline int strlen(const char *s) +{ + if (s == NULL) + return 0; + register int __res = 0; + while (s[__res] != '\0') + { + ++__res; + } + return __res; +} + +/** + * @brief 测量字符串的长度 + * + * @param src 字符串 + * @param maxlen 最大长度 + * @return long + */ +long strnlen(const char *src, unsigned long maxlen); + +/* + 比较字符串 FirstPart and SecondPart + FirstPart = SecondPart => 0 + FirstPart > SecondPart => 1 + FirstPart < SecondPart => -1 +*/ + +int strcmp(char *FirstPart, char *SecondPart); + +char *strncpy(char *dst, const char *src, long count); + +long strncpy_from_user(char *dst, const char *src, unsigned long size); + +/** + * @brief 测量来自用户空间的字符串的长度,会检验地址空间是否属于用户空间 + * @param src + * @param maxlen + * @return long + */ +long strnlen_user(const char *src, unsigned long maxlen); diff --git a/kernel/exception/irq.c b/kernel/exception/irq.c index 685249ee..3c134ae2 100644 --- a/kernel/exception/irq.c +++ b/kernel/exception/irq.c @@ -11,6 +11,7 @@ #include #include +#include #include "gate.h" #include diff --git a/kernel/filesystem/VFS/VFS.c b/kernel/filesystem/VFS/VFS.c index db6bee88..7bb809da 100644 --- a/kernel/filesystem/VFS/VFS.c +++ b/kernel/filesystem/VFS/VFS.c @@ -1,6 +1,7 @@ #include "VFS.h" #include #include +#include #include #include #include diff --git a/kernel/process/process.c b/kernel/process/process.c index 60fe0041..638da4a5 100644 --- a/kernel/process/process.c +++ b/kernel/process/process.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include diff --git a/kernel/syscall/syscall.c b/kernel/syscall/syscall.c index bb6e25a1..5a18ec1b 100644 --- a/kernel/syscall/syscall.c +++ b/kernel/syscall/syscall.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include