Commit bd33ae4e authored by minicago's avatar minicago
Browse files

fixed&doc: fat32 NULL

parent fc6effe4
No related merge requests found
Showing with 76 additions and 15 deletions
+76 -15
......@@ -34,6 +34,26 @@ extern char pmem_base[];
``main`` 中编写测试代码,测试通过。
### 伙伴系统
构建一棵维护内核内存堆中物理页的线段树。
每个节点记录当前节点对应区域的最大连续页数。
每次分配与释放在线段树上遍历。
伙伴系统提供了``palloc(_n)````p_free``函数
### slab
将从伙伴系统中获取的整页地址进行合适拆分分配给内核。
具体实现是将页拆分成相同大小的内存段。
每次kalloc取对应大小的内
提供了``kmalloc````kfree``函数
## 虚拟内存
### 页表
......@@ -103,6 +123,16 @@ palloc仍然是相同的代码,但palloc分配的不再是原来物理上的pa
但依赖palloc的函数也能正常运行,因为他们也能“自动”通过页表“翻译”。
### vm
管理虚拟内存段的结构体
每个vm拥有一个pm_list
vm可以管理对应虚拟内存段在init, fork,exit,pagefault时的**行为**(如何初始化,如何拷贝,是否释放,如何处理缺页)
每个进程拥有一个vm_list
### 错误调试
1) 在mappages时,代码发生remmap(重复映射)。原因是pmem(堆空间)的对齐未合理实现,一个较好的实现方式是在链接脚本中添加``. = ALIGN(0x1000);``(页大小为4096)。
......@@ -113,18 +143,20 @@ palloc仍然是相同的代码,但palloc分配的不再是原来物理上的pa
### kernel virtual memory space
|name|base|size|
|-|-|-|
|CLINT0 |0x02000000|PG_SIZE|
|PLIC0 |0x0c000000|PG_SIZE|
|VIRTIO |0x10001000|PG_SIZE|
|KERNEL0 |0x80000000|内核代码大小|
|PMEM0 |KERNEL END|TO_MAX_PA|
|CLINT0 | 0x02000000|PG_SIZE|
|PLIC0 | 0x0c000000|PG_SIZE|
|VIRTIO | 0x10001000|PG_SIZE|
|KERNEL0 | 0x80000000|内核代码大小|
|PMEM0 | KERNEL END|TO_MAX_PA|
|HEAP0 |0x100000000|0x80000000|
|CORO_STACK0(tid)|0x20000f000 + tid * 0x10000|最大PG_SIZE|
|STACK0 |0x300000000|0x80000000|
|TRAMPOLINE |0x3fffff000|PG_SIZE|
### user virtual memory space
|name|base|size|
|-|-|-|
|CODE0 |0x00000000|用户代码大小|
|T_STACK0(tid) |0x200000000 + tid * 0x10000|最大15 * PG_SIZE|
|STACK0 |0x300000000|0x80000000|
|CORO_STACK0(tid)|0x20000f000 + tid * 0x10000|最大PG_SIZE|
|TRAMPOLINE |0x3fffff000|PG_SIZE|
\ No newline at end of file
......@@ -18,6 +18,14 @@
所以目前阶段,我们只维护子进程记数。
**更新**
在实现wait的时候,我们发现不记录进程子进程的代价是巨大的,每次wait需要遍历整个进程池。
而且在实现wait前,我们已经实现了kmalloc,可以实现内核小段地址的分配,似乎保存自进程的开销也变得可以接受。
但多次kmalloc带来的时间代价依旧是难以接受的,所以我们在process_t中添加child_list和prev,next来保存线程树信息,在需要更新时获取thread_pool的wait_lock来更新。
### fork
在多线程结构中,``fork`` 理论上只会复制调用它的那个线程。(据说这是「POSIX 系统的历史包袱」)
......@@ -64,6 +72,11 @@
而辅助协程可以随时创造和销毁,由主协程中管理其内存空间,可以避免内存泄漏。
**注意**
为了避免协程出现内存泄漏,我们可以采取最简单的方法,在每次``entry_to_user``回到用户程序后,都可以重置协程的栈,这样可以避免每次协程因为生存时函数跳转流程不同,导致栈空间内存的泄漏。
``` mermaid
sequenceDiagram
......@@ -101,8 +114,17 @@ end
一个进程上允许存在多个线程,他们之间**堆栈代码段资源完全相同**,这可能会导致线程之间的一些**非法**操作(如修改同一进程上其余线程的系统栈),但我们在系统层面上允许这种行为:综合考虑后,认为这种行为不具有较大的安全隐患,且用户可以避免并且在不了解系统的页表结构时很难触发。
**更新**
在实现fork的时候,我们发现不同线程如果栈空间虚拟地址不同会带来fork之后无法访问涉及fork前栈空间信息的内容,于是在实现fork&exec的版本中,我们重新将用户程序系统栈的虚拟地址统一设置为TSTACK0不再与线程相关。
进程会记录附着的线程数(但不知道具体tid:减小内存负担),当一个进程没有内存附着的时候,会允许其回收资源。
回收资源分为两步,第一步是释放掉vm_list记录的虚拟空间表中的虚拟空间,以及页表信息,并且令其子进程父进程变为``NULL``,在此之后进程将会成为僵尸进程。
僵尸进程保留进程的基本信息,维持进程树上的关系,在其父进程``wait``其或其不存在父进程(父进程变为``NULL``)时彻底回收剩下所有资源。
### 线程号
我们查阅资料发现两种线程标号的策略。
......
# Spinlock & Waitqueue
\ No newline at end of file
......@@ -354,7 +354,7 @@ int fat32_superblock_init(inode_t *node, superblock_t *parent, superblock_t *sb,
{
// read boot sector
struct buf *b = NULL;
uint8 *dbs;
uint8 *dbs = NULL;
sb->extra = kmalloc(sizeof(fat32_info_t));
sb->fs_type = FS_TYPE_FAT32;
sb->identifier = identifier;
......@@ -405,9 +405,9 @@ int fat32_superblock_init(inode_t *node, superblock_t *parent, superblock_t *sb,
//TODO: make the memory alloced to fat is continuous by more official function
info->fat_blocks = fat_blocks;
int fat_size = fat_blocks*BSIZE;
int page_num = ceil_div(fat_size,PG_SIZE);
// info->fat = (uint32 *)kmalloc(fat_size);
info->fat = (uint32 *)palloc_n(page_num);
// int page_num = ceil_div(fat_size,PG_SIZE);
info->fat = (uint32 *)kmalloc(fat_size);
// info->fat = (uint32 *)palloc_n(page_num);
printf("fat32: info->fat%p\n",info->fat);
int bid = info->fat_offset * info->blocks_per_sector;
if(parent->fs_type!=FS_TYPE_DISK) {
......@@ -450,8 +450,8 @@ fat32_superblock_init_error:
static int free_extra(void *extra) {
fat32_info_t *info = (fat32_info_t *)extra;
//kfree(info->fat);
pfree(info->fat);
kfree(info->fat);
// pfree(info->fat);
kfree(extra);
return 1;
}
......@@ -738,12 +738,13 @@ static int fat32_create_inode(inode_t* dir, char* filename, uint8 type, uint8 ma
return 0;
}
struct sfn_entry tmp;
if (lookup_entry(sb, dir->id, filename, &tmp)!=-1)
{
printf("fat32: file exists\n");
return 0;
}
// get free index, if dir is too small to add the file, will add cluster
int cid = dir->id;
char *mem = palloc();
......@@ -787,7 +788,7 @@ static int fat32_create_inode(inode_t* dir, char* filename, uint8 type, uint8 ma
} else {
int ori_cid = cid;
cid = get_next_cid(sb, cid);
if(cid==FAT32_END_CID) {
if(!FAT32_CID_IS_VALID(cid)) {
cid = add_cluster(sb, ori_cid);
if(cid==-1) {
printf("fat32: add cluster error\n");
......
......@@ -209,11 +209,13 @@ file_t* file_openat(inode_t *dir_node, const char *path, int flags, int mode)
remove_last_file(npath);
get_last_file(path, filename);
if(npath[0]!='\0') dir_node = look_up_path(dir_node, npath, NULL);
if(flags & O_DIRECTORY) {
res = create_inode(dir_node, filename, 0, T_DIR);
} else {
res = create_inode(dir_node, filename, 0, T_FILE);
}
release_inode(dir_node);
pfree(mem);
if(res==NULL) return NULL;
......
......@@ -249,6 +249,7 @@ inode_t* create_inode(inode_t* dir, char* filename, uint8 major, uint8 type) {
if (dir->valid == 0) {
panic("create_inode: invalid inode");
}
if ((dir->sb->create_inode(dir, filename, type, major, &node)) == 0) {
printf("create_inode: create error");
return NULL;
......
......@@ -213,6 +213,7 @@ void init_kmem_cache(){
slab_t* alloc_slab(int size, int offset, int num){
slab_t* slab = palloc_n(1);
memset(slab, 0 ,PG_SIZE);
if(slab == NULL) panic("alloc slab: No page for alloc slab");
slab->freelist = ((void*) (slab)) + offset;
for(int i = 0; i < num; i++){
......
......@@ -117,6 +117,7 @@ int sys_openat(int dirfd, uint64 va, int flags, int mode)
}
else {
file = file_openat(dir_node, path, flags, mode);
}
if(file == NULL) {
printf("sys_openat: file_openat error\n");
......@@ -159,7 +160,7 @@ int sys_mkdirat(int dirfd, uint64 va, int mode)
int sys_close(int fd)
{
printf("sys_close: fd=%d\n", fd);
real_printf("sys_close: fd=%d\n", fd);
if (fd < 0 || fd >= MAX_FD) {
printf("sys_close: fd error\n");
return -1;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment