🆕 cd命令

This commit is contained in:
fslongjin
2022-05-25 22:50:32 +08:00
parent 8bd7b64a0b
commit 37669ebf87
15 changed files with 443 additions and 94 deletions

View File

@ -5,7 +5,7 @@ CFLAGS += -I .
libc_sub_dirs=math
libc: unistd.o fcntl.o malloc.o errno.o printf.o stdlib.o ctype.o
libc: unistd.o fcntl.o malloc.o errno.o printf.o stdlib.o ctype.o string.o
@list='$(libc_sub_dirs)'; for subdir in $$list; do \
echo "make all in $$subdir";\
cd $$subdir;\
@ -32,4 +32,7 @@ stdlib.o: stdlib.c
gcc $(CFLAGS) -c stdlib.c -o stdlib.o
ctype.o: ctype.c
gcc $(CFLAGS) -c ctype.c -o ctype.o
gcc $(CFLAGS) -c ctype.c -o ctype.o
string.o: string.c
gcc $(CFLAGS) -c string.c -o string.o

View File

@ -268,7 +268,7 @@ static void malloc_insert_free_list(malloc_mem_chunk_t *ck)
*/
void *malloc(ssize_t size)
{
// printf("malloc\n");
// 计算需要分配的块的大小
if (size + sizeof(uint64_t) <= sizeof(malloc_mem_chunk_t))
size = sizeof(malloc_mem_chunk_t);
@ -281,6 +281,7 @@ void *malloc(ssize_t size)
if (ck == NULL) // 没有空闲块
{
// printf("no free blocks\n");
// 尝试合并空闲块
malloc_merge_free_chunk();
ck = malloc_query_free_chunk_bf(size);
@ -288,10 +289,12 @@ void *malloc(ssize_t size)
// 找到了合适的块
if (ck)
goto found;
// printf("before enlarge\n");
// 找不到合适的块,扩容堆区域
if (malloc_enlarge(size) == -ENOMEM)
return (void *)-ENOMEM; // 内存不足
malloc_merge_free_chunk(); // 扩容后运行合并,否则会导致碎片
@ -304,6 +307,7 @@ found:;
// printf("ck = %#018lx\n", (uint64_t)ck);
if (ck == NULL)
return (void *)-ENOMEM;
// printf("ck->prev=%#018lx ck->next=%#018lx\n", ck->prev, ck->next);
// 分配空闲块
// 从空闲链表取出
if (ck->prev == NULL) // 当前是链表的第一个块
@ -321,6 +325,7 @@ found:;
// 当前块剩余的空间还能容纳多一个结点的空间,则分裂当前块
if ((int64_t)(ck->length) - size > sizeof(malloc_mem_chunk_t))
{
// printf("seperate\n");
malloc_mem_chunk_t *new_ck = (malloc_mem_chunk_t *)(((uint64_t)ck) + size);
new_ck->length = ck->length - size;
new_ck->prev = new_ck->next = NULL;
@ -328,7 +333,7 @@ found:;
ck->length = size;
malloc_insert_free_list(new_ck);
}
// printf("malloc done: %#018lx, length=%#018lx\n", ((uint64_t)ck + sizeof(uint64_t)), ck->length);
// 此时链表结点的指针的空间被分配出去
return (void *)((uint64_t)ck + sizeof(uint64_t));
}
@ -367,13 +372,13 @@ static void release_brk()
*
* @param ptr 堆内存的指针
*/
void free(void *ptr)
void free(void *ptr)
{
// 找到结点此时prev和next都处于未初始化的状态
malloc_mem_chunk_t *ck = (malloc_mem_chunk_t *)((uint64_t)ptr - sizeof(uint64_t));
// printf("free(): addr = %#018lx\t len=%#018lx\n", (uint64_t)ck, ck->length);
count_last_free_size += ck->length;
malloc_insert_free_list(ck);
if (count_last_free_size > PAGE_2M_SIZE)

109
user/libs/libc/string.c Normal file
View File

@ -0,0 +1,109 @@
#include "string.h"
size_t strlen(const char *s)
{
register int __res = 0;
while (s[__res] != '\0')
{
++__res;
}
return __res;
}
int strcmp(const char *FirstPart, const 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;
}
void *memset(void *dst, unsigned char C, uint64_t size)
{
int d0, d1;
unsigned long tmp = C * 0x0101010101010101UL;
__asm__ __volatile__("cld \n\t"
"rep \n\t"
"stosq \n\t"
"testb $4, %b3 \n\t"
"je 1f \n\t"
"stosl \n\t"
"1:\ttestb $2, %b3 \n\t"
"je 2f\n\t"
"stosw \n\t"
"2:\ttestb $1, %b3 \n\t"
"je 3f \n\t"
"stosb \n\t"
"3: \n\t"
: "=&c"(d0), "=&D"(d1)
: "a"(tmp), "q"(size), "0"(size / 8), "1"(dst)
: "memory");
return dst;
}
/**
* @brief 拷贝指定字节数的字符串
*
* @param dst 目标地址
* @param src 源字符串
* @param Count 字节数
* @return char*
*/
char *strncpy(char *dst, 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;
}
/**
* @brief 拼接两个字符串将src接到dest末尾
*
* @param dest 目标串
* @param src 源串
* @return char*
*/
char *strcat(char *dest, const char *src)
{
unsigned int dest_size = strlen(dest);
unsigned int src_size = strlen(src);
char *d = dest;
for (size_t i = 0; i < src_size; i++)
{
d[dest_size + i] = src[i];
}
d[dest_size + src_size] = '\0';
return dest;
}

View File

@ -2,40 +2,14 @@
#include <libc/sys/types.h>
void *memset(void *dst, unsigned char C, uint64_t size)
{
int d0, d1;
unsigned long tmp = C * 0x0101010101010101UL;
__asm__ __volatile__("cld \n\t"
"rep \n\t"
"stosq \n\t"
"testb $4, %b3 \n\t"
"je 1f \n\t"
"stosl \n\t"
"1:\ttestb $2, %b3 \n\t"
"je 2f\n\t"
"stosw \n\t"
"2:\ttestb $1, %b3 \n\t"
"je 3f \n\t"
"stosb \n\t"
"3: \n\t"
: "=&c"(d0), "=&D"(d1)
: "a"(tmp), "q"(size), "0"(size / 8), "1"(dst)
: "memory");
return dst;
}
size_t strlen(const char *s)
{
register size_t __res = 0;
while (s[__res] != '\0')
{
++__res;
}
return __res;
}
void *memset(void *dst, unsigned char C, uint64_t size);
/**
* @brief 获取字符串的大小
*
* @param s 字符串
* @return size_t 大小
*/
size_t strlen(const char *s);
/*
比较字符串 FirstPart and SecondPart
@ -44,25 +18,23 @@ size_t strlen(const char *s)
FirstPart < SecondPart => -1
*/
int strcmp(const char *FirstPart, const 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;
}
int strcmp(const char *FirstPart, const char *SecondPart);
/**
* @brief 拷贝指定字节数的字符串
*
* @param dst 目标地址
* @param src 源字符串
* @param Count 字节数
* @return char*
*/
char *strncpy(char *dst, char *src, long Count);
/**
* @brief 拼接两个字符串将src接到dest末尾
*
* @param dest 目标串
* @param src 源串
* @return char*
*/
char *strcat(char *dest, const char *src);

View File

@ -2,6 +2,7 @@
#include <libsystem/syscall.h>
#include <libc/errno.h>
#include <libc/stdio.h>
#include <libc/stddef.h>
/**
* @brief 关闭文件接口
@ -105,4 +106,33 @@ void *sbrk(int64_t increment)
errno = 0;
return (void *)retval;
}
}
/**
* @brief 切换当前工作目录
*
* @param dest_path 目标目录
* @return int64_t 成功0,失败:负值(错误码)
*/
int64_t chdir(char *dest_path)
{
if (dest_path == NULL)
{
errno = -EFAULT;
return -1;
}
else
{
int retval = syscall_invoke(SYS_CHDIR, (uint64_t)dest_path, 0,0,0,0,0,0,0);
if(retval == 0)
{
errno = 0;
return 0;
}
else
{
errno = retval;
return -1;
}
}
}

View File

@ -2,11 +2,6 @@
#include <stdint.h>
#include <libc/sys/types.h>
/**
* @brief 关闭文件接口
*
@ -47,15 +42,15 @@ off_t lseek(int fd, off_t offset, int whence);
/**
* @brief fork当前进程
*
* @return pid_t
*
* @return pid_t
*/
pid_t fork(void);
/**
* @brief fork当前进程但是与父进程共享VM、flags、fd
*
* @return pid_t
*
* @return pid_t
*/
pid_t vfork(void);
@ -72,8 +67,16 @@ uint64_t brk(uint64_t end_brk);
/**
* @brief 将堆内存空间加上offset注意该系统调用只应在普通进程中调用而不能是内核线程
*
*
* @param increment offset偏移量
* @return uint64_t the previous program break
*/
void * sbrk(int64_t increment);
void *sbrk(int64_t increment);
/**
* @brief 切换当前工作目录
*
* @param dest_path 目标目录
* @return int64_t 成功0,失败:负值(错误码)
*/
int64_t chdir(char *dest_path);