mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-08 18:26:48 +00:00
🆕 用户/内核内存拷贝函数
This commit is contained in:
parent
5f24cd56fe
commit
59cbd6c4fc
@ -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. */
|
@ -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;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user