replace disp_*
This commit is contained in:
parent
f9ed0ed420
commit
f70a22b8c2
@ -49,7 +49,6 @@ typedef struct s_tty
|
|||||||
struct s_console *console;
|
struct s_console *console;
|
||||||
} TTY;
|
} TTY;
|
||||||
|
|
||||||
|
|
||||||
typedef struct n_tty
|
typedef struct n_tty
|
||||||
{
|
{
|
||||||
int driver_type; // 1-vga&kbd; 2-serial
|
int driver_type; // 1-vga&kbd; 2-serial
|
||||||
@ -75,21 +74,24 @@ typedef struct vga_buf
|
|||||||
int cur_row;
|
int cur_row;
|
||||||
int cur_col; // cursor position, on screen
|
int cur_col; // cursor position, on screen
|
||||||
|
|
||||||
|
bool Is2param;
|
||||||
enum CSI_state CSI;
|
enum CSI_state CSI;
|
||||||
i16 param1; // the first param of CSI
|
i16 param1; // the first param of CSI
|
||||||
i16 param2; // the second of CSI
|
i16 param2; // the second of CSI
|
||||||
u16 color;
|
u16 color;
|
||||||
} vga_buf;
|
} vga_buf;
|
||||||
|
|
||||||
typedef struct keyboard_buf {
|
typedef struct keyboard_buf
|
||||||
void* buf; // 1d array, buffer input virtual line, works as a ldisc
|
{
|
||||||
|
void *buf; // 1d array, buffer input virtual line, works as a ldisc
|
||||||
int tail;
|
int tail;
|
||||||
int head;
|
int head;
|
||||||
int len;
|
int len;
|
||||||
int readable;
|
int readable;
|
||||||
} keyboard_buf;
|
} keyboard_buf;
|
||||||
|
|
||||||
typedef struct serial_buf {
|
typedef struct serial_buf
|
||||||
|
{
|
||||||
void *buf;
|
void *buf;
|
||||||
int tail;
|
int tail;
|
||||||
int head;
|
int head;
|
||||||
@ -104,27 +106,26 @@ void init_screen(TTY *tty);
|
|||||||
void out_char(CONSOLE *con, char ch);
|
void out_char(CONSOLE *con, char ch);
|
||||||
int is_current_console(CONSOLE *con);
|
int is_current_console(CONSOLE *con);
|
||||||
|
|
||||||
NTTY* get_tty(const int nr_tty);
|
NTTY *get_tty(const int nr_tty);
|
||||||
|
|
||||||
void vga_tty_init(NTTY* tty);
|
void vga_tty_init(NTTY *tty);
|
||||||
void vga_tty_write(NTTY* tty, char ch);
|
void vga_tty_write(NTTY *tty, char ch);
|
||||||
void vga_tty_flush(NTTY* tty);
|
void vga_tty_flush(NTTY *tty);
|
||||||
void vga_tty_backspace(NTTY* tty);
|
void vga_tty_backspace(NTTY *tty);
|
||||||
void vga_tty_scroll(NTTY *tty, int direction);
|
void vga_tty_scroll(NTTY *tty, int direction);
|
||||||
void vga_tty_select(NTTY *tty);
|
void vga_tty_select(NTTY *tty);
|
||||||
|
|
||||||
void ps2_tty_init(NTTY* tty);
|
void ps2_tty_init(NTTY *tty);
|
||||||
int ps2_tty_read(NTTY* tty, char* buf, int nr);
|
int ps2_tty_read(NTTY *tty, char *buf, int nr);
|
||||||
|
|
||||||
|
#define CYCLE_SUB(head, tail, _max) ((head) <= (tail) ? (tail) - (head) : (tail) + (_max) - (head))
|
||||||
#define CYCLE_SUB(head, tail, _max) ((head) <= (tail) ? (tail)-(head) : (tail) + (_max) - (head))
|
|
||||||
#define NEXT(x, _max) (((x) + 1) % (_max))
|
#define NEXT(x, _max) (((x) + 1) % (_max))
|
||||||
#define LAST(x, _max) (((x) - 1) >= 0 ? ((x) - 1) % (_max) : (_max) - 1)
|
#define LAST(x, _max) (((x)-1) >= 0 ? ((x)-1) % (_max) : (_max)-1)
|
||||||
|
|
||||||
#define FOREGROUND(color) ((u16)(color & 0xf) << 8)
|
#define FOREGROUND(color) ((u16)(color & 0xf) << 8)
|
||||||
#define BACKGROUND(color) ((u16)(color & 0xf) << 12)
|
#define BACKGROUND(color) ((u16)(color & 0xf) << 12)
|
||||||
|
|
||||||
// extern int cur_ntty;
|
// extern int cur_ntty;
|
||||||
extern NTTY* cur_ntty;
|
extern NTTY *cur_ntty;
|
||||||
// extern NTTY ntty_table[3];
|
// extern NTTY ntty_table[3];
|
||||||
#endif /* _ORANGES_TTY_H_ */
|
#endif /* _ORANGES_TTY_H_ */
|
||||||
300
kernel/exec.c
300
kernel/exec.c
@ -1,6 +1,6 @@
|
|||||||
/**********************************************
|
/**********************************************
|
||||||
* exec.c add by visual 2016.5.23
|
* exec.c add by visual 2016.5.23
|
||||||
*************************************************/
|
*************************************************/
|
||||||
#include "type.h"
|
#include "type.h"
|
||||||
#include "const.h"
|
#include "const.h"
|
||||||
#include "protect.h"
|
#include "protect.h"
|
||||||
@ -13,239 +13,233 @@
|
|||||||
#include "vfs.h"
|
#include "vfs.h"
|
||||||
#include "stdio.h"
|
#include "stdio.h"
|
||||||
|
|
||||||
|
static u32 exec_elfcpy(u32 fd, Elf32_Phdr Echo_Phdr, u32 attribute);
|
||||||
|
static u32 exec_load(u32 fd, const Elf32_Ehdr *Echo_Ehdr, const Elf32_Phdr Echo_Phdr[]);
|
||||||
static u32 exec_elfcpy(u32 fd,Elf32_Phdr Echo_Phdr,u32 attribute);
|
static int exec_pcb_init(char *path);
|
||||||
static u32 exec_load(u32 fd,const Elf32_Ehdr* Echo_Ehdr,const Elf32_Phdr Echo_Phdr[]);
|
|
||||||
static int exec_pcb_init(char* path);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*======================================================================*
|
/*======================================================================*
|
||||||
* sys_exec add by visual 2016.5.23
|
* sys_exec add by visual 2016.5.23
|
||||||
*exec系统调用功能实现部分
|
*exec系统调用功能实现部分
|
||||||
*======================================================================*/
|
*======================================================================*/
|
||||||
u32 sys_exec(char *path)
|
u32 sys_exec(char *path)
|
||||||
{
|
{
|
||||||
Elf32_Ehdr *Echo_Ehdr = NULL;
|
Elf32_Ehdr *Echo_Ehdr = NULL;
|
||||||
Elf32_Phdr *Echo_Phdr = NULL;
|
Elf32_Phdr *Echo_Phdr = NULL;
|
||||||
u32 addr_lin;
|
u32 addr_lin;
|
||||||
u32 err_temp;
|
u32 err_temp;
|
||||||
|
|
||||||
char* p_reg; //point to a register in the new kernel stack, added by xw, 17/12/11
|
|
||||||
|
|
||||||
if( 0==path )
|
char *p_reg; // point to a register in the new kernel stack, added by xw, 17/12/11
|
||||||
|
|
||||||
|
if (0 == path)
|
||||||
{
|
{
|
||||||
disp_color_str("exec: path ERROR!",0x74);
|
printf("\x1b[31,47mexec: path ERROR!\x1b[m");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************打开文件************************/
|
/*******************打开文件************************/
|
||||||
// u32 fd = open(path,"r"); //deleted by mingxuan 2019-5-19
|
// u32 fd = open(path,"r"); //deleted by mingxuan 2019-5-19
|
||||||
u32 fd = do_vopen(path, O_RDWR); //deleted by mingxuan 2019-5-19
|
u32 fd = do_vopen(path, O_RDWR); // deleted by mingxuan 2019-5-19
|
||||||
|
|
||||||
if(fd==-1)
|
if (fd == -1)
|
||||||
{
|
{
|
||||||
//printf("sys_exec open error!\n"); //deleted by mingxuan 2019-5-23
|
// printf("sys_exec open error!\n"); //deleted by mingxuan 2019-5-23
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
// u32 fd = fake_open(path,"r"); //modified by xw, 18/5/30
|
// u32 fd = fake_open(path,"r"); //modified by xw, 18/5/30
|
||||||
|
|
||||||
/*************获取elf信息**************/
|
/*************获取elf信息**************/
|
||||||
Echo_Ehdr = (Elf32_Ehdr*)K_PHY2LIN(sys_kmalloc(sizeof(Elf32_Ehdr)));
|
Echo_Ehdr = (Elf32_Ehdr *)K_PHY2LIN(sys_kmalloc(sizeof(Elf32_Ehdr)));
|
||||||
read_Ehdr(fd, Echo_Ehdr, 0);
|
read_Ehdr(fd, Echo_Ehdr, 0);
|
||||||
Echo_Phdr = (Elf32_Phdr*)K_PHY2LIN(sys_kmalloc(sizeof(Elf32_Phdr) * Echo_Ehdr->e_phnum));
|
Echo_Phdr = (Elf32_Phdr *)K_PHY2LIN(sys_kmalloc(sizeof(Elf32_Phdr) * Echo_Ehdr->e_phnum));
|
||||||
for (int i = 0 ; i < Echo_Ehdr->e_phnum ; i++)
|
for (int i = 0; i < Echo_Ehdr->e_phnum; i++)
|
||||||
read_Phdr(fd, Echo_Phdr + i, Echo_Ehdr->e_phoff + i * sizeof(Elf32_Phdr));
|
read_Phdr(fd, Echo_Phdr + i, Echo_Ehdr->e_phoff + i * sizeof(Elf32_Phdr));
|
||||||
|
|
||||||
/*************释放进程内存****************/
|
/*************释放进程内存****************/
|
||||||
//目前还没有实现 思路是:数据、代码根据text_info和data_info属性决定释放深度,其余内存段可以完全释放
|
// 目前还没有实现 思路是:数据、代码根据text_info和data_info属性决定释放深度,其余内存段可以完全释放
|
||||||
|
|
||||||
/*************根据elf的program复制文件信息**************/
|
/*************根据elf的program复制文件信息**************/
|
||||||
if(-1==exec_load(fd,Echo_Ehdr,Echo_Phdr)) return -1;//使用了const指针传递
|
if (-1 == exec_load(fd, Echo_Ehdr, Echo_Phdr))
|
||||||
|
return -1; // 使用了const指针传递
|
||||||
|
|
||||||
|
/*****************重新初始化该进程的进程表信息(包括LDT)、线性地址布局、进程树属性********************/
|
||||||
|
exec_pcb_init(path);
|
||||||
|
|
||||||
/*****************重新初始化该进程的进程表信息(包括LDT)、线性地址布局、进程树属性********************/
|
|
||||||
exec_pcb_init(path);
|
|
||||||
|
|
||||||
/***********************代码、数据、堆、栈***************************/
|
/***********************代码、数据、堆、栈***************************/
|
||||||
//代码、数据已经处理,将eip重置即可
|
// 代码、数据已经处理,将eip重置即可
|
||||||
p_proc_current->task.regs.eip = Echo_Ehdr->e_entry;//进程入口线性地址
|
p_proc_current->task.regs.eip = Echo_Ehdr->e_entry; // 进程入口线性地址
|
||||||
p_reg = (char*)(p_proc_current + 1); //added by xw, 17/12/11
|
p_reg = (char *)(p_proc_current + 1); // added by xw, 17/12/11
|
||||||
*((u32*)(p_reg + EIPREG - P_STACKTOP)) = p_proc_current->task.regs.eip; //added by xw, 17/12/11
|
*((u32 *)(p_reg + EIPREG - P_STACKTOP)) = p_proc_current->task.regs.eip; // added by xw, 17/12/11
|
||||||
|
|
||||||
//栈
|
|
||||||
p_proc_current->task.regs.esp=(u32)p_proc_current->task.memmap.stack_lin_base; //栈地址最高处
|
|
||||||
*((u32*)(p_reg + ESPREG - P_STACKTOP)) = p_proc_current->task.regs.esp; //added by xw, 17/12/11
|
|
||||||
|
|
||||||
for( addr_lin=p_proc_current->task.memmap.stack_lin_base ; addr_lin > p_proc_current->task.memmap.stack_lin_limit ; addr_lin-=num_4K )
|
|
||||||
{
|
|
||||||
err_temp = lin_mapping_phy( addr_lin,//线性地址 //add by visual 2016.5.9
|
|
||||||
MAX_UNSIGNED_INT,//物理地址 //edit by visual 2016.5.19
|
|
||||||
p_proc_current->task.pid,//进程pid //edit by visual 2016.5.19
|
|
||||||
PG_P | PG_USU | PG_RWW,//页目录的属性位
|
|
||||||
PG_P | PG_USU | PG_RWW);//页表的属性位
|
|
||||||
|
|
||||||
if( err_temp!=0 )
|
// 栈
|
||||||
|
p_proc_current->task.regs.esp = (u32)p_proc_current->task.memmap.stack_lin_base; // 栈地址最高处
|
||||||
|
*((u32 *)(p_reg + ESPREG - P_STACKTOP)) = p_proc_current->task.regs.esp; // added by xw, 17/12/11
|
||||||
|
|
||||||
|
for (addr_lin = p_proc_current->task.memmap.stack_lin_base; addr_lin > p_proc_current->task.memmap.stack_lin_limit; addr_lin -= num_4K)
|
||||||
|
{
|
||||||
|
err_temp = lin_mapping_phy(addr_lin, // 线性地址 //add by visual 2016.5.9
|
||||||
|
MAX_UNSIGNED_INT, // 物理地址 //edit by visual 2016.5.19
|
||||||
|
p_proc_current->task.pid, // 进程pid //edit by visual 2016.5.19
|
||||||
|
PG_P | PG_USU | PG_RWW, // 页目录的属性位
|
||||||
|
PG_P | PG_USU | PG_RWW); // 页表的属性位
|
||||||
|
|
||||||
|
if (err_temp != 0)
|
||||||
{
|
{
|
||||||
disp_color_str("kernel_main Error:lin_mapping_phy",0x74);
|
|
||||||
|
kprintf("\x1b[31;47mkernel_main Error:lin_mapping_phy\x1b[m");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//堆 用户还没有申请,所以没有分配,只在PCB表里标示了线性起始位置
|
// 堆 用户还没有申请,所以没有分配,只在PCB表里标示了线性起始位置
|
||||||
|
|
||||||
real_close(fd); //added by mingxuan 2019-5-23
|
real_close(fd); // added by mingxuan 2019-5-23
|
||||||
if (Echo_Ehdr != NULL)
|
if (Echo_Ehdr != NULL)
|
||||||
sys_free(Echo_Ehdr);
|
sys_free(Echo_Ehdr);
|
||||||
if (Echo_Phdr != NULL)
|
if (Echo_Phdr != NULL)
|
||||||
sys_free(Echo_Phdr);
|
sys_free(Echo_Phdr);
|
||||||
|
|
||||||
//disp_color_str("\n[exec success:",0x72);//灰底绿字
|
// kprintf("\n\x1b[32;47m[exec success:");//灰底绿字
|
||||||
//disp_color_str(path,0x72);//灰底绿字
|
// kprintf(path);//灰底绿字
|
||||||
//disp_color_str("]",0x72);//灰底绿字
|
// kpritff("]\x1b[m");//灰底绿字
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*======================================================================*
|
/*======================================================================*
|
||||||
* exec_elfcpy add by visual 2016.5.23
|
* exec_elfcpy add by visual 2016.5.23
|
||||||
*复制elf中program到内存中
|
*复制elf中program到内存中
|
||||||
*======================================================================*/
|
*======================================================================*/
|
||||||
static u32 exec_elfcpy(u32 fd,Elf32_Phdr Echo_Phdr,u32 attribute) // 这部分代码将来要移动到exec.c文件中,包括下面exec()中的一部分
|
static u32 exec_elfcpy(u32 fd, Elf32_Phdr Echo_Phdr, u32 attribute) // 这部分代码将来要移动到exec.c文件中,包括下面exec()中的一部分
|
||||||
{
|
{
|
||||||
u32 lin_addr = Echo_Phdr.p_vaddr;
|
u32 lin_addr = Echo_Phdr.p_vaddr;
|
||||||
u32 lin_limit = Echo_Phdr.p_vaddr + Echo_Phdr.p_memsz;
|
u32 lin_limit = Echo_Phdr.p_vaddr + Echo_Phdr.p_memsz;
|
||||||
u32 file_offset = Echo_Phdr.p_offset;
|
u32 file_offset = Echo_Phdr.p_offset;
|
||||||
u32 file_limit = Echo_Phdr.p_offset + Echo_Phdr.p_filesz;
|
u32 file_limit = Echo_Phdr.p_offset + Echo_Phdr.p_filesz;
|
||||||
char ch;
|
char ch;
|
||||||
//u32 pde_addr_phy = get_pde_phy_addr(p_proc_current->task.pid); //页目录物理地址 //delete by visual 2016.5.19
|
// u32 pde_addr_phy = get_pde_phy_addr(p_proc_current->task.pid); //页目录物理地址 //delete by visual 2016.5.19
|
||||||
//u32 addr_phy = do_malloc(Echo_Phdr.p_memsz);//申请物理内存 //delete by visual 2016.5.19
|
// u32 addr_phy = do_malloc(Echo_Phdr.p_memsz);//申请物理内存 //delete by visual 2016.5.19
|
||||||
for( ; lin_addr<lin_limit ; lin_addr++,file_offset++ )
|
for (; lin_addr < lin_limit; lin_addr++, file_offset++)
|
||||||
{
|
{
|
||||||
lin_mapping_phy(lin_addr,MAX_UNSIGNED_INT,p_proc_current->task.pid,PG_P | PG_USU | PG_RWW/*说明*/,attribute);//说明:PDE属性尽量为读写,因为它要映射1024个物理页,可能既有数据,又有代码 //edit by visual 2016.5.19
|
lin_mapping_phy(lin_addr, MAX_UNSIGNED_INT, p_proc_current->task.pid, PG_P | PG_USU | PG_RWW /*说明*/, attribute); // 说明:PDE属性尽量为读写,因为它要映射1024个物理页,可能既有数据,又有代码 //edit by visual 2016.5.19
|
||||||
if( file_offset<file_limit )
|
if (file_offset < file_limit)
|
||||||
{//文件中还有数据,正常拷贝
|
{ // 文件中还有数据,正常拷贝
|
||||||
//modified by xw, 18/5/30
|
// modified by xw, 18/5/30
|
||||||
// seek(file_offset);
|
// seek(file_offset);
|
||||||
// read(fd,&ch,1);
|
// read(fd,&ch,1);
|
||||||
|
|
||||||
//fake_seek(file_offset); //deleted by mingxuan 2019-5-22
|
// fake_seek(file_offset); //deleted by mingxuan 2019-5-22
|
||||||
//real_lseek(fd, file_offset, SEEK_SET); //modified by mingxuan 2019-5-22
|
// real_lseek(fd, file_offset, SEEK_SET); //modified by mingxuan 2019-5-22
|
||||||
do_vlseek(fd, file_offset, SEEK_SET); //modified by mingxuan 2019-5-24
|
do_vlseek(fd, file_offset, SEEK_SET); // modified by mingxuan 2019-5-24
|
||||||
|
|
||||||
//fake_read(fd,&ch,1); //deleted by mingxuan 2019-5-22
|
// fake_read(fd,&ch,1); //deleted by mingxuan 2019-5-22
|
||||||
//real_read(fd, &ch, 1); //modified by mingxuan 2019-5-22
|
// real_read(fd, &ch, 1); //modified by mingxuan 2019-5-22
|
||||||
do_vread(fd, &ch, 1); //modified by mingxuan 2019-5-24
|
do_vread(fd, &ch, 1); // modified by mingxuan 2019-5-24
|
||||||
//~xw
|
//~xw
|
||||||
|
|
||||||
*((u8*)lin_addr) = ch;//memcpy((void*)lin_addr,&ch,1);
|
*((u8 *)lin_addr) = ch; // memcpy((void*)lin_addr,&ch,1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//已初始化数据段拷贝完毕,剩下的是未初始化的数据段,在内存中填0
|
// 已初始化数据段拷贝完毕,剩下的是未初始化的数据段,在内存中填0
|
||||||
*((u8*)lin_addr) = 0;//memset((void*)lin_addr,0,1);
|
*((u8 *)lin_addr) = 0; // memset((void*)lin_addr,0,1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*======================================================================*
|
/*======================================================================*
|
||||||
* exec_load add by visual 2016.5.23
|
* exec_load add by visual 2016.5.23
|
||||||
*根据elf的program复制文件信息
|
*根据elf的program复制文件信息
|
||||||
*======================================================================*/
|
*======================================================================*/
|
||||||
static u32 exec_load(u32 fd,const Elf32_Ehdr* Echo_Ehdr,const Elf32_Phdr Echo_Phdr[])
|
static u32 exec_load(u32 fd, const Elf32_Ehdr *Echo_Ehdr, const Elf32_Phdr Echo_Phdr[])
|
||||||
{
|
{
|
||||||
u32 ph_num;
|
u32 ph_num;
|
||||||
|
|
||||||
if( 0==Echo_Ehdr->e_phnum )
|
if (0 == Echo_Ehdr->e_phnum)
|
||||||
{
|
{
|
||||||
disp_color_str("exec_load: elf ERROR!",0x74);
|
kprintf("\x1b[31;47mexec_load: elf ERROR!\x1b[m", 0x74);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
//我们还不能确定elf中一共能有几个program,但就目前我们查看过的elf文件中,只出现过两中program,一种.text(R-E)和一种.data(RW-)
|
// 我们还不能确定elf中一共能有几个program,但就目前我们查看过的elf文件中,只出现过两中program,一种.text(R-E)和一种.data(RW-)
|
||||||
for( ph_num=0; ph_num<Echo_Ehdr->e_phnum ; ph_num++ )
|
for (ph_num = 0; ph_num < Echo_Ehdr->e_phnum; ph_num++)
|
||||||
{
|
{
|
||||||
if( 0==Echo_Phdr[ph_num].p_memsz )
|
if (0 == Echo_Phdr[ph_num].p_memsz)
|
||||||
{//最后一个program
|
{ // 最后一个program
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if( Echo_Phdr[ph_num].p_flags == 0x5) //101,R_E
|
if (Echo_Phdr[ph_num].p_flags == 0x5) // 101,R_E
|
||||||
{//Code Segment
|
{ // Code Segment
|
||||||
exec_elfcpy(fd,Echo_Phdr[ph_num],PG_P | PG_USU | PG_RWR);//进程代码段
|
exec_elfcpy(fd, Echo_Phdr[ph_num], PG_P | PG_USU | PG_RWR); // 进程代码段
|
||||||
// kprintf("text lin base: 0x%08x\n", Echo_Phdr[ph_num].p_vaddr);
|
// kprintf("text lin base: 0x%08x\n", Echo_Phdr[ph_num].p_vaddr);
|
||||||
p_proc_current->task.memmap.text_lin_base = Echo_Phdr[ph_num].p_vaddr;
|
p_proc_current->task.memmap.text_lin_base = Echo_Phdr[ph_num].p_vaddr;
|
||||||
p_proc_current->task.memmap.text_lin_limit = Echo_Phdr[ph_num].p_vaddr + Echo_Phdr[ph_num].p_memsz;
|
p_proc_current->task.memmap.text_lin_limit = Echo_Phdr[ph_num].p_vaddr + Echo_Phdr[ph_num].p_memsz;
|
||||||
}
|
}
|
||||||
else if(Echo_Phdr[ph_num].p_flags == 0x4)//110,R__
|
else if (Echo_Phdr[ph_num].p_flags == 0x4) // 110,R__
|
||||||
{// It is virtually ROData Segment, god knows what those senpai think about this
|
{ // It is virtually ROData Segment, god knows what those senpai think about this
|
||||||
exec_elfcpy(fd,Echo_Phdr[ph_num],PG_P | PG_USU | PG_RWW);//进程数据段
|
exec_elfcpy(fd, Echo_Phdr[ph_num], PG_P | PG_USU | PG_RWW); // 进程数据段
|
||||||
// kprintf("data lin base: 0x%08x\n", Echo_Phdr[ph_num].p_vaddr);
|
// kprintf("data lin base: 0x%08x\n", Echo_Phdr[ph_num].p_vaddr);
|
||||||
p_proc_current->task.memmap.data_lin_base = Echo_Phdr[ph_num].p_vaddr;
|
p_proc_current->task.memmap.data_lin_base = Echo_Phdr[ph_num].p_vaddr;
|
||||||
p_proc_current->task.memmap.data_lin_limit = Echo_Phdr[ph_num].p_vaddr + Echo_Phdr[ph_num].p_memsz;
|
p_proc_current->task.memmap.data_lin_limit = Echo_Phdr[ph_num].p_vaddr + Echo_Phdr[ph_num].p_memsz;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
disp_color_str("exec_load: unKnown elf'program!",0x74);
|
kprintf("\x1b[31;47mexec_load: unKnown elf'program!\x1b[m");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*======================================================================*
|
/*======================================================================*
|
||||||
* exec_init add by visual 2016.5.23
|
* exec_init add by visual 2016.5.23
|
||||||
* 重新初始化寄存器和特权级、线性地址布局
|
* 重新初始化寄存器和特权级、线性地址布局
|
||||||
*======================================================================*/
|
*======================================================================*/
|
||||||
static int exec_pcb_init(char* path)
|
static int exec_pcb_init(char *path)
|
||||||
{
|
{
|
||||||
char* p_regs; //point to registers in the new kernel stack, added by xw, 17/12/11
|
char *p_regs; // point to registers in the new kernel stack, added by xw, 17/12/11
|
||||||
|
|
||||||
//名称 状态 特权级 寄存器
|
// 名称 状态 特权级 寄存器
|
||||||
strncpy(p_proc_current->task.p_name, path, sizeof(p_proc_current->task.p_name)-1); //名称
|
strncpy(p_proc_current->task.p_name, path, sizeof(p_proc_current->task.p_name) - 1); // 名称
|
||||||
p_proc_current->task.stat = READY; //状态
|
p_proc_current->task.stat = READY; // 状态
|
||||||
p_proc_current->task.ldts[0].attr1 = DA_C | PRIVILEGE_USER << 5;//特权级修改为用户级
|
p_proc_current->task.ldts[0].attr1 = DA_C | PRIVILEGE_USER << 5; // 特权级修改为用户级
|
||||||
p_proc_current->task.ldts[1].attr1 = DA_DRW | PRIVILEGE_USER << 5;//特权级修改为用户级
|
p_proc_current->task.ldts[1].attr1 = DA_DRW | PRIVILEGE_USER << 5; // 特权级修改为用户级
|
||||||
p_proc_current->task.regs.cs = ((8 * 0) & SA_RPL_MASK & SA_TI_MASK)| SA_TIL | RPL_USER;
|
p_proc_current->task.regs.cs = ((8 * 0) & SA_RPL_MASK & SA_TI_MASK) | SA_TIL | RPL_USER;
|
||||||
p_proc_current->task.regs.ds = ((8 * 1) & SA_RPL_MASK & SA_TI_MASK)| SA_TIL | RPL_USER;
|
p_proc_current->task.regs.ds = ((8 * 1) & SA_RPL_MASK & SA_TI_MASK) | SA_TIL | RPL_USER;
|
||||||
p_proc_current->task.regs.es = ((8 * 1) & SA_RPL_MASK & SA_TI_MASK)| SA_TIL | RPL_USER;
|
p_proc_current->task.regs.es = ((8 * 1) & SA_RPL_MASK & SA_TI_MASK) | SA_TIL | RPL_USER;
|
||||||
p_proc_current->task.regs.fs = ((8 * 1) & SA_RPL_MASK & SA_TI_MASK)| SA_TIL | RPL_USER;
|
p_proc_current->task.regs.fs = ((8 * 1) & SA_RPL_MASK & SA_TI_MASK) | SA_TIL | RPL_USER;
|
||||||
p_proc_current->task.regs.ss = ((8 * 1) & SA_RPL_MASK & SA_TI_MASK)| SA_TIL | RPL_USER;
|
p_proc_current->task.regs.ss = ((8 * 1) & SA_RPL_MASK & SA_TI_MASK) | SA_TIL | RPL_USER;
|
||||||
p_proc_current->task.regs.gs = (SELECTOR_KERNEL_GS & SA_RPL_MASK)| RPL_USER;
|
p_proc_current->task.regs.gs = (SELECTOR_KERNEL_GS & SA_RPL_MASK) | RPL_USER;
|
||||||
p_proc_current->task.regs.eflags = 0x202; /* IF=1,bit2 永远是1 */
|
p_proc_current->task.regs.eflags = 0x202; /* IF=1,bit2 永远是1 */
|
||||||
|
|
||||||
/***************copy registers data****************************/
|
/***************copy registers data****************************/
|
||||||
//copy registers data to the bottom of the new kernel stack
|
// copy registers data to the bottom of the new kernel stack
|
||||||
//added by xw, 17/12/11
|
// added by xw, 17/12/11
|
||||||
p_regs = (char*)(p_proc_current + 1);
|
p_regs = (char *)(p_proc_current + 1);
|
||||||
p_regs -= P_STACKTOP;
|
p_regs -= P_STACKTOP;
|
||||||
memcpy(p_regs, (char*)p_proc_current, 18 * 4);
|
memcpy(p_regs, (char *)p_proc_current, 18 * 4);
|
||||||
|
|
||||||
//进程表线性地址布局部分,text、data已经在前面初始化了
|
// 进程表线性地址布局部分,text、data已经在前面初始化了
|
||||||
p_proc_current->task.memmap.vpage_lin_base = VpageLinBase; //保留内存基址
|
p_proc_current->task.memmap.vpage_lin_base = VpageLinBase; // 保留内存基址
|
||||||
p_proc_current->task.memmap.vpage_lin_limit = VpageLinBase; //保留内存界限
|
p_proc_current->task.memmap.vpage_lin_limit = VpageLinBase; // 保留内存界限
|
||||||
p_proc_current->task.memmap.heap_lin_base = HeapLinBase; //堆基址
|
p_proc_current->task.memmap.heap_lin_base = HeapLinBase; // 堆基址
|
||||||
p_proc_current->task.memmap.heap_lin_limit = HeapLinBase; //堆界限
|
p_proc_current->task.memmap.heap_lin_limit = HeapLinBase; // 堆界限
|
||||||
p_proc_current->task.memmap.stack_child_limit = StackLinLimitMAX; //add by visual 2016.5.27
|
p_proc_current->task.memmap.stack_child_limit = StackLinLimitMAX; // add by visual 2016.5.27
|
||||||
p_proc_current->task.memmap.stack_lin_base = StackLinBase; //栈基址
|
p_proc_current->task.memmap.stack_lin_base = StackLinBase; // 栈基址
|
||||||
p_proc_current->task.memmap.stack_lin_limit = StackLinBase - 0x4000; //栈界限(使用时注意栈的生长方向)
|
p_proc_current->task.memmap.stack_lin_limit = StackLinBase - 0x4000; // 栈界限(使用时注意栈的生长方向)
|
||||||
p_proc_current->task.memmap.arg_lin_base = ArgLinBase; //参数内存基址
|
p_proc_current->task.memmap.arg_lin_base = ArgLinBase; // 参数内存基址
|
||||||
p_proc_current->task.memmap.arg_lin_limit = ArgLinBase; //参数内存界限
|
p_proc_current->task.memmap.arg_lin_limit = ArgLinBase; // 参数内存界限
|
||||||
p_proc_current->task.memmap.kernel_lin_base = KernelLinBase; //内核基址
|
p_proc_current->task.memmap.kernel_lin_base = KernelLinBase; // 内核基址
|
||||||
p_proc_current->task.memmap.kernel_lin_limit = KernelLinBase + KernelSize; //内核大小初始化为8M
|
p_proc_current->task.memmap.kernel_lin_limit = KernelLinBase + KernelSize; // 内核大小初始化为8M
|
||||||
|
|
||||||
//进程树属性,只要改两项,其余不用改
|
// 进程树属性,只要改两项,其余不用改
|
||||||
//p_proc_current->task.info.type = TYPE_PROCESS; //当前是进程还是线程
|
// p_proc_current->task.info.type = TYPE_PROCESS; //当前是进程还是线程
|
||||||
//p_proc_current->task.info.real_ppid = -1; //亲父进程,创建它的那个进程
|
// p_proc_current->task.info.real_ppid = -1; //亲父进程,创建它的那个进程
|
||||||
//p_proc_current->task.info.ppid = -1; //当前父进程
|
// p_proc_current->task.info.ppid = -1; //当前父进程
|
||||||
//p_proc_current->task.info.child_p_num = 0; //子进程数量
|
// p_proc_current->task.info.child_p_num = 0; //子进程数量
|
||||||
//p_proc_current->task.info.child_process[NR_CHILD_MAX];//子进程列表
|
// p_proc_current->task.info.child_process[NR_CHILD_MAX];//子进程列表
|
||||||
//p_proc_current->task.info.child_t_num = 0; //子线程数量
|
// p_proc_current->task.info.child_t_num = 0; //子线程数量
|
||||||
//p_proc_current->task.info.child_thread[NR_CHILD_MAX];//子线程列表
|
// p_proc_current->task.info.child_thread[NR_CHILD_MAX];//子线程列表
|
||||||
p_proc_current->task.info.text_hold = 1; //是否拥有代码
|
p_proc_current->task.info.text_hold = 1; // 是否拥有代码
|
||||||
p_proc_current->task.info.data_hold = 1; //是否拥有数据
|
p_proc_current->task.info.data_hold = 1; // 是否拥有数据
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
921
kernel/fat32.c
921
kernel/fat32.c
File diff suppressed because it is too large
Load Diff
332
kernel/fork.c
332
kernel/fork.c
@ -1,7 +1,7 @@
|
|||||||
/*****************************************************
|
/*****************************************************
|
||||||
* fork.c //add by visual 2016.5.25
|
* fork.c //add by visual 2016.5.25
|
||||||
*系统调用fork()功能实现部分sys_fork()
|
*系统调用fork()功能实现部分sys_fork()
|
||||||
********************************************************/
|
********************************************************/
|
||||||
#include "type.h"
|
#include "type.h"
|
||||||
#include "const.h"
|
#include "const.h"
|
||||||
#include "protect.h"
|
#include "protect.h"
|
||||||
@ -11,227 +11,223 @@
|
|||||||
#include "proto.h"
|
#include "proto.h"
|
||||||
#include "stdio.h"
|
#include "stdio.h"
|
||||||
|
|
||||||
static int fork_mem_cpy(u32 ppid,u32 pid);
|
static int fork_mem_cpy(u32 ppid, u32 pid);
|
||||||
static int fork_pcb_cpy(PROCESS* p_child);
|
static int fork_pcb_cpy(PROCESS *p_child);
|
||||||
static int fork_update_info(PROCESS* p_child);
|
static int fork_update_info(PROCESS *p_child);
|
||||||
|
|
||||||
|
|
||||||
/**********************************************************
|
/**********************************************************
|
||||||
* sys_fork //add by visual 2016.5.25
|
* sys_fork //add by visual 2016.5.25
|
||||||
*系统调用sys_fork的具体实现部分
|
*系统调用sys_fork的具体实现部分
|
||||||
*************************************************************/
|
*************************************************************/
|
||||||
int sys_fork()
|
int sys_fork()
|
||||||
{
|
{
|
||||||
PROCESS* p_child;
|
PROCESS *p_child;
|
||||||
char* p_reg; //point to a register in the new kernel stack, added by xw, 17/12/11
|
char *p_reg; // point to a register in the new kernel stack, added by xw, 17/12/11
|
||||||
|
|
||||||
/*****************申请空白PCB表**********************/
|
/*****************申请空白PCB表**********************/
|
||||||
p_child = alloc_PCB();
|
p_child = alloc_PCB();
|
||||||
if( 0==p_child )
|
if (0 == p_child)
|
||||||
{
|
{
|
||||||
disp_color_str("PCB NULL,fork faild!",0x74);
|
kprintf("\x1b[31;47mPCB NULL,fork faild!\x1b[m");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/****************初始化子进程高端地址页表(内核部分)***********************///这个页表可以复制父进程的!
|
/****************初始化子进程高端地址页表(内核部分)***********************/ // 这个页表可以复制父进程的!
|
||||||
init_page_pte(p_child->task.pid); //这里面已经填写了该进程的cr3寄存器变量
|
init_page_pte(p_child->task.pid); // 这里面已经填写了该进程的cr3寄存器变量
|
||||||
|
|
||||||
/************复制父进程的PCB部分内容(保留了自己的标识信息)**************/
|
/************复制父进程的PCB部分内容(保留了自己的标识信息)**************/
|
||||||
fork_pcb_cpy(p_child);
|
fork_pcb_cpy(p_child);
|
||||||
|
|
||||||
/**************复制线性内存,包括堆、栈、代码数据等等***********************/
|
/**************复制线性内存,包括堆、栈、代码数据等等***********************/
|
||||||
fork_mem_cpy(p_proc_current->task.pid,p_child->task.pid);
|
fork_mem_cpy(p_proc_current->task.pid, p_child->task.pid);
|
||||||
|
|
||||||
/**************更新进程树标识info信息************************/
|
/**************更新进程树标识info信息************************/
|
||||||
fork_update_info(p_child);
|
fork_update_info(p_child);
|
||||||
|
|
||||||
/************修改子进程的名字***************/
|
/************修改子进程的名字***************/
|
||||||
strcpy(p_child->task.p_name,"fork"); // 所有的子进程都叫fork
|
strcpy(p_child->task.p_name, "fork"); // 所有的子进程都叫fork
|
||||||
|
|
||||||
/*************子进程返回值在其eax寄存器***************/
|
/*************子进程返回值在其eax寄存器***************/
|
||||||
p_child->task.regs.eax = 0;//return child with 0
|
p_child->task.regs.eax = 0; // return child with 0
|
||||||
p_reg = (char*)(p_child + 1); //added by xw, 17/12/11
|
p_reg = (char *)(p_child + 1); // added by xw, 17/12/11
|
||||||
*((u32*)(p_reg + EAXREG - P_STACKTOP)) = p_child->task.regs.eax; //added by xw, 17/12/11
|
*((u32 *)(p_reg + EAXREG - P_STACKTOP)) = p_child->task.regs.eax; // added by xw, 17/12/11
|
||||||
|
|
||||||
/****************用户进程数+1****************************/
|
/****************用户进程数+1****************************/
|
||||||
u_proc_sum += 1;
|
u_proc_sum += 1;
|
||||||
|
|
||||||
// kprintf("\x1b[32mfork success %s \x1b[0m\n", p_proc_current->task.p_name);
|
// kprintf("\x1b[32mfork success %s \x1b[0m\n", p_proc_current->task.p_name);
|
||||||
|
|
||||||
//anything child need is prepared now, set its state to ready. added by xw, 17/12/11
|
// anything child need is prepared now, set its state to ready. added by xw, 17/12/11
|
||||||
p_child->task.stat = READY;
|
p_child->task.stat = READY;
|
||||||
}
|
}
|
||||||
return p_child->task.pid;
|
return p_child->task.pid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**********************************************************
|
/**********************************************************
|
||||||
* fork_mem_cpy //add by visual 2016.5.24
|
* fork_mem_cpy //add by visual 2016.5.24
|
||||||
*复制父进程的一系列内存数据
|
*复制父进程的一系列内存数据
|
||||||
*************************************************************/
|
*************************************************************/
|
||||||
static int fork_mem_cpy(u32 ppid,u32 pid)
|
static int fork_mem_cpy(u32 ppid, u32 pid)
|
||||||
{
|
{
|
||||||
u32 addr_lin;
|
u32 addr_lin;
|
||||||
//复制代码,代码是共享的,直接将物理地址挂载在子进程的页表上
|
// 复制代码,代码是共享的,直接将物理地址挂载在子进程的页表上
|
||||||
for(addr_lin = p_proc_current->task.memmap.text_lin_base ; addr_lin < p_proc_current->task.memmap.text_lin_limit ; addr_lin+=num_4K )
|
for (addr_lin = p_proc_current->task.memmap.text_lin_base; addr_lin < p_proc_current->task.memmap.text_lin_limit; addr_lin += num_4K)
|
||||||
{
|
{
|
||||||
lin_mapping_phy(addr_lin,//线性地址
|
lin_mapping_phy(addr_lin, // 线性地址
|
||||||
get_page_phy_addr(ppid,addr_lin),//物理地址,为MAX_UNSIGNED_INT时,由该函数自动分配物理内存
|
get_page_phy_addr(ppid, addr_lin), // 物理地址,为MAX_UNSIGNED_INT时,由该函数自动分配物理内存
|
||||||
pid,//要挂载的进程的pid,子进程的pid
|
pid, // 要挂载的进程的pid,子进程的pid
|
||||||
PG_P | PG_USU | PG_RWW,//页目录属性,一般都为可读写
|
PG_P | PG_USU | PG_RWW, // 页目录属性,一般都为可读写
|
||||||
PG_P | PG_USU | PG_RWR);//页表属性,代码是只读的
|
PG_P | PG_USU | PG_RWR); // 页表属性,代码是只读的
|
||||||
}
|
}
|
||||||
//复制数据,数据不共享,子进程需要申请物理地址,并复制过来
|
// 复制数据,数据不共享,子进程需要申请物理地址,并复制过来
|
||||||
for(addr_lin = p_proc_current->task.memmap.data_lin_base ; addr_lin < p_proc_current->task.memmap.data_lin_limit ; addr_lin+=num_4K )
|
for (addr_lin = p_proc_current->task.memmap.data_lin_base; addr_lin < p_proc_current->task.memmap.data_lin_limit; addr_lin += num_4K)
|
||||||
{
|
|
||||||
lin_mapping_phy(SharePageBase,0,ppid,PG_P | PG_USU | PG_RWW,0);//使用前必须清除这个物理页映射
|
|
||||||
lin_mapping_phy(SharePageBase,MAX_UNSIGNED_INT,ppid,PG_P | PG_USU | PG_RWW,PG_P | PG_USU | PG_RWW);//利用父进程的共享页申请物理页
|
|
||||||
memcpy((void*)SharePageBase,(void*)(addr_lin&0xFFFFF000),num_4K);//将数据复制到物理页上,注意这个地方是强制一页一页复制的
|
|
||||||
lin_mapping_phy(addr_lin,//线性地址
|
|
||||||
get_page_phy_addr(ppid,SharePageBase),//物理地址,获取共享页的物理地址,填进子进程页表
|
|
||||||
pid,//要挂载的进程的pid,子进程的pid
|
|
||||||
PG_P | PG_USU | PG_RWW,//页目录属性,一般都为可读写
|
|
||||||
PG_P | PG_USU | PG_RWW);//页表属性,数据是可读写的
|
|
||||||
}
|
|
||||||
//复制保留内存,保留内存不共享,子进程需要申请物理地址,并复制过来
|
|
||||||
for(addr_lin = p_proc_current->task.memmap.vpage_lin_base ; addr_lin < p_proc_current->task.memmap.vpage_lin_limit ; addr_lin+=num_4K )
|
|
||||||
{
|
{
|
||||||
lin_mapping_phy(SharePageBase,0,ppid,PG_P | PG_USU | PG_RWW,0);//使用前必须清除这个物理页映射
|
lin_mapping_phy(SharePageBase, 0, ppid, PG_P | PG_USU | PG_RWW, 0); // 使用前必须清除这个物理页映射
|
||||||
lin_mapping_phy(SharePageBase,MAX_UNSIGNED_INT,ppid,PG_P | PG_USU | PG_RWW,PG_P | PG_USU | PG_RWW);//利用父进程的共享页申请物理页
|
lin_mapping_phy(SharePageBase, MAX_UNSIGNED_INT, ppid, PG_P | PG_USU | PG_RWW, PG_P | PG_USU | PG_RWW); // 利用父进程的共享页申请物理页
|
||||||
memcpy((void*)SharePageBase,(void*)(addr_lin&0xFFFFF000),num_4K);//将数据复制到物理页上,注意这个地方是强制一页一页复制的
|
memcpy((void *)SharePageBase, (void *)(addr_lin & 0xFFFFF000), num_4K); // 将数据复制到物理页上,注意这个地方是强制一页一页复制的
|
||||||
lin_mapping_phy(addr_lin,//线性地址
|
lin_mapping_phy(addr_lin, // 线性地址
|
||||||
get_page_phy_addr(ppid,SharePageBase),//物理地址,获取共享页的物理地址,填进子进程页表
|
get_page_phy_addr(ppid, SharePageBase), // 物理地址,获取共享页的物理地址,填进子进程页表
|
||||||
pid,//要挂载的进程的pid,子进程的pid
|
pid, // 要挂载的进程的pid,子进程的pid
|
||||||
PG_P | PG_USU | PG_RWW,//页目录属性,一般都为可读写
|
PG_P | PG_USU | PG_RWW, // 页目录属性,一般都为可读写
|
||||||
PG_P | PG_USU | PG_RWW);//页表属性,保留内存是可读写的
|
PG_P | PG_USU | PG_RWW); // 页表属性,数据是可读写的
|
||||||
}
|
}
|
||||||
|
// 复制保留内存,保留内存不共享,子进程需要申请物理地址,并复制过来
|
||||||
//复制堆,堆不共享,子进程需要申请物理地址,并复制过来
|
for (addr_lin = p_proc_current->task.memmap.vpage_lin_base; addr_lin < p_proc_current->task.memmap.vpage_lin_limit; addr_lin += num_4K)
|
||||||
for(addr_lin = p_proc_current->task.memmap.heap_lin_base ; addr_lin < p_proc_current->task.memmap.heap_lin_limit ; addr_lin+=num_4K )
|
|
||||||
{
|
{
|
||||||
lin_mapping_phy(SharePageBase,0,ppid,PG_P | PG_USU | PG_RWW,0);//使用前必须清除这个物理页映射
|
lin_mapping_phy(SharePageBase, 0, ppid, PG_P | PG_USU | PG_RWW, 0); // 使用前必须清除这个物理页映射
|
||||||
lin_mapping_phy(SharePageBase,MAX_UNSIGNED_INT,ppid,PG_P | PG_USU | PG_RWW,PG_P | PG_USU | PG_RWW);//利用父进程的共享页申请物理页
|
lin_mapping_phy(SharePageBase, MAX_UNSIGNED_INT, ppid, PG_P | PG_USU | PG_RWW, PG_P | PG_USU | PG_RWW); // 利用父进程的共享页申请物理页
|
||||||
memcpy((void*)SharePageBase,(void*)(addr_lin&0xFFFFF000),num_4K);//将数据复制到物理页上,注意这个地方是强制一页一页复制的
|
memcpy((void *)SharePageBase, (void *)(addr_lin & 0xFFFFF000), num_4K); // 将数据复制到物理页上,注意这个地方是强制一页一页复制的
|
||||||
lin_mapping_phy(addr_lin,//线性地址
|
lin_mapping_phy(addr_lin, // 线性地址
|
||||||
get_page_phy_addr(ppid,SharePageBase),//物理地址,获取共享页的物理地址,填进子进程页表
|
get_page_phy_addr(ppid, SharePageBase), // 物理地址,获取共享页的物理地址,填进子进程页表
|
||||||
pid,//要挂载的进程的pid,子进程的pid
|
pid, // 要挂载的进程的pid,子进程的pid
|
||||||
PG_P | PG_USU | PG_RWW,//页目录属性,一般都为可读写
|
PG_P | PG_USU | PG_RWW, // 页目录属性,一般都为可读写
|
||||||
PG_P | PG_USU | PG_RWW);//页表属性,堆是可读写的
|
PG_P | PG_USU | PG_RWW); // 页表属性,保留内存是可读写的
|
||||||
}
|
|
||||||
|
|
||||||
//复制栈,栈不共享,子进程需要申请物理地址,并复制过来(注意栈的复制方向)
|
|
||||||
for(addr_lin = p_proc_current->task.memmap.stack_lin_base ; addr_lin > p_proc_current->task.memmap.stack_lin_limit ; addr_lin-=num_4K )
|
|
||||||
{
|
|
||||||
lin_mapping_phy(SharePageBase,0,ppid,PG_P | PG_USU | PG_RWW,0);//使用前必须清除这个物理页映射
|
|
||||||
lin_mapping_phy(SharePageBase,MAX_UNSIGNED_INT,ppid,PG_P | PG_USU | PG_RWW,PG_P | PG_USU | PG_RWW);//利用父进程的共享页申请物理页
|
|
||||||
memcpy((void*)SharePageBase,(void*)(addr_lin&0xFFFFF000),num_4K);//将数据复制到物理页上,注意这个地方是强制一页一页复制的
|
|
||||||
lin_mapping_phy(addr_lin,//线性地址
|
|
||||||
get_page_phy_addr(ppid,SharePageBase),//物理地址,获取共享页的物理地址,填进子进程页表
|
|
||||||
pid,//要挂载的进程的pid,子进程的pid
|
|
||||||
PG_P | PG_USU | PG_RWW,//页目录属性,一般都为可读写
|
|
||||||
PG_P | PG_USU | PG_RWW);//页表属性,栈是可读写的
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//复制参数区,参数区不共享,子进程需要申请物理地址,并复制过来
|
// 复制堆,堆不共享,子进程需要申请物理地址,并复制过来
|
||||||
for(addr_lin = p_proc_current->task.memmap.arg_lin_base ; addr_lin < p_proc_current->task.memmap.arg_lin_limit ; addr_lin+=num_4K )
|
for (addr_lin = p_proc_current->task.memmap.heap_lin_base; addr_lin < p_proc_current->task.memmap.heap_lin_limit; addr_lin += num_4K)
|
||||||
{
|
{
|
||||||
lin_mapping_phy(SharePageBase,0,ppid,PG_P | PG_USU | PG_RWW,0);//使用前必须清除这个物理页映射
|
lin_mapping_phy(SharePageBase, 0, ppid, PG_P | PG_USU | PG_RWW, 0); // 使用前必须清除这个物理页映射
|
||||||
lin_mapping_phy(SharePageBase,MAX_UNSIGNED_INT,ppid,PG_P | PG_USU | PG_RWW,PG_P | PG_USU | PG_RWW);//利用父进程的共享页申请物理页
|
lin_mapping_phy(SharePageBase, MAX_UNSIGNED_INT, ppid, PG_P | PG_USU | PG_RWW, PG_P | PG_USU | PG_RWW); // 利用父进程的共享页申请物理页
|
||||||
memcpy((void*)SharePageBase,(void*)(addr_lin&0xFFFFF000),num_4K);//将数据复制到物理页上,注意这个地方是强制一页一页复制的
|
memcpy((void *)SharePageBase, (void *)(addr_lin & 0xFFFFF000), num_4K); // 将数据复制到物理页上,注意这个地方是强制一页一页复制的
|
||||||
lin_mapping_phy(addr_lin,//线性地址
|
lin_mapping_phy(addr_lin, // 线性地址
|
||||||
get_page_phy_addr(ppid,SharePageBase),//物理地址,获取共享页的物理地址,填进子进程页表
|
get_page_phy_addr(ppid, SharePageBase), // 物理地址,获取共享页的物理地址,填进子进程页表
|
||||||
pid,//要挂载的进程的pid,子进程的pid
|
pid, // 要挂载的进程的pid,子进程的pid
|
||||||
PG_P | PG_USU | PG_RWW,//页目录属性,一般都为可读写
|
PG_P | PG_USU | PG_RWW, // 页目录属性,一般都为可读写
|
||||||
PG_P | PG_USU | PG_RWW);//页表属性,参数区是可读写的
|
PG_P | PG_USU | PG_RWW); // 页表属性,堆是可读写的
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
|
// 复制栈,栈不共享,子进程需要申请物理地址,并复制过来(注意栈的复制方向)
|
||||||
|
for (addr_lin = p_proc_current->task.memmap.stack_lin_base; addr_lin > p_proc_current->task.memmap.stack_lin_limit; addr_lin -= num_4K)
|
||||||
|
{
|
||||||
|
lin_mapping_phy(SharePageBase, 0, ppid, PG_P | PG_USU | PG_RWW, 0); // 使用前必须清除这个物理页映射
|
||||||
|
lin_mapping_phy(SharePageBase, MAX_UNSIGNED_INT, ppid, PG_P | PG_USU | PG_RWW, PG_P | PG_USU | PG_RWW); // 利用父进程的共享页申请物理页
|
||||||
|
memcpy((void *)SharePageBase, (void *)(addr_lin & 0xFFFFF000), num_4K); // 将数据复制到物理页上,注意这个地方是强制一页一页复制的
|
||||||
|
lin_mapping_phy(addr_lin, // 线性地址
|
||||||
|
get_page_phy_addr(ppid, SharePageBase), // 物理地址,获取共享页的物理地址,填进子进程页表
|
||||||
|
pid, // 要挂载的进程的pid,子进程的pid
|
||||||
|
PG_P | PG_USU | PG_RWW, // 页目录属性,一般都为可读写
|
||||||
|
PG_P | PG_USU | PG_RWW); // 页表属性,栈是可读写的
|
||||||
|
}
|
||||||
|
|
||||||
|
// 复制参数区,参数区不共享,子进程需要申请物理地址,并复制过来
|
||||||
|
for (addr_lin = p_proc_current->task.memmap.arg_lin_base; addr_lin < p_proc_current->task.memmap.arg_lin_limit; addr_lin += num_4K)
|
||||||
|
{
|
||||||
|
lin_mapping_phy(SharePageBase, 0, ppid, PG_P | PG_USU | PG_RWW, 0); // 使用前必须清除这个物理页映射
|
||||||
|
lin_mapping_phy(SharePageBase, MAX_UNSIGNED_INT, ppid, PG_P | PG_USU | PG_RWW, PG_P | PG_USU | PG_RWW); // 利用父进程的共享页申请物理页
|
||||||
|
memcpy((void *)SharePageBase, (void *)(addr_lin & 0xFFFFF000), num_4K); // 将数据复制到物理页上,注意这个地方是强制一页一页复制的
|
||||||
|
lin_mapping_phy(addr_lin, // 线性地址
|
||||||
|
get_page_phy_addr(ppid, SharePageBase), // 物理地址,获取共享页的物理地址,填进子进程页表
|
||||||
|
pid, // 要挂载的进程的pid,子进程的pid
|
||||||
|
PG_P | PG_USU | PG_RWW, // 页目录属性,一般都为可读写
|
||||||
|
PG_P | PG_USU | PG_RWW); // 页表属性,参数区是可读写的
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**********************************************************
|
/**********************************************************
|
||||||
* fork_pcb_cpy //add by visual 2016.5.26
|
* fork_pcb_cpy //add by visual 2016.5.26
|
||||||
*复制父进程PCB表,但是又马上恢复了子进程的标识信息
|
*复制父进程PCB表,但是又马上恢复了子进程的标识信息
|
||||||
*************************************************************/
|
*************************************************************/
|
||||||
static int fork_pcb_cpy(PROCESS* p_child)
|
static int fork_pcb_cpy(PROCESS *p_child)
|
||||||
{
|
{
|
||||||
int pid;
|
int pid;
|
||||||
u32 eflags,selector_ldt,cr3_child;
|
u32 eflags, selector_ldt, cr3_child;
|
||||||
char* p_reg; //point to a register in the new kernel stack, added by xw, 17/12/11
|
char *p_reg; // point to a register in the new kernel stack, added by xw, 17/12/11
|
||||||
// char* esp_save_int, esp_save_context; //It's not what you want! damn it.
|
// char* esp_save_int, esp_save_context; //It's not what you want! damn it.
|
||||||
char *esp_save_int, *esp_save_context; //use to save corresponding field in child's PCB.
|
char *esp_save_int, *esp_save_context; // use to save corresponding field in child's PCB.
|
||||||
|
|
||||||
//暂存标识信息
|
// 暂存标识信息
|
||||||
pid = p_child->task.pid;
|
pid = p_child->task.pid;
|
||||||
|
|
||||||
//eflags = p_child->task.regs.eflags;
|
// eflags = p_child->task.regs.eflags;
|
||||||
p_reg = (char*)(p_child + 1); //added by xw, 17/12/11
|
p_reg = (char *)(p_child + 1); // added by xw, 17/12/11
|
||||||
eflags = *((u32*)(p_reg + EFLAGSREG - P_STACKTOP)); //added by xw, 17/12/11
|
eflags = *((u32 *)(p_reg + EFLAGSREG - P_STACKTOP)); // added by xw, 17/12/11
|
||||||
|
|
||||||
selector_ldt = p_child->task.ldt_sel;
|
selector_ldt = p_child->task.ldt_sel;
|
||||||
cr3_child = p_child->task.cr3;
|
cr3_child = p_child->task.cr3;
|
||||||
|
|
||||||
//复制PCB内容
|
// 复制PCB内容
|
||||||
//modified by xw, 17/12/11
|
// modified by xw, 17/12/11
|
||||||
//modified begin
|
// modified begin
|
||||||
//*p_child = *p_proc_current;
|
//*p_child = *p_proc_current;
|
||||||
|
|
||||||
//esp_save_int and esp_save_context must be saved, because the child and the parent
|
// esp_save_int and esp_save_context must be saved, because the child and the parent
|
||||||
//use different kernel stack! And these two are importent to the child's initial running.
|
// use different kernel stack! And these two are importent to the child's initial running.
|
||||||
//Added by xw, 18/4/21
|
// Added by xw, 18/4/21
|
||||||
esp_save_int = p_child->task.esp_save_int;
|
esp_save_int = p_child->task.esp_save_int;
|
||||||
esp_save_context = p_child->task.esp_save_context;
|
esp_save_context = p_child->task.esp_save_context;
|
||||||
p_child->task = p_proc_current->task;
|
p_child->task = p_proc_current->task;
|
||||||
//note that syscalls can be interrupted now! the state of child can only be setted
|
// note that syscalls can be interrupted now! the state of child can only be setted
|
||||||
//READY when anything else is well prepared. if an interruption happens right here,
|
// READY when anything else is well prepared. if an interruption happens right here,
|
||||||
//an error will still occur.
|
// an error will still occur.
|
||||||
p_child->task.stat = IDLE;
|
p_child->task.stat = IDLE;
|
||||||
p_child->task.esp_save_int = esp_save_int; //esp_save_int of child must be restored!!
|
p_child->task.esp_save_int = esp_save_int; // esp_save_int of child must be restored!!
|
||||||
p_child->task.esp_save_context = esp_save_context; //same above
|
p_child->task.esp_save_context = esp_save_context; // same above
|
||||||
// p_child->task.esp_save_context = (char*)(p_child + 1) - P_STACKTOP - 4 * 6;
|
// p_child->task.esp_save_context = (char*)(p_child + 1) - P_STACKTOP - 4 * 6;
|
||||||
memcpy(((char*)(p_child + 1) - P_STACKTOP), ((char*)(p_proc_current + 1) - P_STACKTOP), 18 * 4);
|
memcpy(((char *)(p_child + 1) - P_STACKTOP), ((char *)(p_proc_current + 1) - P_STACKTOP), 18 * 4);
|
||||||
//modified end
|
// modified end
|
||||||
|
|
||||||
//恢复标识信息
|
// 恢复标识信息
|
||||||
p_child->task.pid = pid;
|
p_child->task.pid = pid;
|
||||||
|
|
||||||
//p_child->task.regs.eflags = eflags;
|
// p_child->task.regs.eflags = eflags;
|
||||||
p_reg = (char*)(p_child + 1); //added by xw, 17/12/11
|
p_reg = (char *)(p_child + 1); // added by xw, 17/12/11
|
||||||
*((u32*)(p_reg + EFLAGSREG - P_STACKTOP)) = eflags; //added by xw, 17/12/11
|
*((u32 *)(p_reg + EFLAGSREG - P_STACKTOP)) = eflags; // added by xw, 17/12/11
|
||||||
|
|
||||||
p_child->task.ldt_sel = selector_ldt;
|
p_child->task.ldt_sel = selector_ldt;
|
||||||
p_child->task.cr3 = cr3_child;
|
p_child->task.cr3 = cr3_child;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**********************************************************
|
/**********************************************************
|
||||||
* fork_update_info //add by visual 2016.5.26
|
* fork_update_info //add by visual 2016.5.26
|
||||||
*更新父进程和子进程的进程树标识info
|
*更新父进程和子进程的进程树标识info
|
||||||
*************************************************************/
|
*************************************************************/
|
||||||
static int fork_update_info(PROCESS* p_child)
|
static int fork_update_info(PROCESS *p_child)
|
||||||
{
|
{
|
||||||
/************更新父进程的info***************/
|
/************更新父进程的info***************/
|
||||||
//p_proc_current->task.info.type; //当前是进程还是线程
|
// p_proc_current->task.info.type; //当前是进程还是线程
|
||||||
//p_proc_current->task.info.real_ppid; //亲父进程,创建它的那个进程
|
// p_proc_current->task.info.real_ppid; //亲父进程,创建它的那个进程
|
||||||
//p_proc_current->task.info.ppid; //当前父进程
|
// p_proc_current->task.info.ppid; //当前父进程
|
||||||
p_proc_current->task.info.child_p_num += 1; //子进程数量
|
p_proc_current->task.info.child_p_num += 1; // 子进程数量
|
||||||
p_proc_current->task.info.child_process[p_proc_current->task.info.child_p_num-1] = p_child->task.pid;//子进程列表
|
p_proc_current->task.info.child_process[p_proc_current->task.info.child_p_num - 1] = p_child->task.pid; // 子进程列表
|
||||||
//p_proc_current->task.info.child_t_num; //子线程数量
|
// p_proc_current->task.info.child_t_num; //子线程数量
|
||||||
//p_proc_current->task.info.child_thread[NR_CHILD_MAX];//子线程列表
|
// p_proc_current->task.info.child_thread[NR_CHILD_MAX];//子线程列表
|
||||||
//p_proc_current->task.text_hold; //是否拥有代码
|
// p_proc_current->task.text_hold; //是否拥有代码
|
||||||
//p_proc_current->task.data_hold; //是否拥有数据
|
// p_proc_current->task.data_hold; //是否拥有数据
|
||||||
|
|
||||||
/************更新子进程的info***************/
|
/************更新子进程的info***************/
|
||||||
p_child->task.info.type = p_proc_current->task.info.type; //当前进程属性跟父进程一样
|
p_child->task.info.type = p_proc_current->task.info.type; // 当前进程属性跟父进程一样
|
||||||
p_child->task.info.real_ppid = p_proc_current->task.pid; //亲父进程,创建它的那个进程
|
p_child->task.info.real_ppid = p_proc_current->task.pid; // 亲父进程,创建它的那个进程
|
||||||
p_child->task.info.ppid = p_proc_current->task.pid; //当前父进程
|
p_child->task.info.ppid = p_proc_current->task.pid; // 当前父进程
|
||||||
p_child->task.info.child_p_num = 0; //子进程数量
|
p_child->task.info.child_p_num = 0; // 子进程数量
|
||||||
//p_child->task.info.child_process[NR_CHILD_MAX] = pid;//子进程列表
|
// p_child->task.info.child_process[NR_CHILD_MAX] = pid;//子进程列表
|
||||||
p_child->task.info.child_t_num = 0; //子线程数量
|
p_child->task.info.child_t_num = 0; // 子线程数量
|
||||||
//p_child->task.info.child_thread[NR_CHILD_MAX];//子线程列表
|
// p_child->task.info.child_thread[NR_CHILD_MAX];//子线程列表
|
||||||
p_child->task.info.text_hold = 0; //是否拥有代码,子进程不拥有代码
|
p_child->task.info.text_hold = 0; // 是否拥有代码,子进程不拥有代码
|
||||||
p_child->task.info.data_hold = 1; //是否拥有数据,子进程拥有数据
|
p_child->task.info.data_hold = 1; // 是否拥有数据,子进程拥有数据
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -132,7 +132,8 @@ void initial()
|
|||||||
do_vclose(stdout);
|
do_vclose(stdout);
|
||||||
do_vclose(stderr);
|
do_vclose(stderr);
|
||||||
|
|
||||||
exec("orange/shell_1.bin");
|
// exec("orange/shell_1.bin");
|
||||||
|
exec("orange/test.bin");
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
;
|
;
|
||||||
|
|||||||
@ -33,7 +33,7 @@ static int initialize_cpus(); // added by xw, 18/6/2
|
|||||||
int kernel_main()
|
int kernel_main()
|
||||||
{
|
{
|
||||||
clear_kernel_pagepte_low();
|
clear_kernel_pagepte_low();
|
||||||
|
|
||||||
init_serial();
|
init_serial();
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
@ -204,7 +204,7 @@ static int initialize_processes()
|
|||||||
/***************初始化PID进程页表*****************************/
|
/***************初始化PID进程页表*****************************/
|
||||||
if (0 != init_page_pte(pid))
|
if (0 != init_page_pte(pid))
|
||||||
{
|
{
|
||||||
disp_color_str("kernel_main Error:init_page_pte", 0x74);
|
kprintf("\x1b[31;47mkernel_main Error:init_page_pte\x1b[m");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
// pde_addr_phy_temp = get_pde_phy_addr(pid);//获取该进程页目录物理地址 //delete by visual 2016.5.19
|
// pde_addr_phy_temp = get_pde_phy_addr(pid);//获取该进程页目录物理地址 //delete by visual 2016.5.19
|
||||||
@ -219,7 +219,7 @@ static int initialize_processes()
|
|||||||
// addr_phy_temp = (u32)do_kmalloc_4k();//为栈申请一个物理页,Task的栈是在内核里面 //delete by visual 2016.5.19
|
// addr_phy_temp = (u32)do_kmalloc_4k();//为栈申请一个物理页,Task的栈是在内核里面 //delete by visual 2016.5.19
|
||||||
// if( addr_phy_temp<0 || (addr_phy_temp&0x3FF)!=0 )
|
// if( addr_phy_temp<0 || (addr_phy_temp&0x3FF)!=0 )
|
||||||
//{
|
//{
|
||||||
// disp_color_str("kernel_main Error:addr_phy_temp",0x74);
|
// kprintf("\x1b[31;47mkernel_main Error:addr_phy_temp\x1b[m");
|
||||||
// return -1;
|
// return -1;
|
||||||
// }
|
// }
|
||||||
err_temp = lin_mapping_phy(AddrLin, // 线性地址 //add by visual 2016.5.9
|
err_temp = lin_mapping_phy(AddrLin, // 线性地址 //add by visual 2016.5.9
|
||||||
@ -229,7 +229,7 @@ static int initialize_processes()
|
|||||||
PG_P | PG_USU | PG_RWW); // 页表的属性位
|
PG_P | PG_USU | PG_RWW); // 页表的属性位
|
||||||
if (err_temp != 0)
|
if (err_temp != 0)
|
||||||
{
|
{
|
||||||
disp_color_str("kernel_main Error:lin_mapping_phy", 0x74);
|
kprintf("\x1b[31;47mkernel_main Error:lin_mapping_phy\x1b[m");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -357,7 +357,7 @@ static int initialize_processes()
|
|||||||
/***************初始化PID进程页表*****************************/
|
/***************初始化PID进程页表*****************************/
|
||||||
if (0 != init_page_pte(pid))
|
if (0 != init_page_pte(pid))
|
||||||
{
|
{
|
||||||
disp_color_str("kernel_main Error:init_page_pte", 0x74);
|
kprintf("\x1b[mkernel_main Error:init_page_pte\x1b[m");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
// pde_addr_phy_temp = get_pde_phy_addr(pid);//获取该进程页目录物理地址 //edit by visual 2016.5.19
|
// pde_addr_phy_temp = get_pde_phy_addr(pid);//获取该进程页目录物理地址 //edit by visual 2016.5.19
|
||||||
@ -372,7 +372,7 @@ static int initialize_processes()
|
|||||||
// addr_phy_temp = (u32)do_kmalloc_4k();//为栈申请一个物理页,Task的栈是在内核里面 //delete by visual 2016.5.19
|
// addr_phy_temp = (u32)do_kmalloc_4k();//为栈申请一个物理页,Task的栈是在内核里面 //delete by visual 2016.5.19
|
||||||
// if( addr_phy_temp<0 || (addr_phy_temp&0x3FF)!=0 )
|
// if( addr_phy_temp<0 || (addr_phy_temp&0x3FF)!=0 )
|
||||||
//{
|
//{
|
||||||
// disp_color_str("kernel_main Error:addr_phy_temp",0x74);
|
// kprintf("\x1b[31;47mkernel_main Error:addr_phy_temp\x1b[m");
|
||||||
// return -1;
|
// return -1;
|
||||||
// }
|
// }
|
||||||
err_temp = lin_mapping_phy(AddrLin, // 线性地址
|
err_temp = lin_mapping_phy(AddrLin, // 线性地址
|
||||||
@ -382,7 +382,7 @@ static int initialize_processes()
|
|||||||
PG_P | PG_USU | PG_RWW); // 页表的属性位
|
PG_P | PG_USU | PG_RWW); // 页表的属性位
|
||||||
if (err_temp != 0)
|
if (err_temp != 0)
|
||||||
{
|
{
|
||||||
disp_color_str("kernel_main Error:lin_mapping_phy", 0x74);
|
kprintf("\x1b[31;47mkernel_main Error:lin_mapping_phy\x1b[m");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
185
kernel/pagetbl.c
185
kernel/pagetbl.c
@ -31,33 +31,33 @@ void switch_pde()
|
|||||||
*该函数只初始化了进程的高端(内核端)地址页表
|
*该函数只初始化了进程的高端(内核端)地址页表
|
||||||
*======================================================================*/
|
*======================================================================*/
|
||||||
u32 init_page_pte(u32 pid)
|
u32 init_page_pte(u32 pid)
|
||||||
{ //页表初始化函数
|
{ // 页表初始化函数
|
||||||
|
|
||||||
u32 AddrLin, pde_addr_phy_temp, err_temp;
|
u32 AddrLin, pde_addr_phy_temp, err_temp;
|
||||||
|
|
||||||
pde_addr_phy_temp = do_kmalloc_4k(); //为页目录申请一页
|
pde_addr_phy_temp = do_kmalloc_4k(); // 为页目录申请一页
|
||||||
memset((void *)K_PHY2LIN(pde_addr_phy_temp), 0, num_4K); // add by visual 2016.5.26
|
memset((void *)K_PHY2LIN(pde_addr_phy_temp), 0, num_4K); // add by visual 2016.5.26
|
||||||
|
|
||||||
if (pde_addr_phy_temp < 0 || (pde_addr_phy_temp & 0x3FF) != 0) // add by visual 2016.5.9
|
if (pde_addr_phy_temp < 0 || (pde_addr_phy_temp & 0x3FF) != 0) // add by visual 2016.5.9
|
||||||
{
|
{
|
||||||
disp_color_str("init_page_pte Error:pde_addr_phy_temp", 0x74);
|
kprintf("\x1b[31;47minit_page_pte Error:pde_addr_phy_temp\x1b[m");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
proc_table[pid].task.cr3 = pde_addr_phy_temp; //初始化了进程表中cr3寄存器变量,属性位暂时不管
|
proc_table[pid].task.cr3 = pde_addr_phy_temp; // 初始化了进程表中cr3寄存器变量,属性位暂时不管
|
||||||
/*********************页表初始化部分*********************************/
|
/*********************页表初始化部分*********************************/
|
||||||
u32 phy_addr = 0;
|
u32 phy_addr = 0;
|
||||||
|
|
||||||
for (AddrLin = KernelLinBase, phy_addr = 0; AddrLin < KernelLinBase + KernelSize; AddrLin += num_4K, phy_addr += num_4K)
|
for (AddrLin = KernelLinBase, phy_addr = 0; AddrLin < KernelLinBase + KernelSize; AddrLin += num_4K, phy_addr += num_4K)
|
||||||
{ //只初始化内核部分,3G后的线性地址映射到物理地址开始处
|
{ // 只初始化内核部分,3G后的线性地址映射到物理地址开始处
|
||||||
err_temp = lin_mapping_phy(AddrLin, //线性地址 //add by visual 2016.5.9
|
err_temp = lin_mapping_phy(AddrLin, // 线性地址 //add by visual 2016.5.9
|
||||||
phy_addr, //物理地址
|
phy_addr, // 物理地址
|
||||||
pid, //进程pid //edit by visual 2016.5.19
|
pid, // 进程pid //edit by visual 2016.5.19
|
||||||
PG_P | PG_USU | PG_RWW, //页目录的属性位(用户权限) //edit by visual 2016.5.26
|
PG_P | PG_USU | PG_RWW, // 页目录的属性位(用户权限) //edit by visual 2016.5.26
|
||||||
PG_P | PG_USS | PG_RWW); //页表的属性位(系统权限) //edit by visual 2016.5.17
|
PG_P | PG_USS | PG_RWW); // 页表的属性位(系统权限) //edit by visual 2016.5.17
|
||||||
if (err_temp != 0)
|
if (err_temp != 0)
|
||||||
{
|
{
|
||||||
disp_color_str("init_page_pte Error:lin_mapping_phy", 0x74);
|
kprintf("\x1b[31;47minit_page_pte Error:lin_mapping_phy\x1b[m");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -68,12 +68,12 @@ u32 init_page_pte(u32 pid)
|
|||||||
/*======================================================================*
|
/*======================================================================*
|
||||||
page_fault_handle edit by visual 2016.5.9
|
page_fault_handle edit by visual 2016.5.9
|
||||||
*======================================================================*/
|
*======================================================================*/
|
||||||
void page_fault_handler(u32 vec_no, //异常编号,此时应该是14,代表缺页异常
|
void page_fault_handler(u32 vec_no, // 异常编号,此时应该是14,代表缺页异常
|
||||||
u32 err_code, //错误码
|
u32 err_code, // 错误码
|
||||||
u32 eip, //导致缺页的指令的线性地址
|
u32 eip, // 导致缺页的指令的线性地址
|
||||||
u32 cs, //发生错误时的代码段寄存器内容
|
u32 cs, // 发生错误时的代码段寄存器内容
|
||||||
u32 eflags) //时发生错误的标志寄存器内容
|
u32 eflags) // 时发生错误的标志寄存器内容
|
||||||
{ //缺页中断处理函数
|
{ // 缺页中断处理函数
|
||||||
u32 pde_addr_phy_temp;
|
u32 pde_addr_phy_temp;
|
||||||
u32 pte_addr_phy_temp;
|
u32 pte_addr_phy_temp;
|
||||||
u32 cr2;
|
u32 cr2;
|
||||||
@ -89,29 +89,29 @@ void page_fault_handler(u32 vec_no, //异常编号,此时应该是14,代
|
|||||||
halt();
|
halt();
|
||||||
}
|
}
|
||||||
|
|
||||||
//获取该进程页目录物理地址
|
// 获取该进程页目录物理地址
|
||||||
pde_addr_phy_temp = get_pde_phy_addr(p_proc_current->task.pid);
|
pde_addr_phy_temp = get_pde_phy_addr(p_proc_current->task.pid);
|
||||||
//获取该线性地址对应的页表的物理地址
|
// 获取该线性地址对应的页表的物理地址
|
||||||
pte_addr_phy_temp = get_pte_phy_addr(p_proc_current->task.pid, cr2);
|
pte_addr_phy_temp = get_pte_phy_addr(p_proc_current->task.pid, cr2);
|
||||||
|
|
||||||
kprintf("\n");
|
kprintf("\n");
|
||||||
kprintf("\033[91;47m Page Fault\033[0m in %d\n", p_proc_current->task.pid);
|
kprintf("\033[91;47m Page Fault\033[0m in %d\n", p_proc_current->task.pid);
|
||||||
kprintf("\033[91meip=0x%08x, eflags=0x%x, CS=0x%x, ERR=0x%x, CR2=0x%08x\033[0m\n", eip, eflags, cs, err_code, cr2);
|
kprintf("\033[91meip=0x%08x, eflags=0x%x, CS=0x%x, ERR=0x%x, CR2=0x%08x\033[0m\n", eip, eflags, cs, err_code, cr2);
|
||||||
kprintf("\033[91mCR3=0x%08x, PDE=%p, PTE=%p\033[0m\n",
|
kprintf("\033[91mCR3=0x%08x, PDE=%p, PTE=%p\033[0m\n",
|
||||||
p_proc_current->task.cr3,
|
p_proc_current->task.cr3,
|
||||||
*((u32 *)K_PHY2LIN(pde_addr_phy_temp) + get_pde_index(cr2)),
|
*((u32 *)K_PHY2LIN(pde_addr_phy_temp) + get_pde_index(cr2)),
|
||||||
*((u32 *)K_PHY2LIN(pte_addr_phy_temp) + get_pte_index(cr2)));
|
*((u32 *)K_PHY2LIN(pte_addr_phy_temp) + get_pte_index(cr2)));
|
||||||
disable_int();
|
disable_int();
|
||||||
halt();
|
halt();
|
||||||
|
|
||||||
if (0 == pte_exist(pde_addr_phy_temp, cr2))
|
if (0 == pte_exist(pde_addr_phy_temp, cr2))
|
||||||
{ //页表不存在
|
{ // 页表不存在
|
||||||
// kprintf("\033[91;47m[PDE FAULT]\033[0m in %d\n",p_proc_current->task.pid);
|
// kprintf("\033[91;47m[PDE FAULT]\033[0m in %d\n",p_proc_current->task.pid);
|
||||||
(*((u32 *)K_PHY2LIN(pde_addr_phy_temp) + get_pde_index(cr2))) |= PG_P;
|
(*((u32 *)K_PHY2LIN(pde_addr_phy_temp) + get_pde_index(cr2))) |= PG_P;
|
||||||
// kprintf("\033[92;47m[Solved]\033[0m in %d\n",p_proc_current->task.pid);
|
// kprintf("\033[92;47m[Solved]\033[0m in %d\n",p_proc_current->task.pid);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ //只是缺少物理页
|
{ // 只是缺少物理页
|
||||||
// kprintf("\033[91;47m[PTE FAULT]\033[0m in %d\n",p_proc_current->task.pid);
|
// kprintf("\033[91;47m[PTE FAULT]\033[0m in %d\n",p_proc_current->task.pid);
|
||||||
(*((u32 *)K_PHY2LIN(pte_addr_phy_temp) + get_pte_index(cr2))) |= PG_P;
|
(*((u32 *)K_PHY2LIN(pte_addr_phy_temp) + get_pte_index(cr2))) |= PG_P;
|
||||||
// kprintf("\033[92;47m[Solved]\033[0m in %d\n",p_proc_current->task.pid);
|
// kprintf("\033[92;47m[Solved]\033[0m in %d\n",p_proc_current->task.pid);
|
||||||
@ -134,25 +134,25 @@ void page_fault_handler(u32 vec_no, //异常编号,此时应该是14,代
|
|||||||
get_pde_index add by visual 2016.4.28
|
get_pde_index add by visual 2016.4.28
|
||||||
*======================================================================*/
|
*======================================================================*/
|
||||||
inline u32 get_pde_index(u32 AddrLin)
|
inline u32 get_pde_index(u32 AddrLin)
|
||||||
{ //由 线性地址 得到 页目录项编号
|
{ // 由 线性地址 得到 页目录项编号
|
||||||
return (AddrLin >> 22); //高10位A31~A22
|
return (AddrLin >> 22); // 高10位A31~A22
|
||||||
}
|
}
|
||||||
|
|
||||||
/*======================================================================*
|
/*======================================================================*
|
||||||
get_pte_index add by visual 2016.4.28
|
get_pte_index add by visual 2016.4.28
|
||||||
*======================================================================*/
|
*======================================================================*/
|
||||||
inline u32 get_pte_index(u32 AddrLin)
|
inline u32 get_pte_index(u32 AddrLin)
|
||||||
{ //由 线性地址 得到 页表项编号
|
{ // 由 线性地址 得到 页表项编号
|
||||||
return (((AddrLin)&0x003FFFFF) >> 12); //中间10位A21~A12,0x3FFFFF = 0000 0000 0011 1111 1111 1111 1111 1111
|
return (((AddrLin)&0x003FFFFF) >> 12); // 中间10位A21~A12,0x3FFFFF = 0000 0000 0011 1111 1111 1111 1111 1111
|
||||||
}
|
}
|
||||||
|
|
||||||
/*======================================================================*
|
/*======================================================================*
|
||||||
get_pde_phy_addr add by visual 2016.4.28
|
get_pde_phy_addr add by visual 2016.4.28
|
||||||
*======================================================================*/
|
*======================================================================*/
|
||||||
inline u32 get_pde_phy_addr(u32 pid)
|
inline u32 get_pde_phy_addr(u32 pid)
|
||||||
{ //获取页目录物理地址
|
{ // 获取页目录物理地址
|
||||||
if (proc_table[pid].task.cr3 == 0)
|
if (proc_table[pid].task.cr3 == 0)
|
||||||
{ //还没有初始化页目录
|
{ // 还没有初始化页目录
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -164,19 +164,19 @@ inline u32 get_pde_phy_addr(u32 pid)
|
|||||||
/*======================================================================*
|
/*======================================================================*
|
||||||
get_pte_phy_addr add by visual 2016.4.28
|
get_pte_phy_addr add by visual 2016.4.28
|
||||||
*======================================================================*/
|
*======================================================================*/
|
||||||
inline u32 get_pte_phy_addr(u32 pid, //页目录物理地址 //edit by visual 2016.5.19
|
inline u32 get_pte_phy_addr(u32 pid, // 页目录物理地址 //edit by visual 2016.5.19
|
||||||
u32 AddrLin) //线性地址
|
u32 AddrLin) // 线性地址
|
||||||
{ //获取该线性地址所属页表的物理地址
|
{ // 获取该线性地址所属页表的物理地址
|
||||||
u32 PageDirPhyAddr = get_pde_phy_addr(pid); // add by visual 2016.5.19
|
u32 PageDirPhyAddr = get_pde_phy_addr(pid); // add by visual 2016.5.19
|
||||||
return (*((u32 *)K_PHY2LIN(PageDirPhyAddr) + get_pde_index(AddrLin))) & 0xFFFFF000; //先找到该进程页目录首地址,然后计算出该线性地址对应的页目录项,再访问,最后注意4k对齐
|
return (*((u32 *)K_PHY2LIN(PageDirPhyAddr) + get_pde_index(AddrLin))) & 0xFFFFF000; // 先找到该进程页目录首地址,然后计算出该线性地址对应的页目录项,再访问,最后注意4k对齐
|
||||||
}
|
}
|
||||||
|
|
||||||
/*======================================================================*
|
/*======================================================================*
|
||||||
get_page_phy_addr add by visual 2016.5.9
|
get_page_phy_addr add by visual 2016.5.9
|
||||||
*======================================================================*/
|
*======================================================================*/
|
||||||
inline u32 get_page_phy_addr(u32 pid, //页表物理地址 //edit by visual 2016.5.19
|
inline u32 get_page_phy_addr(u32 pid, // 页表物理地址 //edit by visual 2016.5.19
|
||||||
u32 AddrLin) //线性地址
|
u32 AddrLin) // 线性地址
|
||||||
{ //获取该线性地址对应的物理页物理地址
|
{ // 获取该线性地址对应的物理页物理地址
|
||||||
u32 PageTblPhyAddr = get_pte_phy_addr(pid, AddrLin); // add by visual 2016.5.19
|
u32 PageTblPhyAddr = get_pte_phy_addr(pid, AddrLin); // add by visual 2016.5.19
|
||||||
return (*((u32 *)K_PHY2LIN(PageTblPhyAddr) + get_pte_index(AddrLin))) & 0xFFFFF000;
|
return (*((u32 *)K_PHY2LIN(PageTblPhyAddr) + get_pte_index(AddrLin))) & 0xFFFFF000;
|
||||||
}
|
}
|
||||||
@ -184,11 +184,11 @@ inline u32 get_page_phy_addr(u32 pid, //页表物理地址 //edit by vi
|
|||||||
/*======================================================================*
|
/*======================================================================*
|
||||||
pte_exist add by visual 2016.4.28
|
pte_exist add by visual 2016.4.28
|
||||||
*======================================================================*/
|
*======================================================================*/
|
||||||
u32 pte_exist(u32 PageDirPhyAddr, //页目录物理地址
|
u32 pte_exist(u32 PageDirPhyAddr, // 页目录物理地址
|
||||||
u32 AddrLin) //线性地址
|
u32 AddrLin) // 线性地址
|
||||||
{ //判断 有没有 页表
|
{ // 判断 有没有 页表
|
||||||
if ((0x00000001 & (*((u32 *)K_PHY2LIN(PageDirPhyAddr) + get_pde_index(AddrLin)))) == 0) //先找到该进程页目录,然后计算出该线性地址对应的页目录项,访问并判断其是否存在
|
if ((0x00000001 & (*((u32 *)K_PHY2LIN(PageDirPhyAddr) + get_pde_index(AddrLin)))) == 0) // 先找到该进程页目录,然后计算出该线性地址对应的页目录项,访问并判断其是否存在
|
||||||
{ //标志位为0,不存在
|
{ // 标志位为0,不存在
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -200,11 +200,11 @@ u32 pte_exist(u32 PageDirPhyAddr, //页目录物理地址
|
|||||||
/*======================================================================*
|
/*======================================================================*
|
||||||
phy_exist add by visual 2016.4.28
|
phy_exist add by visual 2016.4.28
|
||||||
*======================================================================*/
|
*======================================================================*/
|
||||||
u32 phy_exist(u32 PageTblPhyAddr, //页表物理地址
|
u32 phy_exist(u32 PageTblPhyAddr, // 页表物理地址
|
||||||
u32 AddrLin) //线性地址
|
u32 AddrLin) // 线性地址
|
||||||
{ //判断 该线性地址 有没有 对应的 物理页
|
{ // 判断 该线性地址 有没有 对应的 物理页
|
||||||
if ((0x00000001 & (*((u32 *)K_PHY2LIN(PageTblPhyAddr) + get_pte_index(AddrLin)))) == 0)
|
if ((0x00000001 & (*((u32 *)K_PHY2LIN(PageTblPhyAddr) + get_pte_index(AddrLin)))) == 0)
|
||||||
{ //标志位为0,不存在
|
{ // 标志位为0,不存在
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -216,25 +216,25 @@ u32 phy_exist(u32 PageTblPhyAddr, //页表物理地址
|
|||||||
/*======================================================================*
|
/*======================================================================*
|
||||||
write_page_pde add by visual 2016.4.28
|
write_page_pde add by visual 2016.4.28
|
||||||
*======================================================================*/
|
*======================================================================*/
|
||||||
void write_page_pde(u32 PageDirPhyAddr, //页目录物理地址
|
void write_page_pde(u32 PageDirPhyAddr, // 页目录物理地址
|
||||||
u32 AddrLin, //线性地址
|
u32 AddrLin, // 线性地址
|
||||||
u32 TblPhyAddr, //要填写的页表的物理地址(函数会进行4k对齐)
|
u32 TblPhyAddr, // 要填写的页表的物理地址(函数会进行4k对齐)
|
||||||
u32 Attribute) //属性
|
u32 Attribute) // 属性
|
||||||
{ //填写页目录
|
{ // 填写页目录
|
||||||
(*((u32 *)K_PHY2LIN(PageDirPhyAddr) + get_pde_index(AddrLin))) = (TblPhyAddr & 0xFFFFF000) | Attribute;
|
(*((u32 *)K_PHY2LIN(PageDirPhyAddr) + get_pde_index(AddrLin))) = (TblPhyAddr & 0xFFFFF000) | Attribute;
|
||||||
//进程页目录起始地址+每一项的大小*所属的项
|
// 进程页目录起始地址+每一项的大小*所属的项
|
||||||
}
|
}
|
||||||
|
|
||||||
/*======================================================================*
|
/*======================================================================*
|
||||||
write_page_pte add by visual 2016.4.28
|
write_page_pte add by visual 2016.4.28
|
||||||
*======================================================================*/
|
*======================================================================*/
|
||||||
void write_page_pte(u32 TblPhyAddr, //页表物理地址
|
void write_page_pte(u32 TblPhyAddr, // 页表物理地址
|
||||||
u32 AddrLin, //线性地址
|
u32 AddrLin, // 线性地址
|
||||||
u32 PhyAddr, //要填写的物理页物理地址(任意的物理地址,函数会进行4k对齐)
|
u32 PhyAddr, // 要填写的物理页物理地址(任意的物理地址,函数会进行4k对齐)
|
||||||
u32 Attribute) //属性
|
u32 Attribute) // 属性
|
||||||
{ //填写页目录,会添加属性
|
{ // 填写页目录,会添加属性
|
||||||
(*((u32 *)K_PHY2LIN(TblPhyAddr) + get_pte_index(AddrLin))) = (PhyAddr & 0xFFFFF000) | Attribute;
|
(*((u32 *)K_PHY2LIN(TblPhyAddr) + get_pte_index(AddrLin))) = (PhyAddr & 0xFFFFF000) | Attribute;
|
||||||
//页表起始地址+一项的大小*所属的项
|
// 页表起始地址+一项的大小*所属的项
|
||||||
}
|
}
|
||||||
|
|
||||||
/*======================================================================*
|
/*======================================================================*
|
||||||
@ -245,12 +245,12 @@ u32 vmalloc(u32 size)
|
|||||||
{
|
{
|
||||||
u32 temp;
|
u32 temp;
|
||||||
if (p_proc_current->task.info.type == TYPE_PROCESS)
|
if (p_proc_current->task.info.type == TYPE_PROCESS)
|
||||||
{ //进程直接就是标识
|
{ // 进程直接就是标识
|
||||||
temp = p_proc_current->task.memmap.heap_lin_limit;
|
temp = p_proc_current->task.memmap.heap_lin_limit;
|
||||||
p_proc_current->task.memmap.heap_lin_limit += size;
|
p_proc_current->task.memmap.heap_lin_limit += size;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ //线程需要取父进程的标识
|
{ // 线程需要取父进程的标识
|
||||||
temp = *((u32 *)p_proc_current->task.memmap.heap_lin_limit);
|
temp = *((u32 *)p_proc_current->task.memmap.heap_lin_limit);
|
||||||
(*((u32 *)p_proc_current->task.memmap.heap_lin_limit)) += size;
|
(*((u32 *)p_proc_current->task.memmap.heap_lin_limit)) += size;
|
||||||
}
|
}
|
||||||
@ -262,70 +262,69 @@ u32 vmalloc(u32 size)
|
|||||||
* lin_mapping_phy add by visual 2016.5.9
|
* lin_mapping_phy add by visual 2016.5.9
|
||||||
*将线性地址映射到物理地址上去,函数内部会分配物理地址
|
*将线性地址映射到物理地址上去,函数内部会分配物理地址
|
||||||
*======================================================================*/
|
*======================================================================*/
|
||||||
int lin_mapping_phy(u32 AddrLin, //线性地址
|
int lin_mapping_phy(u32 AddrLin, // 线性地址
|
||||||
u32 phy_addr, //物理地址,若为MAX_UNSIGNED_INT(0xFFFFFFFF),则表示需要由该函数判断是否分配物理地址,否则将phy_addr直接和AddrLin建立映射
|
u32 phy_addr, // 物理地址,若为MAX_UNSIGNED_INT(0xFFFFFFFF),则表示需要由该函数判断是否分配物理地址,否则将phy_addr直接和AddrLin建立映射
|
||||||
u32 pid, //进程pid //edit by visual 2016.5.19
|
u32 pid, // 进程pid //edit by visual 2016.5.19
|
||||||
u32 pde_Attribute, //页目录中的属性位
|
u32 pde_Attribute, // 页目录中的属性位
|
||||||
u32 pte_Attribute) //页表中的属性位
|
u32 pte_Attribute) // 页表中的属性位
|
||||||
{
|
{
|
||||||
u32 pte_addr_phy;
|
u32 pte_addr_phy;
|
||||||
u32 pde_addr_phy = get_pde_phy_addr(pid); // add by visual 2016.5.19
|
u32 pde_addr_phy = get_pde_phy_addr(pid); // add by visual 2016.5.19
|
||||||
|
|
||||||
if (0 == pte_exist(pde_addr_phy, AddrLin))
|
if (0 == pte_exist(pde_addr_phy, AddrLin))
|
||||||
{ //页表不存在,创建一个,并填进页目录中
|
{ // 页表不存在,创建一个,并填进页目录中
|
||||||
pte_addr_phy = (u32)do_kmalloc_4k(); //为页表申请一页
|
pte_addr_phy = (u32)do_kmalloc_4k(); // 为页表申请一页
|
||||||
memset((void *)K_PHY2LIN(pte_addr_phy), 0, num_4K); // add by visual 2016.5.26
|
memset((void *)K_PHY2LIN(pte_addr_phy), 0, num_4K); // add by visual 2016.5.26
|
||||||
|
|
||||||
if (pte_addr_phy < 0 || (pte_addr_phy & 0x3FF) != 0) // add by visual 2016.5.9
|
if (pte_addr_phy < 0 || (pte_addr_phy & 0x3FF) != 0) // add by visual 2016.5.9
|
||||||
{
|
{
|
||||||
disp_color_str("lin_mapping_phy Error:pte_addr_phy", 0x74);
|
kprintf("\x1b[31;47mlin_mapping_phy Error:pte_addr_phy\x1b[m");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
write_page_pde(pde_addr_phy, //页目录物理地址
|
write_page_pde(pde_addr_phy, // 页目录物理地址
|
||||||
AddrLin, //线性地址
|
AddrLin, // 线性地址
|
||||||
pte_addr_phy, //页表物理地址
|
pte_addr_phy, // 页表物理地址
|
||||||
pde_Attribute); //属性
|
pde_Attribute); // 属性
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ //页表存在,获取该页表物理地址
|
{ // 页表存在,获取该页表物理地址
|
||||||
pte_addr_phy = get_pte_phy_addr(pid, //进程pid //edit by visual 2016.5.19
|
pte_addr_phy = get_pte_phy_addr(pid, // 进程pid //edit by visual 2016.5.19
|
||||||
AddrLin); //线性地址
|
AddrLin); // 线性地址
|
||||||
}
|
}
|
||||||
|
|
||||||
if (MAX_UNSIGNED_INT == phy_addr) // add by visual 2016.5.19
|
if (MAX_UNSIGNED_INT == phy_addr) // add by visual 2016.5.19
|
||||||
{ //由函数申请内存
|
{ // 由函数申请内存
|
||||||
if (0 == phy_exist(pte_addr_phy, AddrLin))
|
if (0 == phy_exist(pte_addr_phy, AddrLin))
|
||||||
{ //无物理页,申请物理页并修改phy_addr
|
{ // 无物理页,申请物理页并修改phy_addr
|
||||||
if (AddrLin >= K_PHY2LIN(0))
|
if (AddrLin >= K_PHY2LIN(0))
|
||||||
phy_addr = do_kmalloc_4k(); //从内核物理地址申请一页
|
phy_addr = do_kmalloc_4k(); // 从内核物理地址申请一页
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// disp_str("%");
|
phy_addr = do_malloc_4k(); // 从用户物理地址空间申请一页
|
||||||
phy_addr = do_malloc_4k(); //从用户物理地址空间申请一页
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//有物理页,什么也不做,直接返回,必须返回
|
// 有物理页,什么也不做,直接返回,必须返回
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ //指定填写phy_addr
|
{ // 指定填写phy_addr
|
||||||
//不用修改phy_addr
|
// 不用修改phy_addr
|
||||||
}
|
}
|
||||||
|
|
||||||
if (phy_addr < 0 || (phy_addr & 0x3FF) != 0)
|
if (phy_addr < 0 || (phy_addr & 0x3FF) != 0)
|
||||||
{
|
{
|
||||||
disp_color_str("lin_mapping_phy:phy_addr ERROR", 0x74);
|
kprintf("\x1b[31;47mlin_mapping_phy:phy_addr ERROR\x1b[m");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
write_page_pte(pte_addr_phy, //页表物理地址
|
write_page_pte(pte_addr_phy, // 页表物理地址
|
||||||
AddrLin, //线性地址
|
AddrLin, // 线性地址
|
||||||
phy_addr, //物理页物理地址
|
phy_addr, // 物理页物理地址
|
||||||
pte_Attribute); //属性
|
pte_Attribute); // 属性
|
||||||
refresh_page_cache();
|
refresh_page_cache();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -338,7 +337,7 @@ int lin_mapping_phy(u32 AddrLin, //线性地址
|
|||||||
void clear_kernel_pagepte_low()
|
void clear_kernel_pagepte_low()
|
||||||
{
|
{
|
||||||
u32 page_num = *(u32 *)PageTblNumAddr;
|
u32 page_num = *(u32 *)PageTblNumAddr;
|
||||||
memset((void *)(K_PHY2LIN(KernelPageTblAddr)), 0, 4 * page_num); //从内核页目录中清除内核页目录项前8项
|
memset((void *)(K_PHY2LIN(KernelPageTblAddr)), 0, 4 * page_num); // 从内核页目录中清除内核页目录项前8项
|
||||||
memset((void *)(K_PHY2LIN(KernelPageTblAddr + 0x1000)), 0, 4096 * page_num); //从内核页表中清除线性地址的低端映射关系
|
memset((void *)(K_PHY2LIN(KernelPageTblAddr + 0x1000)), 0, 4096 * page_num); // 从内核页表中清除线性地址的低端映射关系
|
||||||
refresh_page_cache();
|
refresh_page_cache();
|
||||||
}
|
}
|
||||||
|
|||||||
400
kernel/protect.c
400
kernel/protect.c
@ -1,8 +1,8 @@
|
|||||||
|
|
||||||
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
protect.c
|
protect.c
|
||||||
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
Forrest Yu, 2005
|
Forrest Yu, 2005
|
||||||
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
|
||||||
|
|
||||||
#include "type.h"
|
#include "type.h"
|
||||||
@ -13,49 +13,46 @@
|
|||||||
#include "proto.h"
|
#include "proto.h"
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
|
|
||||||
|
|
||||||
/* 本文件内函数声明 */
|
/* 本文件内函数声明 */
|
||||||
static void init_idt_desc(unsigned char vector, u8 desc_type, int_handler handler, unsigned char privilege);
|
static void init_idt_desc(unsigned char vector, u8 desc_type, int_handler handler, unsigned char privilege);
|
||||||
static void init_descriptor(DESCRIPTOR * p_desc, u32 base, u32 limit, u16 attribute);
|
static void init_descriptor(DESCRIPTOR *p_desc, u32 base, u32 limit, u16 attribute);
|
||||||
|
|
||||||
|
|
||||||
/* 中断处理函数 */
|
/* 中断处理函数 */
|
||||||
void divide_error();
|
void divide_error();
|
||||||
void single_step_exception();
|
void single_step_exception();
|
||||||
void nmi();
|
void nmi();
|
||||||
void breakpoint_exception();
|
void breakpoint_exception();
|
||||||
void overflow();
|
void overflow();
|
||||||
void bounds_check();
|
void bounds_check();
|
||||||
void inval_opcode();
|
void inval_opcode();
|
||||||
void copr_not_available();
|
void copr_not_available();
|
||||||
void double_fault();
|
void double_fault();
|
||||||
void copr_seg_overrun();
|
void copr_seg_overrun();
|
||||||
void inval_tss();
|
void inval_tss();
|
||||||
void segment_not_present();
|
void segment_not_present();
|
||||||
void stack_exception();
|
void stack_exception();
|
||||||
void general_protection();
|
void general_protection();
|
||||||
void page_fault();
|
void page_fault();
|
||||||
void copr_error();
|
void copr_error();
|
||||||
void hwint00();
|
void hwint00();
|
||||||
void hwint01();
|
void hwint01();
|
||||||
void hwint02();
|
void hwint02();
|
||||||
void hwint03();
|
void hwint03();
|
||||||
void hwint04();
|
void hwint04();
|
||||||
void hwint05();
|
void hwint05();
|
||||||
void hwint06();
|
void hwint06();
|
||||||
void hwint07();
|
void hwint07();
|
||||||
void hwint08();
|
void hwint08();
|
||||||
void hwint09();
|
void hwint09();
|
||||||
void hwint10();
|
void hwint10();
|
||||||
void hwint11();
|
void hwint11();
|
||||||
void hwint12();
|
void hwint12();
|
||||||
void hwint13();
|
void hwint13();
|
||||||
void hwint14();
|
void hwint14();
|
||||||
void hwint15();
|
void hwint15();
|
||||||
|
|
||||||
|
|
||||||
/*======================================================================*
|
/*======================================================================*
|
||||||
init_prot
|
init_prot
|
||||||
*----------------------------------------------------------------------*
|
*----------------------------------------------------------------------*
|
||||||
初始化 IDT
|
初始化 IDT
|
||||||
*======================================================================*/
|
*======================================================================*/
|
||||||
@ -64,271 +61,270 @@ void init_prot()
|
|||||||
init_8259A();
|
init_8259A();
|
||||||
|
|
||||||
// 全部初始化成中断门(没有陷阱门)
|
// 全部初始化成中断门(没有陷阱门)
|
||||||
init_idt_desc(INT_VECTOR_DIVIDE, DA_386IGate,
|
init_idt_desc(INT_VECTOR_DIVIDE, DA_386IGate,
|
||||||
divide_error, PRIVILEGE_KRNL);
|
divide_error, PRIVILEGE_KRNL);
|
||||||
|
|
||||||
init_idt_desc(INT_VECTOR_DEBUG, DA_386IGate,
|
init_idt_desc(INT_VECTOR_DEBUG, DA_386IGate,
|
||||||
single_step_exception, PRIVILEGE_KRNL);
|
single_step_exception, PRIVILEGE_KRNL);
|
||||||
|
|
||||||
init_idt_desc(INT_VECTOR_NMI, DA_386IGate,
|
init_idt_desc(INT_VECTOR_NMI, DA_386IGate,
|
||||||
nmi, PRIVILEGE_KRNL);
|
nmi, PRIVILEGE_KRNL);
|
||||||
|
|
||||||
init_idt_desc(INT_VECTOR_BREAKPOINT, DA_386IGate,
|
init_idt_desc(INT_VECTOR_BREAKPOINT, DA_386IGate,
|
||||||
breakpoint_exception, PRIVILEGE_USER);
|
breakpoint_exception, PRIVILEGE_USER);
|
||||||
|
|
||||||
init_idt_desc(INT_VECTOR_OVERFLOW, DA_386IGate,
|
init_idt_desc(INT_VECTOR_OVERFLOW, DA_386IGate,
|
||||||
overflow, PRIVILEGE_USER);
|
overflow, PRIVILEGE_USER);
|
||||||
|
|
||||||
init_idt_desc(INT_VECTOR_BOUNDS, DA_386IGate,
|
init_idt_desc(INT_VECTOR_BOUNDS, DA_386IGate,
|
||||||
bounds_check, PRIVILEGE_KRNL);
|
bounds_check, PRIVILEGE_KRNL);
|
||||||
|
|
||||||
init_idt_desc(INT_VECTOR_INVAL_OP, DA_386IGate,
|
init_idt_desc(INT_VECTOR_INVAL_OP, DA_386IGate,
|
||||||
inval_opcode, PRIVILEGE_KRNL);
|
inval_opcode, PRIVILEGE_KRNL);
|
||||||
|
|
||||||
init_idt_desc(INT_VECTOR_COPROC_NOT, DA_386IGate,
|
init_idt_desc(INT_VECTOR_COPROC_NOT, DA_386IGate,
|
||||||
copr_not_available, PRIVILEGE_KRNL);
|
copr_not_available, PRIVILEGE_KRNL);
|
||||||
|
|
||||||
init_idt_desc(INT_VECTOR_DOUBLE_FAULT, DA_386IGate,
|
init_idt_desc(INT_VECTOR_DOUBLE_FAULT, DA_386IGate,
|
||||||
double_fault, PRIVILEGE_KRNL);
|
double_fault, PRIVILEGE_KRNL);
|
||||||
|
|
||||||
init_idt_desc(INT_VECTOR_COPROC_SEG, DA_386IGate,
|
init_idt_desc(INT_VECTOR_COPROC_SEG, DA_386IGate,
|
||||||
copr_seg_overrun, PRIVILEGE_KRNL);
|
copr_seg_overrun, PRIVILEGE_KRNL);
|
||||||
|
|
||||||
init_idt_desc(INT_VECTOR_INVAL_TSS, DA_386IGate,
|
init_idt_desc(INT_VECTOR_INVAL_TSS, DA_386IGate,
|
||||||
inval_tss, PRIVILEGE_KRNL);
|
inval_tss, PRIVILEGE_KRNL);
|
||||||
|
|
||||||
init_idt_desc(INT_VECTOR_SEG_NOT, DA_386IGate,
|
init_idt_desc(INT_VECTOR_SEG_NOT, DA_386IGate,
|
||||||
segment_not_present, PRIVILEGE_KRNL);
|
segment_not_present, PRIVILEGE_KRNL);
|
||||||
|
|
||||||
init_idt_desc(INT_VECTOR_STACK_FAULT, DA_386IGate,
|
init_idt_desc(INT_VECTOR_STACK_FAULT, DA_386IGate,
|
||||||
stack_exception, PRIVILEGE_KRNL);
|
stack_exception, PRIVILEGE_KRNL);
|
||||||
|
|
||||||
init_idt_desc(INT_VECTOR_PROTECTION, DA_386IGate,
|
init_idt_desc(INT_VECTOR_PROTECTION, DA_386IGate,
|
||||||
general_protection, PRIVILEGE_KRNL);
|
general_protection, PRIVILEGE_KRNL);
|
||||||
|
|
||||||
init_idt_desc(INT_VECTOR_PAGE_FAULT, DA_386IGate,
|
init_idt_desc(INT_VECTOR_PAGE_FAULT, DA_386IGate,
|
||||||
page_fault, PRIVILEGE_KRNL);
|
page_fault, PRIVILEGE_KRNL);
|
||||||
|
|
||||||
init_idt_desc(INT_VECTOR_COPROC_ERR, DA_386IGate,
|
init_idt_desc(INT_VECTOR_COPROC_ERR, DA_386IGate,
|
||||||
copr_error, PRIVILEGE_KRNL);
|
copr_error, PRIVILEGE_KRNL);
|
||||||
|
|
||||||
init_idt_desc(INT_VECTOR_IRQ0 + 0, DA_386IGate,
|
init_idt_desc(INT_VECTOR_IRQ0 + 0, DA_386IGate,
|
||||||
hwint00, PRIVILEGE_KRNL);
|
hwint00, PRIVILEGE_KRNL);
|
||||||
|
|
||||||
init_idt_desc(INT_VECTOR_IRQ0 + 1, DA_386IGate,
|
init_idt_desc(INT_VECTOR_IRQ0 + 1, DA_386IGate,
|
||||||
hwint01, PRIVILEGE_KRNL);
|
hwint01, PRIVILEGE_KRNL);
|
||||||
|
|
||||||
init_idt_desc(INT_VECTOR_IRQ0 + 2, DA_386IGate,
|
init_idt_desc(INT_VECTOR_IRQ0 + 2, DA_386IGate,
|
||||||
hwint02, PRIVILEGE_KRNL);
|
hwint02, PRIVILEGE_KRNL);
|
||||||
|
|
||||||
init_idt_desc(INT_VECTOR_IRQ0 + 3, DA_386IGate,
|
init_idt_desc(INT_VECTOR_IRQ0 + 3, DA_386IGate,
|
||||||
hwint03, PRIVILEGE_KRNL);
|
hwint03, PRIVILEGE_KRNL);
|
||||||
|
|
||||||
init_idt_desc(INT_VECTOR_IRQ0 + 4, DA_386IGate,
|
init_idt_desc(INT_VECTOR_IRQ0 + 4, DA_386IGate,
|
||||||
hwint04, PRIVILEGE_KRNL);
|
hwint04, PRIVILEGE_KRNL);
|
||||||
|
|
||||||
init_idt_desc(INT_VECTOR_IRQ0 + 5, DA_386IGate,
|
init_idt_desc(INT_VECTOR_IRQ0 + 5, DA_386IGate,
|
||||||
hwint05, PRIVILEGE_KRNL);
|
hwint05, PRIVILEGE_KRNL);
|
||||||
|
|
||||||
init_idt_desc(INT_VECTOR_IRQ0 + 6, DA_386IGate,
|
init_idt_desc(INT_VECTOR_IRQ0 + 6, DA_386IGate,
|
||||||
hwint06, PRIVILEGE_KRNL);
|
hwint06, PRIVILEGE_KRNL);
|
||||||
|
|
||||||
init_idt_desc(INT_VECTOR_IRQ0 + 7, DA_386IGate,
|
init_idt_desc(INT_VECTOR_IRQ0 + 7, DA_386IGate,
|
||||||
hwint07, PRIVILEGE_KRNL);
|
hwint07, PRIVILEGE_KRNL);
|
||||||
|
|
||||||
init_idt_desc(INT_VECTOR_IRQ8 + 0, DA_386IGate,
|
init_idt_desc(INT_VECTOR_IRQ8 + 0, DA_386IGate,
|
||||||
hwint08, PRIVILEGE_KRNL);
|
hwint08, PRIVILEGE_KRNL);
|
||||||
|
|
||||||
init_idt_desc(INT_VECTOR_IRQ8 + 1, DA_386IGate,
|
init_idt_desc(INT_VECTOR_IRQ8 + 1, DA_386IGate,
|
||||||
hwint09, PRIVILEGE_KRNL);
|
hwint09, PRIVILEGE_KRNL);
|
||||||
|
|
||||||
init_idt_desc(INT_VECTOR_IRQ8 + 2, DA_386IGate,
|
init_idt_desc(INT_VECTOR_IRQ8 + 2, DA_386IGate,
|
||||||
hwint10, PRIVILEGE_KRNL);
|
hwint10, PRIVILEGE_KRNL);
|
||||||
|
|
||||||
init_idt_desc(INT_VECTOR_IRQ8 + 3, DA_386IGate,
|
init_idt_desc(INT_VECTOR_IRQ8 + 3, DA_386IGate,
|
||||||
hwint11, PRIVILEGE_KRNL);
|
hwint11, PRIVILEGE_KRNL);
|
||||||
|
|
||||||
init_idt_desc(INT_VECTOR_IRQ8 + 4, DA_386IGate,
|
init_idt_desc(INT_VECTOR_IRQ8 + 4, DA_386IGate,
|
||||||
hwint12, PRIVILEGE_KRNL);
|
hwint12, PRIVILEGE_KRNL);
|
||||||
|
|
||||||
init_idt_desc(INT_VECTOR_IRQ8 + 5, DA_386IGate,
|
init_idt_desc(INT_VECTOR_IRQ8 + 5, DA_386IGate,
|
||||||
hwint13, PRIVILEGE_KRNL);
|
hwint13, PRIVILEGE_KRNL);
|
||||||
|
|
||||||
init_idt_desc(INT_VECTOR_IRQ8 + 6, DA_386IGate,
|
init_idt_desc(INT_VECTOR_IRQ8 + 6, DA_386IGate,
|
||||||
hwint14, PRIVILEGE_KRNL);
|
hwint14, PRIVILEGE_KRNL);
|
||||||
|
|
||||||
init_idt_desc(INT_VECTOR_IRQ8 + 7, DA_386IGate,
|
init_idt_desc(INT_VECTOR_IRQ8 + 7, DA_386IGate,
|
||||||
hwint15, PRIVILEGE_KRNL);
|
hwint15, PRIVILEGE_KRNL);
|
||||||
|
|
||||||
init_idt_desc(INT_VECTOR_SYS_CALL, DA_386IGate,
|
init_idt_desc(INT_VECTOR_SYS_CALL, DA_386IGate,
|
||||||
sys_call, PRIVILEGE_USER);
|
sys_call, PRIVILEGE_USER);
|
||||||
|
|
||||||
/*修改显存描述符*/ //add by visual 2016.5.12
|
/*修改显存描述符*/ // add by visual 2016.5.12
|
||||||
init_descriptor(&gdt[INDEX_VIDEO],
|
init_descriptor(&gdt[INDEX_VIDEO],
|
||||||
K_PHY2LIN(0x0B8000),
|
K_PHY2LIN(0x0B8000),
|
||||||
0x0ffff,
|
0x0ffff,
|
||||||
DA_DRW | DA_DPL3);
|
DA_DRW | DA_DPL3);
|
||||||
|
|
||||||
/* 填充 GDT 中 TSS 这个描述符 */
|
/* 填充 GDT 中 TSS 这个描述符 */
|
||||||
memset(&tss, 0, sizeof(tss));
|
memset(&tss, 0, sizeof(tss));
|
||||||
tss.ss0 = SELECTOR_KERNEL_DS;
|
tss.ss0 = SELECTOR_KERNEL_DS;
|
||||||
init_descriptor(&gdt[INDEX_TSS],
|
init_descriptor(&gdt[INDEX_TSS],
|
||||||
vir2phys(seg2phys(SELECTOR_KERNEL_DS), &tss),
|
vir2phys(seg2phys(SELECTOR_KERNEL_DS), &tss),
|
||||||
sizeof(tss) - 1,
|
sizeof(tss) - 1,
|
||||||
DA_386TSS);
|
DA_386TSS);
|
||||||
tss.iobase = sizeof(tss); /* 没有I/O许可位图 */
|
tss.iobase = sizeof(tss); /* 没有I/O许可位图 */
|
||||||
|
|
||||||
// 填充 GDT 中进程的 LDT 的描述符
|
// 填充 GDT 中进程的 LDT 的描述符
|
||||||
int i;
|
int i;
|
||||||
PROCESS* p_proc = proc_table;
|
PROCESS *p_proc = proc_table;
|
||||||
u16 selector_ldt = INDEX_LDT_FIRST << 3;
|
u16 selector_ldt = INDEX_LDT_FIRST << 3;
|
||||||
for(i=0;i<NR_PCBS;i++){ //edit by visual 2016.4.5
|
for (i = 0; i < NR_PCBS; i++)
|
||||||
init_descriptor(&gdt[selector_ldt>>3],
|
{ // edit by visual 2016.4.5
|
||||||
vir2phys(seg2phys(SELECTOR_KERNEL_DS),proc_table[i].task.ldts),
|
init_descriptor(&gdt[selector_ldt >> 3],
|
||||||
LDT_SIZE * sizeof(DESCRIPTOR) - 1,
|
vir2phys(seg2phys(SELECTOR_KERNEL_DS), proc_table[i].task.ldts),
|
||||||
DA_LDT);
|
LDT_SIZE * sizeof(DESCRIPTOR) - 1,
|
||||||
|
DA_LDT);
|
||||||
p_proc++;
|
p_proc++;
|
||||||
selector_ldt += 1 << 3;
|
selector_ldt += 1 << 3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*======================================================================*
|
/*======================================================================*
|
||||||
init_idt_desc
|
init_idt_desc
|
||||||
*----------------------------------------------------------------------*
|
*----------------------------------------------------------------------*
|
||||||
初始化 386 中断门
|
初始化 386 中断门
|
||||||
*======================================================================*/
|
*======================================================================*/
|
||||||
void init_idt_desc(unsigned char vector, u8 desc_type, int_handler handler, unsigned char privilege)
|
void init_idt_desc(unsigned char vector, u8 desc_type, int_handler handler, unsigned char privilege)
|
||||||
{
|
{
|
||||||
GATE * p_gate = &idt[vector];
|
GATE *p_gate = &idt[vector];
|
||||||
u32 base = (u32)handler;
|
u32 base = (u32)handler;
|
||||||
p_gate->offset_low = base & 0xFFFF;
|
p_gate->offset_low = base & 0xFFFF;
|
||||||
p_gate->selector = SELECTOR_KERNEL_CS;
|
p_gate->selector = SELECTOR_KERNEL_CS;
|
||||||
p_gate->dcount = 0;
|
p_gate->dcount = 0;
|
||||||
p_gate->attr = desc_type | (privilege << 5);
|
p_gate->attr = desc_type | (privilege << 5);
|
||||||
p_gate->offset_high = (base >> 16) & 0xFFFF;
|
p_gate->offset_high = (base >> 16) & 0xFFFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*======================================================================*
|
/*======================================================================*
|
||||||
seg2phys
|
seg2phys
|
||||||
*----------------------------------------------------------------------*
|
*----------------------------------------------------------------------*
|
||||||
由段名求绝对地址
|
由段名求绝对地址
|
||||||
*======================================================================*/
|
*======================================================================*/
|
||||||
u32 seg2phys(u16 seg)
|
u32 seg2phys(u16 seg)
|
||||||
{
|
{
|
||||||
DESCRIPTOR* p_dest = &gdt[seg >> 3];
|
DESCRIPTOR *p_dest = &gdt[seg >> 3];
|
||||||
|
|
||||||
return (p_dest->base_high << 24) | (p_dest->base_mid << 16) | (p_dest->base_low);
|
return (p_dest->base_high << 24) | (p_dest->base_mid << 16) | (p_dest->base_low);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*======================================================================*
|
/*======================================================================*
|
||||||
init_descriptor
|
init_descriptor
|
||||||
*----------------------------------------------------------------------*
|
*----------------------------------------------------------------------*
|
||||||
初始化段描述符
|
初始化段描述符
|
||||||
*======================================================================*/
|
*======================================================================*/
|
||||||
static void init_descriptor(DESCRIPTOR * p_desc, u32 base, u32 limit, u16 attribute)
|
static void init_descriptor(DESCRIPTOR *p_desc, u32 base, u32 limit, u16 attribute)
|
||||||
{
|
{
|
||||||
p_desc->limit_low = limit & 0x0FFFF; // 段界限 1 (2 字节)
|
p_desc->limit_low = limit & 0x0FFFF; // 段界限 1 (2 字节)
|
||||||
p_desc->base_low = base & 0x0FFFF; // 段基址 1 (2 字节)
|
p_desc->base_low = base & 0x0FFFF; // 段基址 1 (2 字节)
|
||||||
p_desc->base_mid = (base >> 16) & 0x0FF; // 段基址 2 (1 字节)
|
p_desc->base_mid = (base >> 16) & 0x0FF; // 段基址 2 (1 字节)
|
||||||
p_desc->attr1 = attribute & 0xFF; // 属性 1
|
p_desc->attr1 = attribute & 0xFF; // 属性 1
|
||||||
p_desc->limit_high_attr2 = ((limit >> 16) & 0x0F) |
|
p_desc->limit_high_attr2 = ((limit >> 16) & 0x0F) |
|
||||||
((attribute >> 8) & 0xF0);// 段界限 2 + 属性 2
|
((attribute >> 8) & 0xF0); // 段界限 2 + 属性 2
|
||||||
p_desc->base_high = (base >> 24) & 0x0FF; // 段基址 3 (1 字节)
|
p_desc->base_high = (base >> 24) & 0x0FF; // 段基址 3 (1 字节)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*======================================================================*
|
/*======================================================================*
|
||||||
exception_handler
|
exception_handler
|
||||||
*----------------------------------------------------------------------*
|
*----------------------------------------------------------------------*
|
||||||
异常处理
|
异常处理
|
||||||
*======================================================================*/
|
*======================================================================*/
|
||||||
void exception_handler(int vec_no, int err_code, int eip, int cs, int eflags)
|
void exception_handler(int vec_no, int err_code, int eip, int cs, int eflags)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int text_color = 0x74; /* 灰底红字 */
|
int text_color = 0x74; /* 灰底红字 */
|
||||||
char err_description[][64] = { "#DE Divide Error",
|
char err_description[][64] = {"#DE Divide Error",
|
||||||
"#DB RESERVED",
|
"#DB RESERVED",
|
||||||
"— NMI Interrupt",
|
"— NMI Interrupt",
|
||||||
"#BP Breakpoint",
|
"#BP Breakpoint",
|
||||||
"#OF Overflow",
|
"#OF Overflow",
|
||||||
"#BR BOUND Range Exceeded",
|
"#BR BOUND Range Exceeded",
|
||||||
"#UD Invalid Opcode (Undefined Opcode)",
|
"#UD Invalid Opcode (Undefined Opcode)",
|
||||||
"#NM Device Not Available (No Math Coprocessor)",
|
"#NM Device Not Available (No Math Coprocessor)",
|
||||||
"#DF Double Fault",
|
"#DF Double Fault",
|
||||||
" Coprocessor Segment Overrun (reserved)",
|
" Coprocessor Segment Overrun (reserved)",
|
||||||
"#TS Invalid TSS",
|
"#TS Invalid TSS",
|
||||||
"#NP Segment Not Present",
|
"#NP Segment Not Present",
|
||||||
"#SS Stack-Segment Fault",
|
"#SS Stack-Segment Fault",
|
||||||
"#GP General Protection",
|
"#GP General Protection",
|
||||||
"#PF Page Fault",
|
"#PF Page Fault",
|
||||||
"— (Intel reserved. Do not use.)",
|
"— (Intel reserved. Do not use.)",
|
||||||
"#MF x87 FPU Floating-Point Error (Math Fault)",
|
"#MF x87 FPU Floating-Point Error (Math Fault)",
|
||||||
"#AC Alignment Check",
|
"#AC Alignment Check",
|
||||||
"#MC Machine Check",
|
"#MC Machine Check",
|
||||||
"#XF SIMD Floating-Point Exception"
|
"#XF SIMD Floating-Point Exception"};
|
||||||
};
|
|
||||||
|
|
||||||
/* 通过打印空格的方式清空屏幕的前五行,并把 disp_pos 清零 */
|
/* 通过打印空格的方式清空屏幕的前五行,并把 disp_pos 清零 */
|
||||||
disp_pos = 0;
|
disp_pos = 0;
|
||||||
for(i=0;i<80*5;i++){
|
for (i = 0; i < 80 * 5; i++)
|
||||||
disp_str(" ");
|
{
|
||||||
|
printf(" ");
|
||||||
}
|
}
|
||||||
disp_pos = 0;
|
disp_pos = 0;
|
||||||
|
|
||||||
disp_color_str("Exception! --> ", text_color);
|
printf("\x1b[31;47mException! --> ");
|
||||||
disp_color_str(err_description[vec_no], text_color);
|
printf(err_description[vec_no]);
|
||||||
disp_color_str("\n\n", text_color);
|
printf("\n\n");
|
||||||
disp_color_str("EFLAGS:", text_color);
|
printf("EFLAGS:\x1b[m");
|
||||||
disp_int(eflags);
|
printf("%d", eflags);
|
||||||
disp_color_str("CS:", text_color);
|
printf("\x1b[31;47mCS:\x1b[m");
|
||||||
disp_int(cs);
|
printf("%d", cs);
|
||||||
disp_color_str("EIP:", text_color);
|
printf("\x1b[31;47mEIP:\x1b[m");
|
||||||
disp_int(eip);
|
printf("%d", eip);
|
||||||
|
|
||||||
if(err_code != 0xFFFFFFFF){
|
if (err_code != 0xFFFFFFFF)
|
||||||
disp_color_str("Error code:", text_color);
|
{
|
||||||
disp_int(err_code);
|
printf("\x1b[31;47mError code:\x1b[m");
|
||||||
|
printf("%d", err_code);
|
||||||
}
|
}
|
||||||
|
|
||||||
//added by xw, 18/12/19
|
|
||||||
disp_str("\n");
|
|
||||||
|
|
||||||
//added by xw, 18/12/19
|
// added by xw, 18/12/19
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
// added by xw, 18/12/19
|
||||||
p_proc_current->task.stat = KILLED;
|
p_proc_current->task.stat = KILLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*======================================================================*
|
/*======================================================================*
|
||||||
divide error handler
|
divide error handler
|
||||||
*======================================================================*/
|
*======================================================================*/
|
||||||
//used for testing if a exception handler can be interrupted rightly, so it's
|
// used for testing if a exception handler can be interrupted rightly, so it's
|
||||||
//not a real divide_error handler now. added by xw, 18/12/22
|
// not a real divide_error handler now. added by xw, 18/12/22
|
||||||
void divide_error_handler()
|
void divide_error_handler()
|
||||||
{
|
{
|
||||||
int vec_no, err_code, eip, cs, eflags;
|
int vec_no, err_code, eip, cs, eflags;
|
||||||
int i, j;
|
int i, j;
|
||||||
|
|
||||||
asm volatile ( "mov 8(%%ebp), %0\n\t" //get vec_no from stack
|
asm volatile("mov 8(%%ebp), %0\n\t" // get vec_no from stack
|
||||||
"mov 12(%%ebp), %1\n\t" //get err_code from stack
|
"mov 12(%%ebp), %1\n\t" // get err_code from stack
|
||||||
"mov 16(%%ebp), %2\n\t" //get eip from stack
|
"mov 16(%%ebp), %2\n\t" // get eip from stack
|
||||||
"mov 20(%%ebp), %3\n\t" //get cs from stack
|
"mov 20(%%ebp), %3\n\t" // get cs from stack
|
||||||
"mov 24(%%ebp), %4\n\t" //get eflags from stack
|
"mov 24(%%ebp), %4\n\t" // get eflags from stack
|
||||||
: "=r"(vec_no), "=r"(err_code), "=r"(eip),
|
: "=r"(vec_no), "=r"(err_code), "=r"(eip),
|
||||||
"=r"(cs), "=r"(eflags)
|
"=r"(cs), "=r"(eflags));
|
||||||
);
|
|
||||||
exception_handler(vec_no, err_code, eip, cs, eflags);
|
exception_handler(vec_no, err_code, eip, cs, eflags);
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
disp_str("Loop in divide error handler...\n");
|
printf("Loop in divide error handler...\n");
|
||||||
|
|
||||||
i = 100;
|
i = 100;
|
||||||
while(--i){
|
while (--i)
|
||||||
|
{
|
||||||
j = 1000;
|
j = 1000;
|
||||||
while(--j){}
|
while (--j)
|
||||||
|
{
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
287
kernel/pthread.c
287
kernel/pthread.c
@ -1,7 +1,7 @@
|
|||||||
/******************************************************************
|
/******************************************************************
|
||||||
* pthread.c //add by visual 2016.5.26
|
* pthread.c //add by visual 2016.5.26
|
||||||
*系统调用pthread()
|
*系统调用pthread()
|
||||||
*******************************************************************/
|
*******************************************************************/
|
||||||
#include "type.h"
|
#include "type.h"
|
||||||
#include "const.h"
|
#include "const.h"
|
||||||
#include "protect.h"
|
#include "protect.h"
|
||||||
@ -10,204 +10,201 @@
|
|||||||
#include "global.h"
|
#include "global.h"
|
||||||
#include "proto.h"
|
#include "proto.h"
|
||||||
|
|
||||||
static int pthread_pcb_cpy(PROCESS *p_child,PROCESS *p_parent);
|
static int pthread_pcb_cpy(PROCESS *p_child, PROCESS *p_parent);
|
||||||
static int pthread_update_info(PROCESS *p_child,PROCESS *p_parent);
|
static int pthread_update_info(PROCESS *p_child, PROCESS *p_parent);
|
||||||
static int pthread_stack_init(PROCESS *p_child,PROCESS *p_parent);
|
static int pthread_stack_init(PROCESS *p_child, PROCESS *p_parent);
|
||||||
static int pthread_heap_init(PROCESS *p_child,PROCESS *p_parent);
|
static int pthread_heap_init(PROCESS *p_child, PROCESS *p_parent);
|
||||||
|
|
||||||
/**********************************************************
|
/**********************************************************
|
||||||
* sys_pthread //add by visual 2016.5.25
|
* sys_pthread //add by visual 2016.5.25
|
||||||
*系统调用sys_pthread的具体实现部分
|
*系统调用sys_pthread的具体实现部分
|
||||||
*************************************************************/
|
*************************************************************/
|
||||||
int sys_pthread(void *entry)
|
int sys_pthread(void *entry)
|
||||||
{
|
{
|
||||||
PROCESS* p_child;
|
PROCESS *p_child;
|
||||||
|
|
||||||
char* p_reg; //point to a register in the new kernel stack, added by xw, 17/12/11
|
char *p_reg; // point to a register in the new kernel stack, added by xw, 17/12/11
|
||||||
|
|
||||||
/*if(p_proc_current->task.info.type == TYPE_THREAD )
|
/*if(p_proc_current->task.info.type == TYPE_THREAD )
|
||||||
{//线程不能创建线程
|
{//线程不能创建线程
|
||||||
disp_color_str("[pthread failed:",0x74);
|
printf("\x1b[31;47m[pthread failed:");
|
||||||
disp_color_str(p_proc_current->task.p_name,0x74);
|
printf(p_proc_current->task.p_name);
|
||||||
disp_color_str("]",0x74);
|
printf("]\x1b[m");
|
||||||
return -1;
|
return -1;
|
||||||
}*/
|
}*/
|
||||||
/*****************申请空白PCB表**********************/
|
/*****************申请空白PCB表**********************/
|
||||||
p_child = alloc_PCB();
|
p_child = alloc_PCB();
|
||||||
if( 0==p_child )
|
if (0 == p_child)
|
||||||
{
|
{
|
||||||
disp_color_str("PCB NULL,pthread faild!",0x74);
|
printf("\x1b[31;47mPCB NULL,pthread faild!\x1b[m");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PROCESS *p_parent;
|
PROCESS *p_parent;
|
||||||
if( p_proc_current->task.info.type == TYPE_THREAD )
|
if (p_proc_current->task.info.type == TYPE_THREAD)
|
||||||
{//线程
|
{ // 线程
|
||||||
p_parent = &(proc_table[p_proc_current->task.info.ppid]);//父进程
|
p_parent = &(proc_table[p_proc_current->task.info.ppid]); // 父进程
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{//进程
|
{ // 进程
|
||||||
p_parent = p_proc_current;//父进程就是父线程
|
p_parent = p_proc_current; // 父进程就是父线程
|
||||||
}
|
}
|
||||||
/************复制父进程的PCB部分内容(保留了自己的标识信息,但cr3使用的是父进程的)**************/
|
/************复制父进程的PCB部分内容(保留了自己的标识信息,但cr3使用的是父进程的)**************/
|
||||||
pthread_pcb_cpy(p_child,p_parent);
|
pthread_pcb_cpy(p_child, p_parent);
|
||||||
|
|
||||||
/************在父进程的栈中分配子线程的栈(从进程栈的低地址分配8M,注意方向)**********************/
|
/************在父进程的栈中分配子线程的栈(从进程栈的低地址分配8M,注意方向)**********************/
|
||||||
pthread_stack_init(p_child,p_parent);
|
pthread_stack_init(p_child, p_parent);
|
||||||
|
|
||||||
/**************初始化子线程的堆(此时的这两个变量已经变成了指针)***********************/
|
/**************初始化子线程的堆(此时的这两个变量已经变成了指针)***********************/
|
||||||
pthread_heap_init(p_child,p_parent);
|
pthread_heap_init(p_child, p_parent);
|
||||||
|
|
||||||
/********************设置线程的执行入口**********************************************/
|
/********************设置线程的执行入口**********************************************/
|
||||||
p_child->task.regs.eip = (u32)entry;
|
p_child->task.regs.eip = (u32)entry;
|
||||||
p_reg = (char*)(p_child + 1); //added by xw, 17/12/11
|
p_reg = (char *)(p_child + 1); // added by xw, 17/12/11
|
||||||
*((u32*)(p_reg + EIPREG - P_STACKTOP)) = p_child->task.regs.eip; //added by xw, 17/12/11
|
*((u32 *)(p_reg + EIPREG - P_STACKTOP)) = p_child->task.regs.eip; // added by xw, 17/12/11
|
||||||
|
|
||||||
/**************更新进程树标识info信息************************/
|
/**************更新进程树标识info信息************************/
|
||||||
pthread_update_info(p_child,p_parent);
|
pthread_update_info(p_child, p_parent);
|
||||||
|
|
||||||
/************修改子进程的名字***************/
|
/************修改子进程的名字***************/
|
||||||
strcpy(p_child->task.p_name,"pthread"); // 所有的子进程都叫pthread
|
strcpy(p_child->task.p_name, "pthread"); // 所有的子进程都叫pthread
|
||||||
|
|
||||||
/*************子进程返回值在其eax寄存器***************/
|
/*************子进程返回值在其eax寄存器***************/
|
||||||
p_child->task.regs.eax = 0;//return child with 0
|
p_child->task.regs.eax = 0; // return child with 0
|
||||||
p_reg = (char*)(p_child + 1); //added by xw, 17/12/11
|
p_reg = (char *)(p_child + 1); // added by xw, 17/12/11
|
||||||
*((u32*)(p_reg + EAXREG - P_STACKTOP)) = p_child->task.regs.eax; //added by xw, 17/12/11
|
*((u32 *)(p_reg + EAXREG - P_STACKTOP)) = p_child->task.regs.eax; // added by xw, 17/12/11
|
||||||
|
|
||||||
/****************用户进程数+1****************************/
|
/****************用户进程数+1****************************/
|
||||||
u_proc_sum += 1;
|
u_proc_sum += 1;
|
||||||
|
|
||||||
disp_color_str("[pthread success:",0x72);
|
printf("\x1b[32;47m[pthread success:");
|
||||||
disp_color_str(p_proc_current->task.p_name,0x72);
|
printf(p_proc_current->task.p_name);
|
||||||
disp_color_str("]",0x72);
|
printf("]\x1b[m");
|
||||||
|
|
||||||
//anything child need is prepared now, set its state to ready. added by xw, 17/12/11
|
// anything child need is prepared now, set its state to ready. added by xw, 17/12/11
|
||||||
p_child->task.stat = READY;
|
p_child->task.stat = READY;
|
||||||
}
|
}
|
||||||
return p_child->task.pid;
|
return p_child->task.pid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**********************************************************
|
/**********************************************************
|
||||||
* pthread_pcb_cpy //add by visual 2016.5.26
|
* pthread_pcb_cpy //add by visual 2016.5.26
|
||||||
*复制父进程PCB表,但是又马上恢复了子进程的标识信息
|
*复制父进程PCB表,但是又马上恢复了子进程的标识信息
|
||||||
*************************************************************/
|
*************************************************************/
|
||||||
static int pthread_pcb_cpy(PROCESS *p_child,PROCESS *p_parent)
|
static int pthread_pcb_cpy(PROCESS *p_child, PROCESS *p_parent)
|
||||||
{
|
{
|
||||||
int pid;
|
int pid;
|
||||||
u32 eflags,selector_ldt;
|
u32 eflags, selector_ldt;
|
||||||
char* p_reg; //point to a register in the new kernel stack, added by xw, 17/12/11
|
char *p_reg; // point to a register in the new kernel stack, added by xw, 17/12/11
|
||||||
char *esp_save_int, *esp_save_context; //use to save corresponding field in child's PCB, xw, 18/4/21
|
char *esp_save_int, *esp_save_context; // use to save corresponding field in child's PCB, xw, 18/4/21
|
||||||
|
|
||||||
//暂存标识信息
|
// 暂存标识信息
|
||||||
pid = p_child->task.pid;
|
pid = p_child->task.pid;
|
||||||
|
|
||||||
//eflags = p_child->task.regs.eflags; //deleted by xw, 17/12/11
|
// eflags = p_child->task.regs.eflags; //deleted by xw, 17/12/11
|
||||||
p_reg = (char*)(p_child + 1); //added by xw, 17/12/11
|
p_reg = (char *)(p_child + 1); // added by xw, 17/12/11
|
||||||
eflags = *((u32*)(p_reg + EFLAGSREG - P_STACKTOP)); //added by xw, 17/12/11
|
eflags = *((u32 *)(p_reg + EFLAGSREG - P_STACKTOP)); // added by xw, 17/12/11
|
||||||
|
|
||||||
selector_ldt = p_child->task.ldt_sel;
|
selector_ldt = p_child->task.ldt_sel;
|
||||||
|
|
||||||
//复制PCB内容
|
// 复制PCB内容
|
||||||
//modified by xw, 17/12/11
|
// modified by xw, 17/12/11
|
||||||
//modified begin
|
// modified begin
|
||||||
//*p_child = *p_parent;
|
//*p_child = *p_parent;
|
||||||
|
|
||||||
//esp_save_int and esp_save_context must be saved, because the child and the parent
|
// esp_save_int and esp_save_context must be saved, because the child and the parent
|
||||||
//use different kernel stack! And these two are importent to the child's initial running.
|
// use different kernel stack! And these two are importent to the child's initial running.
|
||||||
//Added by xw, 18/4/21
|
// Added by xw, 18/4/21
|
||||||
esp_save_int = p_child->task.esp_save_int;
|
esp_save_int = p_child->task.esp_save_int;
|
||||||
esp_save_context = p_child->task.esp_save_context;
|
esp_save_context = p_child->task.esp_save_context;
|
||||||
p_child->task = p_parent->task;
|
p_child->task = p_parent->task;
|
||||||
//note that syscalls can be interrupted now! the state of child can only be setted
|
// note that syscalls can be interrupted now! the state of child can only be setted
|
||||||
//READY when anything else is well prepared. if an interruption happens right here,
|
// READY when anything else is well prepared. if an interruption happens right here,
|
||||||
//an error will still occur.
|
// an error will still occur.
|
||||||
p_child->task.stat = IDLE;
|
p_child->task.stat = IDLE;
|
||||||
p_child->task.esp_save_int = esp_save_int; //esp_save_int of child must be restored!!
|
p_child->task.esp_save_int = esp_save_int; // esp_save_int of child must be restored!!
|
||||||
p_child->task.esp_save_context = esp_save_context; //same above
|
p_child->task.esp_save_context = esp_save_context; // same above
|
||||||
memcpy(((char*)(p_child + 1) - P_STACKTOP), ((char*)(p_parent + 1) - P_STACKTOP), 18 * 4);
|
memcpy(((char *)(p_child + 1) - P_STACKTOP), ((char *)(p_parent + 1) - P_STACKTOP), 18 * 4);
|
||||||
//modified end
|
// modified end
|
||||||
|
|
||||||
//恢复标识信息
|
// 恢复标识信息
|
||||||
p_child->task.pid = pid;
|
p_child->task.pid = pid;
|
||||||
|
|
||||||
//p_child->task.regs.eflags = eflags;
|
// p_child->task.regs.eflags = eflags;
|
||||||
p_reg = (char*)(p_child + 1); //added by xw, 17/12/11
|
p_reg = (char *)(p_child + 1); // added by xw, 17/12/11
|
||||||
*((u32*)(p_reg + EFLAGSREG - P_STACKTOP)) = eflags; //added by xw, 17/12/11
|
*((u32 *)(p_reg + EFLAGSREG - P_STACKTOP)) = eflags; // added by xw, 17/12/11
|
||||||
|
|
||||||
p_child->task.ldt_sel = selector_ldt;
|
p_child->task.ldt_sel = selector_ldt;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**********************************************************
|
/**********************************************************
|
||||||
* pthread_update_info //add by visual 2016.5.26
|
* pthread_update_info //add by visual 2016.5.26
|
||||||
*更新父进程和子线程程的进程树标识info
|
*更新父进程和子线程程的进程树标识info
|
||||||
*************************************************************/
|
*************************************************************/
|
||||||
static int pthread_update_info(PROCESS* p_child,PROCESS *p_parent)
|
static int pthread_update_info(PROCESS *p_child, PROCESS *p_parent)
|
||||||
{
|
{
|
||||||
/************更新父进程的info***************///注意 父进程 父进程 父进程
|
/************更新父进程的info***************/ // 注意 父进程 父进程 父进程
|
||||||
if( p_parent!=p_proc_current )
|
if (p_parent != p_proc_current)
|
||||||
{//只有在线程创建线程的时候才会执行 ,p_parent事实上是父进程
|
{ // 只有在线程创建线程的时候才会执行 ,p_parent事实上是父进程
|
||||||
p_parent->task.info.child_t_num += 1; //子线程数量
|
p_parent->task.info.child_t_num += 1; // 子线程数量
|
||||||
p_parent->task.info.child_thread[p_parent->task.info.child_t_num-1] = p_child->task.pid;//子线程列表
|
p_parent->task.info.child_thread[p_parent->task.info.child_t_num - 1] = p_child->task.pid; // 子线程列表
|
||||||
}
|
}
|
||||||
/************更新父线程的info**************/
|
/************更新父线程的info**************/
|
||||||
//p_proc_current->task.info.type; //当前是进程还是线程
|
// p_proc_current->task.info.type; //当前是进程还是线程
|
||||||
//p_proc_current->task.info.real_ppid; //亲父进程,创建它的那个进程
|
// p_proc_current->task.info.real_ppid; //亲父进程,创建它的那个进程
|
||||||
//p_proc_current->task.info.ppid; //当前父进程
|
// p_proc_current->task.info.ppid; //当前父进程
|
||||||
//p_proc_current->task.info.child_p_num += 1; //子进程数量
|
// p_proc_current->task.info.child_p_num += 1; //子进程数量
|
||||||
//p_proc_current->task.info.child_process[p_proc_current->task.info.child_p_num-1] = p_child->task.pid;//子进程列表
|
// p_proc_current->task.info.child_process[p_proc_current->task.info.child_p_num-1] = p_child->task.pid;//子进程列表
|
||||||
p_proc_current->task.info.child_t_num += 1; //子线程数量
|
p_proc_current->task.info.child_t_num += 1; // 子线程数量
|
||||||
p_proc_current->task.info.child_thread[p_proc_current->task.info.child_t_num-1] = p_child->task.pid;//子线程列表
|
p_proc_current->task.info.child_thread[p_proc_current->task.info.child_t_num - 1] = p_child->task.pid; // 子线程列表
|
||||||
//p_proc_current->task.text_hold; //是否拥有代码
|
// p_proc_current->task.text_hold; //是否拥有代码
|
||||||
//p_proc_current->task.data_hold; //是否拥有数据
|
// p_proc_current->task.data_hold; //是否拥有数据
|
||||||
|
|
||||||
/************更新子线程的info***************/
|
/************更新子线程的info***************/
|
||||||
p_child->task.info.type = TYPE_THREAD ;//这是一个线程
|
p_child->task.info.type = TYPE_THREAD; // 这是一个线程
|
||||||
p_child->task.info.real_ppid = p_proc_current->task.pid; //亲父进程,创建它的那个线程,注意,这个是创建它的那个线程p_proc_current
|
p_child->task.info.real_ppid = p_proc_current->task.pid; // 亲父进程,创建它的那个线程,注意,这个是创建它的那个线程p_proc_current
|
||||||
p_child->task.info.ppid = p_parent->task.pid; //当前父进程
|
p_child->task.info.ppid = p_parent->task.pid; // 当前父进程
|
||||||
p_child->task.info.child_p_num = 0; //子进程数量
|
p_child->task.info.child_p_num = 0; // 子进程数量
|
||||||
//p_child->task.info.child_process[NR_CHILD_MAX] = pid;//子进程列表
|
// p_child->task.info.child_process[NR_CHILD_MAX] = pid;//子进程列表
|
||||||
p_child->task.info.child_t_num = 0; //子线程数量
|
p_child->task.info.child_t_num = 0; // 子线程数量
|
||||||
//p_child->task.info.child_thread[NR_CHILD_MAX];//子线程列表
|
// p_child->task.info.child_thread[NR_CHILD_MAX];//子线程列表
|
||||||
p_child->task.info.text_hold = 0; //是否拥有代码,子进程不拥有代码
|
p_child->task.info.text_hold = 0; // 是否拥有代码,子进程不拥有代码
|
||||||
p_child->task.info.data_hold = 0; //是否拥有数据,子进程拥有数据
|
p_child->task.info.data_hold = 0; // 是否拥有数据,子进程拥有数据
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**********************************************************
|
/**********************************************************
|
||||||
* pthread_stack_init //add by visual 2016.5.26
|
* pthread_stack_init //add by visual 2016.5.26
|
||||||
*申请子线程的栈,并重置其esp
|
*申请子线程的栈,并重置其esp
|
||||||
*************************************************************/
|
*************************************************************/
|
||||||
static int pthread_stack_init(PROCESS* p_child,PROCESS *p_parent)
|
static int pthread_stack_init(PROCESS *p_child, PROCESS *p_parent)
|
||||||
{
|
{
|
||||||
int addr_lin;
|
int addr_lin;
|
||||||
char* p_reg; //point to a register in the new kernel stack, added by xw, 17/12/11
|
char *p_reg; // point to a register in the new kernel stack, added by xw, 17/12/11
|
||||||
|
|
||||||
p_child->task.memmap.stack_lin_limit = p_parent->task.memmap.stack_child_limit;//子线程的栈界
|
p_child->task.memmap.stack_lin_limit = p_parent->task.memmap.stack_child_limit; // 子线程的栈界
|
||||||
p_parent->task.memmap.stack_child_limit += 0x4000; //分配16K
|
p_parent->task.memmap.stack_child_limit += 0x4000; // 分配16K
|
||||||
p_child->task.memmap.stack_lin_base = p_parent->task.memmap.stack_child_limit - num_4B; //子线程的基址
|
p_child->task.memmap.stack_lin_base = p_parent->task.memmap.stack_child_limit - num_4B; // 子线程的基址
|
||||||
|
|
||||||
for( addr_lin=p_child->task.memmap.stack_lin_base ; addr_lin>p_child->task.memmap.stack_lin_limit ; addr_lin-=num_4K)//申请物理地址
|
for (addr_lin = p_child->task.memmap.stack_lin_base; addr_lin > p_child->task.memmap.stack_lin_limit; addr_lin -= num_4K) // 申请物理地址
|
||||||
lin_mapping_phy(addr_lin,MAX_UNSIGNED_INT,p_child->task.pid,PG_P | PG_USU | PG_RWW,PG_P | PG_USU | PG_RWW);
|
lin_mapping_phy(addr_lin, MAX_UNSIGNED_INT, p_child->task.pid, PG_P | PG_USU | PG_RWW, PG_P | PG_USU | PG_RWW);
|
||||||
|
|
||||||
p_child->task.regs.esp = p_child->task.memmap.stack_lin_base; //调整esp
|
p_child->task.regs.esp = p_child->task.memmap.stack_lin_base; // 调整esp
|
||||||
p_reg = (char*)(p_child + 1); //added by xw, 17/12/11
|
p_reg = (char *)(p_child + 1); // added by xw, 17/12/11
|
||||||
*((u32*)(p_reg + ESPREG - P_STACKTOP)) = p_child->task.regs.esp; //added by xw, 17/12/11
|
*((u32 *)(p_reg + ESPREG - P_STACKTOP)) = p_child->task.regs.esp; // added by xw, 17/12/11
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/**********************************************************
|
/**********************************************************
|
||||||
* pthread_stack_init //add by visual 2016.5.26
|
* pthread_stack_init //add by visual 2016.5.26
|
||||||
*子线程使用父进程的堆
|
*子线程使用父进程的堆
|
||||||
*************************************************************/
|
*************************************************************/
|
||||||
static int pthread_heap_init(PROCESS* p_child,PROCESS *p_parent)
|
static int pthread_heap_init(PROCESS *p_child, PROCESS *p_parent)
|
||||||
{
|
{
|
||||||
p_child->task.memmap.heap_lin_base = (u32)&(p_parent->task.memmap.heap_lin_base);
|
p_child->task.memmap.heap_lin_base = (u32) & (p_parent->task.memmap.heap_lin_base);
|
||||||
p_child->task.memmap.heap_lin_limit = (u32)&(p_parent->task.memmap.heap_lin_limit);
|
p_child->task.memmap.heap_lin_limit = (u32) & (p_parent->task.memmap.heap_lin_limit);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,27 +12,30 @@
|
|||||||
#include "global.h"
|
#include "global.h"
|
||||||
#include "proto.h"
|
#include "proto.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This syscall needs long time to finish, so we can use it
|
* This syscall needs long time to finish, so we can use it
|
||||||
* to check if our os is kernel-preemptive.
|
* to check if our os is kernel-preemptive.
|
||||||
* added by xw, 18/4/27
|
* added by xw, 18/4/27
|
||||||
*/
|
*/
|
||||||
void sys_print_E()
|
void sys_print_E()
|
||||||
{
|
{
|
||||||
int i, j;
|
int i, j;
|
||||||
|
|
||||||
disp_str("E( ");
|
printf("E( ");
|
||||||
|
|
||||||
i = 100;
|
i = 100;
|
||||||
while(--i){
|
while (--i)
|
||||||
|
{
|
||||||
j = 1000;
|
j = 1000;
|
||||||
while(--j){}
|
while (--j)
|
||||||
|
{
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
disp_str(") ");
|
printf(") ");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This syscall needs long time to finish, so we can use it
|
* This syscall needs long time to finish, so we can use it
|
||||||
* to check if our os is kernel-preemptive.
|
* to check if our os is kernel-preemptive.
|
||||||
* added by xw, 18/4/27
|
* added by xw, 18/4/27
|
||||||
@ -40,14 +43,17 @@ void sys_print_E()
|
|||||||
void sys_print_F()
|
void sys_print_F()
|
||||||
{
|
{
|
||||||
int i, j;
|
int i, j;
|
||||||
|
|
||||||
disp_str("F( ");
|
printf("F( ");
|
||||||
|
|
||||||
i = 100;
|
i = 100;
|
||||||
while(--i){
|
while (--i)
|
||||||
|
{
|
||||||
j = 1000;
|
j = 1000;
|
||||||
while(--j){}
|
while (--j)
|
||||||
|
{
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
disp_str(") ");
|
printf(") ");
|
||||||
}
|
}
|
||||||
|
|||||||
@ -127,7 +127,7 @@ void vga_tty_init(NTTY *tty)
|
|||||||
assert(tty->driver_type == 1);
|
assert(tty->driver_type == 1);
|
||||||
assert(tty->output_buf);
|
assert(tty->output_buf);
|
||||||
vga_buf *vga = tty->output_buf;
|
vga_buf *vga = tty->output_buf;
|
||||||
vga->buf = (void*)K_PHY2LIN(do_kmalloc(sizeof(u16) * SCR_BUFSIZE));
|
vga->buf = (void *)K_PHY2LIN(do_kmalloc(sizeof(u16) * SCR_BUFSIZE));
|
||||||
// vga->buf = (void *)pagebuf[_cnt++];
|
// vga->buf = (void *)pagebuf[_cnt++];
|
||||||
// kprintf("malloced %p %p %p\n", vga->buf, &vga->buf, &vga->scr_top_line);
|
// kprintf("malloced %p %p %p\n", vga->buf, &vga->buf, &vga->scr_top_line);
|
||||||
vga->cur_col = vga->cur_row = 0;
|
vga->cur_col = vga->cur_row = 0;
|
||||||
@ -357,7 +357,7 @@ static void set_color(vga_buf *vgabuf)
|
|||||||
{
|
{
|
||||||
warn("unsupport CSI: color");
|
warn("unsupport CSI: color");
|
||||||
}
|
}
|
||||||
if (vgabuf->CSI == CSI_PARAM2)
|
if (vgabuf->Is2param == true)
|
||||||
{
|
{
|
||||||
if (vgabuf->param2 == 0 && vgabuf->param1 == 0)
|
if (vgabuf->param2 == 0 && vgabuf->param1 == 0)
|
||||||
{
|
{
|
||||||
@ -564,6 +564,7 @@ void vga_tty_write(NTTY *tty, char ch)
|
|||||||
break;
|
break;
|
||||||
case '\x1b':
|
case '\x1b':
|
||||||
vga->CSI = CSI_BRACKET;
|
vga->CSI = CSI_BRACKET;
|
||||||
|
vga->Is2param = false;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (vga->color == 0)
|
if (vga->color == 0)
|
||||||
@ -615,6 +616,7 @@ void vga_tty_write(NTTY *tty, char ch)
|
|||||||
break;
|
break;
|
||||||
case ';':
|
case ';':
|
||||||
vga->CSI = CSI_PARAM2;
|
vga->CSI = CSI_PARAM2;
|
||||||
|
vga->Is2param = true;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (!(0x20 <= ch && ch <= 0x7e))
|
if (!(0x20 <= ch && ch <= 0x7e))
|
||||||
|
|||||||
@ -6,31 +6,23 @@
|
|||||||
#include "tty.h"
|
#include "tty.h"
|
||||||
#include "serialport.h"
|
#include "serialport.h"
|
||||||
|
|
||||||
static void serialputch(int ch, void * cnt) {
|
static void serialputch(int ch, void *cnt)
|
||||||
write_serial(ch);
|
|
||||||
// char _ch = ch;
|
|
||||||
// tty_write(cur_ntty, &_ch, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
kprintfputch(int ch, void *b)
|
|
||||||
{
|
{
|
||||||
char buf[2]={(char)ch,'\0'};
|
// write_serial(ch);
|
||||||
disp_str(buf);
|
char _ch = ch;
|
||||||
|
tty_write(cur_ntty, &_ch, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int vkprintf(const char *fmt, va_list ap)
|
||||||
vkprintf(const char *fmt, va_list ap)
|
|
||||||
{
|
{
|
||||||
|
|
||||||
// vprintfmt((void*)kprintfputch, NULL, fmt, ap);
|
// vprintfmt((void*)kprintfputch, NULL, fmt, ap);
|
||||||
vprintfmt((void*)serialputch, NULL, fmt, ap);
|
vprintfmt((void *)serialputch, NULL, fmt, ap);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int kprintf(const char *fmt, ...)
|
||||||
kprintf(const char *fmt, ...)
|
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
int rc;
|
int rc;
|
||||||
|
|||||||
10
user/test.c
10
user/test.c
@ -34,16 +34,18 @@ int main(int arg, char *argv[])
|
|||||||
// printf("8888888888");
|
// printf("8888888888");
|
||||||
// printf("9999999999\r\b\b\n");
|
// printf("9999999999\r\b\b\n");
|
||||||
// }
|
// }
|
||||||
printf("\x1b[36m");
|
printf("\x1b[33m");
|
||||||
|
|
||||||
for (int i = 0; i < 40; i++)
|
for (int i = 0; i < 40; i++)
|
||||||
{
|
{
|
||||||
printf("%d", i);
|
printf("%d", i);
|
||||||
printf("11111111111111111\n");
|
printf("11111111111111111\n");
|
||||||
}
|
}
|
||||||
|
printf("\x1b[31;47mexec: path ERROR!\x1b[m");
|
||||||
printf("555555");
|
printf("555555");
|
||||||
|
|
||||||
// Cursor Up
|
// Cursor Up
|
||||||
printf("\x1b[2A");
|
// printf("\x1b[2A");
|
||||||
|
|
||||||
// Cursor down
|
// Cursor down
|
||||||
// printf("\x1b[2B");
|
// printf("\x1b[2B");
|
||||||
@ -52,7 +54,7 @@ int main(int arg, char *argv[])
|
|||||||
// printf("\x1b[20C");
|
// printf("\x1b[20C");
|
||||||
|
|
||||||
// Cursor Back
|
// Cursor Back
|
||||||
printf("\x1b[2D");
|
// printf("\x1b[2D");
|
||||||
|
|
||||||
// Cursor Next Line
|
// Cursor Next Line
|
||||||
// printf("\x1b[3E");
|
// printf("\x1b[3E");
|
||||||
@ -70,7 +72,7 @@ int main(int arg, char *argv[])
|
|||||||
// printf("\x1b[3J");
|
// printf("\x1b[3J");
|
||||||
|
|
||||||
// Erase in Line
|
// Erase in Line
|
||||||
printf("\x1b[K");
|
// printf("\x1b[K");
|
||||||
|
|
||||||
// Scroll Up
|
// Scroll Up
|
||||||
// printf("\x1b[13S");
|
// printf("\x1b[13S");
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user