From 59cbd6c4fcaa173a6a059e8ff8b30c50e74c4776 Mon Sep 17 00:00:00 2001 From: fslongjin Date: Fri, 22 Apr 2022 23:40:27 +0800 Subject: [PATCH] =?UTF-8?q?:new:=20=E7=94=A8=E6=88=B7/=E5=86=85=E6=A0=B8?= =?UTF-8?q?=E5=86=85=E5=AD=98=E6=8B=B7=E8=B4=9D=E5=87=BD=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/common/errno.h | 8 +++ kernel/common/glib.h | 156 ++++++++++++++++++++++++++++++------------ 2 files changed, 122 insertions(+), 42 deletions(-) diff --git a/kernel/common/errno.h b/kernel/common/errno.h index 4005e521..a1ebef05 100644 --- a/kernel/common/errno.h +++ b/kernel/common/errno.h @@ -19,6 +19,7 @@ #define EALREADY 7 /* 连接已经在处理 Connection already in progress. */ #define EBADF 8 /* 错误的文件描述符 Bad file descriptor. */ #define EBADMSG 9 /* 错误的消息 Bad message. */ + #define EBUSY 10 /* 设备或资源忙 Device or resource busy. */ #define ECANCELED 11 /* 操作被取消 Operation canceled. */ #define ECHILD 12 /* 没有子进程 No child processes. */ @@ -29,6 +30,7 @@ #define EDESTADDRREQ 17 /* 需要目标地址 Destination address required.*/ #define EDOM 18 /* 数学参数超出作用域 Mathematics argument out of domain of function. */ #define EDQUOT 19 /* 保留使用 Reserved */ + #define EEXIST 20 /* 文件已存在 File exists. */ #define EFAULT 21 /* 错误的地址 Bad address */ #define EFBIG 22 /* 文件太大 File too large. */ @@ -39,6 +41,7 @@ #define EINTR 27 /* 被中断的函数 Interrupted function. */ #define EINVAL 28 /* 不可用的参数 Invalid argument. */ #define EIO 29 /* I/O错误 I/O error. */ + #define EISCONN 30 /* 套接字已连接 Socket is connected. */ #define EISDIR 31 /* 是一个目录 Is a directory */ #define ELOOP 32 /* 符号链接级别过多 Too many levels of symbolic links. */ @@ -49,6 +52,7 @@ #define ENAMETOOLONG 37 /* 文件名过长 Filename too long. */ #define ENETDOWN 38 /* 网络已关闭 Network is down. */ #define ENETRESET 39 /* 网络连接已断开 Connection aborted by network. */ + #define ENETUNREACH 40 /* 网络不可达 Network unreachable. */ #define ENFILE 41 /* 系统中打开的文件过多 Too many files open in system.*/ #define ENOBUFS 42 /* 缓冲区空间不足 No buffer space available. */ @@ -59,6 +63,7 @@ #define ENOLCK 47 /* 没有可用的锁 No locks available. */ #define ENOLINK 48 /* 保留 Reserved. */ #define ENOMEM 49 /* 没有足够的空间 Not enough space. */ + #define ENOMSG 50 /* 没有期待类型的消息 No message of the desired type. */ #define ENOPROTOOPT 51 /* 协议不可用 Protocol not available. */ #define ENOSPC 52 /* 设备上没有空间 No space left on device. */ @@ -69,6 +74,7 @@ #define ENOTDIR 57 /* 不是目录 Not a directory. */ #define ENOTEMPTY 58 /* 目录非空 Directory not empty. */ #define ENOTRECOVERABLE 59 /* 状态不可覆盖 State not recoverable. */ + #define ENOTSOCK 60 /* 不是一个套接字 Not a socket.*/ #define ENOTSUP 61 /* 不被支持 Not supported (may be the same value as [EOPNOTSUPP]). */ #define ENOTTY 62 /* 不正确的I/O控制操作 Inappropriate I/O control operation. */ @@ -79,6 +85,7 @@ #define EPERM 67 /* 操作不被允许 Operation not permitted. */ #define EPIPE 68 /* 断开的管道 Broken pipe. */ #define EPROTO 69 /* 协议错误 Protocol error. */ + #define EPROTONOSUPPORT 70 /* 协议不被支持 Protocol not supported. */ #define EPROTOTYPE 71 /* 对于套接字而言,错误的协议 Protocol wrong type for socket. */ #define ERANGE 72 /* 结果过大 Result too large. */ @@ -89,5 +96,6 @@ #define ETIME 77 /* 流式ioctl()超时 Stream ioctl() timeout */ #define ETIMEDOUT 78 /* 连接超时 Connection timed out.*/ #define ETXTBSY 79 /* 文本文件忙 Text file busy. */ + #define EWOULDBLOCK 80 /* 操作将被禁止 Operation would block (may be the same value as [EAGAIN]). */ #define EXDEV 81 /* 跨设备连接 Cross-device link. */ \ No newline at end of file diff --git a/kernel/common/glib.h b/kernel/common/glib.h index 6fa95fa1..0ae7c448 100644 --- a/kernel/common/glib.h +++ b/kernel/common/glib.h @@ -17,7 +17,7 @@ : "memory") //关闭外部中断 #define nop() __asm__ __volatile__("nop\n\t") #define hlt() __asm__ __volatile__("hlt\n\t") -#define pause() asm volatile ("pause\n\t"); // 处理器等待一段时间 +#define pause() asm volatile("pause\n\t"); // 处理器等待一段时间 //内存屏障 #define io_mfence() __asm__ __volatile__("mfence\n\t" :: \ @@ -123,7 +123,7 @@ static inline void list_del(struct List *entry) */ entry->next->prev = entry->prev; - entry->prev->next = entry->next; + entry->prev->next = entry->next; } static inline bool list_empty(struct List *entry) @@ -133,7 +133,7 @@ static inline bool list_empty(struct List *entry) * @param entry 入口 */ - if(entry == entry->next && entry->prev == entry) + if (entry == entry->next && entry->prev == entry) return true; else return false; @@ -210,7 +210,7 @@ void *memset(void *dst, unsigned char C, ul size) * @param Num 字节数 * @return void* */ -void *memcpy(void *dst, void *src, long Num) +static inline void *memcpy(void *dst, void *src, long Num) { int d0, d1, d2; __asm__ __volatile__("cld \n\t" @@ -233,34 +233,33 @@ void *memcpy(void *dst, void *src, long Num) } /* - 比较字符串 FirstPart and SecondPart - FirstPart = SecondPart => 0 - FirstPart > SecondPart => 1 - FirstPart < SecondPart => -1 + 比较字符串 FirstPart and SecondPart + FirstPart = SecondPart => 0 + FirstPart > SecondPart => 1 + FirstPart < SecondPart => -1 */ -int strcmp(char * FirstPart,char * SecondPart) +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; + 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; } void *memset_c(void *dst, unsigned char c, ul n) @@ -317,17 +316,19 @@ void io_out32(unsigned short port, unsigned int value) /** * @brief 从端口读入n个word到buffer - * + * */ -#define io_insw(port,buffer,nr) \ -__asm__ __volatile__("cld;rep;insw;mfence;"::"d"(port),"D"(buffer),"c"(nr):"memory") +#define io_insw(port, buffer, nr) \ + __asm__ __volatile__("cld;rep;insw;mfence;" ::"d"(port), "D"(buffer), "c"(nr) \ + : "memory") /** * @brief 从输出buffer中的n个word到端口 - * + * */ -#define io_outsw(port,buffer,nr) \ -__asm__ __volatile__("cld;rep;outsw;mfence;"::"d"(port),"S"(buffer),"c"(nr):"memory") +#define io_outsw(port, buffer, nr) \ + __asm__ __volatile__("cld;rep;outsw;mfence;" ::"d"(port), "S"(buffer), "c"(nr) \ + : "memory") /** * @brief 读取rsp寄存器的值(存储了页目录的基地址) @@ -427,13 +428,84 @@ ul rdmsr(ul address) return ((ul)tmp0 << 32) | tmp1; } - uint64_t get_rflags() { - unsigned long tmp = 0; - __asm__ __volatile__ ("pushfq \n\t" - "movq (%%rsp), %0 \n\t" - "popfq \n\t" - :"=r"(tmp)::"memory"); - return tmp; + unsigned long tmp = 0; + __asm__ __volatile__("pushfq \n\t" + "movq (%%rsp), %0 \n\t" + "popfq \n\t" + : "=r"(tmp)::"memory"); + return tmp; +} + +/** + * @brief 验证地址空间是否为用户地址空间 + * + * @param addr_start 地址起始值 + * @param length 地址长度 + * @return true + * @return false + */ +bool verify_area(uint64_t addr_start, uint64_t length) +{ + if ((addr_start + length) <= 0x00007fffffffffffUL) // 用户程序可用的的地址空间应<= 0x00007fffffffffffUL + return true; + else + return false; +} + +/** + * @brief 从用户空间搬运数据到内核空间 + * + * @param dst 目的地址 + * @param src 源地址 + * @param size 搬运的大小 + * @return uint64_t + */ +static inline uint64_t copy_from_user(void *dst, void *src, uint64_t size) +{ + uint64_t tmp0, tmp1; + if (!verify_area((uint64_t)src, size)) + return 0; + + /** + * @brief 先每次搬运8 bytes,剩余就直接一个个byte搬运 + * + */ + asm volatile("rep \n\t" + "movsq \n\t" + "movq %3, %0 \n\t" + "rep \n\t" + "movsb \n\t" + : "=&c"(size), "=&D"(tmp0), "=&S"(tmp1) + : "r"(size & 7), "0"(size >> 3), "1"(dst), "2"(src)); + return size; +} + +/** + * @brief 从内核空间搬运数据到用户空间 + * + * @param dst 目的地址 + * @param src 源地址 + * @param size 搬运的大小 + * @return uint64_t + */ +static inline uint64_t copy_to_user(void *dst, void *src, uint64_t size) +{ + uint64_t tmp0, tmp1; + if (verify_area((uint64_t)src, size)) + return 0; + + /** + * @brief 先每次搬运8 bytes,剩余就直接一个个byte搬运 + * + */ + asm volatile("rep \n\t" + "movsq \n\t" + "movq %3, %0 \n\t" + "rep \n\t" + "movsb \n\t" + : "=&c"(size), "=&D"(tmp0), "=&S"(tmp1) + : "r"(size & 7), "0"(size >> 3), "1"(dst), "2"(src)); + return size; } \ No newline at end of file