replace disp_*

This commit is contained in:
xiaoxiao 2023-01-02 12:45:23 +08:00
parent f9ed0ed420
commit f70a22b8c2
13 changed files with 1288 additions and 1265 deletions

View File

@ -49,7 +49,6 @@ typedef struct s_tty
struct s_console *console;
} TTY;
typedef struct n_tty
{
int driver_type; // 1-vga&kbd; 2-serial
@ -75,21 +74,24 @@ typedef struct vga_buf
int cur_row;
int cur_col; // cursor position, on screen
bool Is2param;
enum CSI_state CSI;
i16 param1; // the first param of CSI
i16 param2; // the second of CSI
u16 color;
} vga_buf;
typedef struct keyboard_buf {
void* buf; // 1d array, buffer input virtual line, works as a ldisc
typedef struct keyboard_buf
{
void *buf; // 1d array, buffer input virtual line, works as a ldisc
int tail;
int head;
int len;
int readable;
} keyboard_buf;
typedef struct serial_buf {
typedef struct serial_buf
{
void *buf;
int tail;
int head;
@ -104,27 +106,26 @@ void init_screen(TTY *tty);
void out_char(CONSOLE *con, char ch);
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_write(NTTY* tty, char ch);
void vga_tty_flush(NTTY* tty);
void vga_tty_backspace(NTTY* tty);
void vga_tty_init(NTTY *tty);
void vga_tty_write(NTTY *tty, char ch);
void vga_tty_flush(NTTY *tty);
void vga_tty_backspace(NTTY *tty);
void vga_tty_scroll(NTTY *tty, int direction);
void vga_tty_select(NTTY *tty);
void ps2_tty_init(NTTY* tty);
int ps2_tty_read(NTTY* tty, char* buf, int nr);
void ps2_tty_init(NTTY *tty);
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 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 BACKGROUND(color) ((u16)(color & 0xf) << 12)
// extern int cur_ntty;
extern NTTY* cur_ntty;
extern NTTY *cur_ntty;
// extern NTTY ntty_table[3];
#endif /* _ORANGES_TTY_H_ */

View File

@ -1,6 +1,6 @@
/**********************************************
* exec.c add by visual 2016.5.23
*************************************************/
* exec.c add by visual 2016.5.23
*************************************************/
#include "type.h"
#include "const.h"
#include "protect.h"
@ -13,239 +13,233 @@
#include "vfs.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 int exec_pcb_init(char* path);
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 int exec_pcb_init(char *path);
/*======================================================================*
* sys_exec add by visual 2016.5.23
*exec系统调用功能实现部分
*======================================================================*/
* sys_exec add by visual 2016.5.23
*exec系统调用功能实现部分
*======================================================================*/
u32 sys_exec(char *path)
{
Elf32_Ehdr *Echo_Ehdr = NULL;
Elf32_Phdr *Echo_Phdr = NULL;
u32 addr_lin;
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;
}
/*******************打开文件************************/
// 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
return -1;
// printf("sys_exec open error!\n"); //deleted by mingxuan 2019-5-23
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信息**************/
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);
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++)
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++)
read_Phdr(fd, Echo_Phdr + i, Echo_Ehdr->e_phoff + i * sizeof(Elf32_Phdr));
/*************释放进程内存****************/
//目前还没有实现 思路是数据、代码根据text_info和data_info属性决定释放深度其余内存段可以完全释放
// 目前还没有实现 思路是数据、代码根据text_info和data_info属性决定释放深度其余内存段可以完全释放
/*************根据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重置即可
p_proc_current->task.regs.eip = Echo_Ehdr->e_entry;//进程入口线性地址
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
//栈
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);//页表的属性位
// 代码、数据已经处理将eip重置即可
p_proc_current->task.regs.eip = Echo_Ehdr->e_entry; // 进程入口线性地址
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
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;
}
}
//堆 用户还没有申请所以没有分配只在PCB表里标示了线性起始位置
real_close(fd); //added by mingxuan 2019-5-23
// 堆 用户还没有申请所以没有分配只在PCB表里标示了线性起始位置
real_close(fd); // added by mingxuan 2019-5-23
if (Echo_Ehdr != NULL)
sys_free(Echo_Ehdr);
if (Echo_Phdr != NULL)
sys_free(Echo_Phdr);
//disp_color_str("\n[exec success:",0x72);//灰底绿字
//disp_color_str(path,0x72);//灰底绿字
//disp_color_str("]",0x72);//灰底绿字
// kprintf("\n\x1b[32;47m[exec success:");//灰底绿字
// kprintf(path);//灰底绿字
// kpritff("]\x1b[m");//灰底绿字
return 0;
}
/*======================================================================*
* exec_elfcpy add by visual 2016.5.23
*elf中program到内存中
*======================================================================*/
static u32 exec_elfcpy(u32 fd,Elf32_Phdr Echo_Phdr,u32 attribute) // 这部分代码将来要移动到exec.c文件中包括下面exec()中的一部分
* exec_elfcpy add by visual 2016.5.23
*elf中program到内存中
*======================================================================*/
static u32 exec_elfcpy(u32 fd, Elf32_Phdr Echo_Phdr, u32 attribute) // 这部分代码将来要移动到exec.c文件中包括下面exec()中的一部分
{
u32 lin_addr = Echo_Phdr.p_vaddr;
u32 lin_limit = Echo_Phdr.p_vaddr + Echo_Phdr.p_memsz;
u32 file_offset = Echo_Phdr.p_offset;
u32 file_limit = Echo_Phdr.p_offset + Echo_Phdr.p_filesz;
char ch;
//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
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
if( file_offset<file_limit )
{//文件中还有数据,正常拷贝
//modified by xw, 18/5/30
// seek(file_offset);
// read(fd,&ch,1);
// 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
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
if (file_offset < file_limit)
{ // 文件中还有数据,正常拷贝
// modified by xw, 18/5/30
// seek(file_offset);
// read(fd,&ch,1);
//fake_seek(file_offset); //deleted 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
//fake_read(fd,&ch,1); //deleted 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
// fake_seek(file_offset); //deleted 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
// fake_read(fd,&ch,1); //deleted 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
//~xw
*((u8*)lin_addr) = ch;//memcpy((void*)lin_addr,&ch,1);
*((u8 *)lin_addr) = ch; // memcpy((void*)lin_addr,&ch,1);
}
else
{
//已初始化数据段拷贝完毕剩下的是未初始化的数据段在内存中填0
*((u8*)lin_addr) = 0;//memset((void*)lin_addr,0,1);
// 已初始化数据段拷贝完毕剩下的是未初始化的数据段在内存中填0
*((u8 *)lin_addr) = 0; // memset((void*)lin_addr,0,1);
}
}
return 0;
}
/*======================================================================*
* exec_load add by visual 2016.5.23
*elf的program复制文件信息
*======================================================================*/
static u32 exec_load(u32 fd,const Elf32_Ehdr* Echo_Ehdr,const Elf32_Phdr Echo_Phdr[])
* exec_load add by visual 2016.5.23
*elf的program复制文件信息
*======================================================================*/
static u32 exec_load(u32 fd, const Elf32_Ehdr *Echo_Ehdr, const Elf32_Phdr Echo_Phdr[])
{
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;
}
//我们还不能确定elf中一共能有几个program但就目前我们查看过的elf文件中只出现过两中program一种.textR-E和一种.dataRW-
for( ph_num=0; ph_num<Echo_Ehdr->e_phnum ; ph_num++ )
// 我们还不能确定elf中一共能有几个program但就目前我们查看过的elf文件中只出现过两中program一种.textR-E和一种.dataRW-
for (ph_num = 0; ph_num < Echo_Ehdr->e_phnum; ph_num++)
{
if( 0==Echo_Phdr[ph_num].p_memsz )
{//最后一个program
if (0 == Echo_Phdr[ph_num].p_memsz)
{ // 最后一个program
break;
}
if( Echo_Phdr[ph_num].p_flags == 0x5) //101R_E
{//Code Segment
exec_elfcpy(fd,Echo_Phdr[ph_num],PG_P | PG_USU | PG_RWR);//进程代码段
if (Echo_Phdr[ph_num].p_flags == 0x5) // 101R_E
{ // Code Segment
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);
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;
}
else if(Echo_Phdr[ph_num].p_flags == 0x4)//110R__
{// 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);//进程数据段
else if (Echo_Phdr[ph_num].p_flags == 0x4) // 110R__
{ // 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); // 进程数据段
// 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_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 0;
}
/*======================================================================*
* exec_init add by visual 2016.5.23
* 线
*======================================================================*/
static int exec_pcb_init(char* path)
* exec_init add by visual 2016.5.23
* 线
*======================================================================*/
static int exec_pcb_init(char *path)
{
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); //名称
p_proc_current->task.stat = READY; //状态
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.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.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.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;
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); // 名称
p_proc_current->task.stat = READY; // 状态
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.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.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.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.eflags = 0x202; /* IF=1,bit2 永远是1 */
/***************copy registers data****************************/
//copy registers data to the bottom of the new kernel stack
//added by xw, 17/12/11
p_regs = (char*)(p_proc_current + 1);
// copy registers data to the bottom of the new kernel stack
// added by xw, 17/12/11
p_regs = (char *)(p_proc_current + 1);
p_regs -= P_STACKTOP;
memcpy(p_regs, (char*)p_proc_current, 18 * 4);
//进程表线性地址布局部分text、data已经在前面初始化了
p_proc_current->task.memmap.vpage_lin_base = 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_limit = HeapLinBase; //堆界限
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_limit = StackLinBase - 0x4000; //栈界限(使用时注意栈的生长方向)
p_proc_current->task.memmap.arg_lin_base = 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_limit = KernelLinBase + KernelSize; //内核大小初始化为8M
//进程树属性,只要改两项,其余不用改
//p_proc_current->task.info.type = TYPE_PROCESS; //当前是进程还是线程
//p_proc_current->task.info.real_ppid = -1; //亲父进程,创建它的那个进程
//p_proc_current->task.info.ppid = -1; //当前父进程
//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_t_num = 0; //子线程数量
//p_proc_current->task.info.child_thread[NR_CHILD_MAX];//子线程列表
p_proc_current->task.info.text_hold = 1; //是否拥有代码
p_proc_current->task.info.data_hold = 1; //是否拥有数据
memcpy(p_regs, (char *)p_proc_current, 18 * 4);
// 进程表线性地址布局部分text、data已经在前面初始化了
p_proc_current->task.memmap.vpage_lin_base = 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_limit = HeapLinBase; // 堆界限
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_limit = StackLinBase - 0x4000; // 栈界限(使用时注意栈的生长方向)
p_proc_current->task.memmap.arg_lin_base = 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_limit = KernelLinBase + KernelSize; // 内核大小初始化为8M
// 进程树属性,只要改两项,其余不用改
// p_proc_current->task.info.type = TYPE_PROCESS; //当前是进程还是线程
// p_proc_current->task.info.real_ppid = -1; //亲父进程,创建它的那个进程
// p_proc_current->task.info.ppid = -1; //当前父进程
// 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_t_num = 0; //子线程数量
// p_proc_current->task.info.child_thread[NR_CHILD_MAX];//子线程列表
p_proc_current->task.info.text_hold = 1; // 是否拥有代码
p_proc_current->task.info.data_hold = 1; // 是否拥有数据
return 0;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
/*****************************************************
* fork.c //add by visual 2016.5.25
*fork()sys_fork()
********************************************************/
* fork.c //add by visual 2016.5.25
*fork()sys_fork()
********************************************************/
#include "type.h"
#include "const.h"
#include "protect.h"
@ -11,227 +11,223 @@
#include "proto.h"
#include "stdio.h"
static int fork_mem_cpy(u32 ppid,u32 pid);
static int fork_pcb_cpy(PROCESS* p_child);
static int fork_update_info(PROCESS* p_child);
static int fork_mem_cpy(u32 ppid, u32 pid);
static int fork_pcb_cpy(PROCESS *p_child);
static int fork_update_info(PROCESS *p_child);
/**********************************************************
* sys_fork //add by visual 2016.5.25
*sys_fork的具体实现部分
*************************************************************/
* sys_fork //add by visual 2016.5.25
*sys_fork的具体实现部分
*************************************************************/
int sys_fork()
{
PROCESS* p_child;
char* p_reg; //point to a register in the new kernel stack, added by xw, 17/12/11
PROCESS *p_child;
char *p_reg; // point to a register in the new kernel stack, added by xw, 17/12/11
/*****************申请空白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;
}
else
{
/****************初始化子进程高端地址页表(内核部分)***********************///这个页表可以复制父进程的!
init_page_pte(p_child->task.pid); //这里面已经填写了该进程的cr3寄存器变量
/****************初始化子进程高端地址页表(内核部分)***********************/ // 这个页表可以复制父进程的!
init_page_pte(p_child->task.pid); // 这里面已经填写了该进程的cr3寄存器变量
/************复制父进程的PCB部分内容保留了自己的标识信息**************/
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信息************************/
fork_update_info(p_child);
/************修改子进程的名字***************/
strcpy(p_child->task.p_name,"fork"); // 所有的子进程都叫fork
/************修改子进程的名字***************/
strcpy(p_child->task.p_name, "fork"); // 所有的子进程都叫fork
/*************子进程返回值在其eax寄存器***************/
p_child->task.regs.eax = 0;//return child with 0
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
p_child->task.regs.eax = 0; // return child with 0
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
/****************用户进程数+1****************************/
u_proc_sum += 1;
// 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;
}
return p_child->task.pid;
return p_child->task.pid;
}
/**********************************************************
* fork_mem_cpy //add by visual 2016.5.24
*
*************************************************************/
static int fork_mem_cpy(u32 ppid,u32 pid)
* fork_mem_cpy //add by visual 2016.5.24
*
*************************************************************/
static int fork_mem_cpy(u32 ppid, u32 pid)
{
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,//线性地址
get_page_phy_addr(ppid,addr_lin),//物理地址为MAX_UNSIGNED_INT时由该函数自动分配物理内存
pid,//要挂载的进程的pid子进程的pid
PG_P | PG_USU | PG_RWW,//页目录属性,一般都为可读写
PG_P | PG_USU | PG_RWR);//页表属性,代码是只读的
lin_mapping_phy(addr_lin, // 线性地址
get_page_phy_addr(ppid, addr_lin), // 物理地址为MAX_UNSIGNED_INT时由该函数自动分配物理内存
pid, // 要挂载的进程的pid子进程的pid
PG_P | PG_USU | PG_RWW, // 页目录属性,一般都为可读写
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 )
{
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 )
// 复制数据,数据不共享,子进程需要申请物理地址,并复制过来
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);//页表属性,保留内存是可读写的
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.heap_lin_base ; addr_lin < p_proc_current->task.memmap.heap_lin_limit ; addr_lin+=num_4K )
// 复制保留内存,保留内存不共享,子进程需要申请物理地址,并复制过来
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,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.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);//页表属性,栈是可读写的
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,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);//页表属性,参数区是可读写的
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;
// 复制栈,栈不共享,子进程需要申请物理地址,并复制过来(注意栈的复制方向)
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
*PCB表
*************************************************************/
static int fork_pcb_cpy(PROCESS* p_child)
* fork_pcb_cpy //add by visual 2016.5.26
*PCB表
*************************************************************/
static int fork_pcb_cpy(PROCESS *p_child)
{
int pid;
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* 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.
//暂存标识信息
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* 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.
// 暂存标识信息
pid = p_child->task.pid;
//eflags = p_child->task.regs.eflags;
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 = p_child->task.regs.eflags;
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
selector_ldt = p_child->task.ldt_sel;
cr3_child = p_child->task.cr3;
//复制PCB内容
//modified by xw, 17/12/11
//modified begin
cr3_child = p_child->task.cr3;
// 复制PCB内容
// modified by xw, 17/12/11
// modified begin
//*p_child = *p_proc_current;
//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.
//Added by xw, 18/4/21
// 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.
// Added by xw, 18/4/21
esp_save_int = p_child->task.esp_save_int;
esp_save_context = p_child->task.esp_save_context;
p_child->task = p_proc_current->task;
//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,
//an error will still occur.
// 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,
// an error will still occur.
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_context = esp_save_context; //same above
// 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);
//modified end
//恢复标识信息
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 = (char*)(p_child + 1) - P_STACKTOP - 4 * 6;
memcpy(((char *)(p_child + 1) - P_STACKTOP), ((char *)(p_proc_current + 1) - P_STACKTOP), 18 * 4);
// modified end
// 恢复标识信息
p_child->task.pid = pid;
//p_child->task.regs.eflags = eflags;
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
p_child->task.ldt_sel = selector_ldt;
// p_child->task.regs.eflags = eflags;
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
p_child->task.ldt_sel = selector_ldt;
p_child->task.cr3 = cr3_child;
return 0;
}
/**********************************************************
* fork_update_info //add by visual 2016.5.26
*info
*************************************************************/
static int fork_update_info(PROCESS* p_child)
* fork_update_info //add by visual 2016.5.26
*info
*************************************************************/
static int fork_update_info(PROCESS *p_child)
{
/************更新父进程的info***************/
//p_proc_current->task.info.type; //当前是进程还是线程
//p_proc_current->task.info.real_ppid; //亲父进程,创建它的那个进程
//p_proc_current->task.info.ppid; //当前父进程
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_t_num; //子线程数量
//p_proc_current->task.info.child_thread[NR_CHILD_MAX];//子线程列表
//p_proc_current->task.text_hold; //是否拥有代码
//p_proc_current->task.data_hold; //是否拥有数据
/************更新子进程的info***************/
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.ppid = p_proc_current->task.pid; //当前父进程
p_child->task.info.child_p_num = 0; //子进程数量
//p_child->task.info.child_process[NR_CHILD_MAX] = pid;//子进程列表
p_child->task.info.child_t_num = 0; //子线程数量
//p_child->task.info.child_thread[NR_CHILD_MAX];//子线程列表
p_child->task.info.text_hold = 0; //是否拥有代码,子进程不拥有代码
p_child->task.info.data_hold = 1; //是否拥有数据,子进程拥有数据
/************更新父进程的info***************/
// p_proc_current->task.info.type; //当前是进程还是线程
// p_proc_current->task.info.real_ppid; //亲父进程,创建它的那个进程
// p_proc_current->task.info.ppid; //当前父进程
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_t_num; //子线程数量
// p_proc_current->task.info.child_thread[NR_CHILD_MAX];//子线程列表
// p_proc_current->task.text_hold; //是否拥有代码
// p_proc_current->task.data_hold; //是否拥有数据
/************更新子进程的info***************/
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.ppid = p_proc_current->task.pid; // 当前父进程
p_child->task.info.child_p_num = 0; // 子进程数量
// p_child->task.info.child_process[NR_CHILD_MAX] = pid;//子进程列表
p_child->task.info.child_t_num = 0; // 子线程数量
// p_child->task.info.child_thread[NR_CHILD_MAX];//子线程列表
p_child->task.info.text_hold = 0; // 是否拥有代码,子进程不拥有代码
p_child->task.info.data_hold = 1; // 是否拥有数据,子进程拥有数据
return 0;
}

View File

@ -132,7 +132,8 @@ void initial()
do_vclose(stdout);
do_vclose(stderr);
exec("orange/shell_1.bin");
// exec("orange/shell_1.bin");
exec("orange/test.bin");
while (1)
;

View File

@ -33,7 +33,7 @@ static int initialize_cpus(); // added by xw, 18/6/2
int kernel_main()
{
clear_kernel_pagepte_low();
init_serial();
int error;
@ -204,7 +204,7 @@ static int initialize_processes()
/***************初始化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;
}
// 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
// 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;
// }
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); // 页表的属性位
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;
}
}
@ -357,7 +357,7 @@ static int initialize_processes()
/***************初始化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;
}
// 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
// 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;
// }
err_temp = lin_mapping_phy(AddrLin, // 线性地址
@ -382,7 +382,7 @@ static int initialize_processes()
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;
}
}

View File

@ -31,33 +31,33 @@ void switch_pde()
*
*======================================================================*/
u32 init_page_pte(u32 pid)
{ //页表初始化函数
{ // 页表初始化函数
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
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;
}
proc_table[pid].task.cr3 = pde_addr_phy_temp; //初始化了进程表中cr3寄存器变量属性位暂时不管
proc_table[pid].task.cr3 = pde_addr_phy_temp; // 初始化了进程表中cr3寄存器变量属性位暂时不管
/*********************页表初始化部分*********************************/
u32 phy_addr = 0;
for (AddrLin = KernelLinBase, phy_addr = 0; AddrLin < KernelLinBase + KernelSize; AddrLin += num_4K, phy_addr += num_4K)
{ //只初始化内核部分3G后的线性地址映射到物理地址开始处
err_temp = lin_mapping_phy(AddrLin, //线性地址 //add by visual 2016.5.9
phy_addr, //物理地址
pid, //进程pid //edit by visual 2016.5.19
PG_P | PG_USU | PG_RWW, //页目录的属性位(用户权限) //edit by visual 2016.5.26
PG_P | PG_USS | PG_RWW); //页表的属性位(系统权限) //edit by visual 2016.5.17
{ // 只初始化内核部分3G后的线性地址映射到物理地址开始处
err_temp = lin_mapping_phy(AddrLin, // 线性地址 //add by visual 2016.5.9
phy_addr, // 物理地址
pid, // 进程pid //edit by visual 2016.5.19
PG_P | PG_USU | PG_RWW, // 页目录的属性位(用户权限) //edit by visual 2016.5.26
PG_P | PG_USS | PG_RWW); // 页表的属性位(系统权限) //edit by visual 2016.5.17
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;
}
}
@ -68,12 +68,12 @@ u32 init_page_pte(u32 pid)
/*======================================================================*
page_fault_handle edit by visual 2016.5.9
*======================================================================*/
void page_fault_handler(u32 vec_no, //异常编号此时应该是14代表缺页异常
u32 err_code, //错误码
u32 eip, //导致缺页的指令的线性地址
u32 cs, //发生错误时的代码段寄存器内容
u32 eflags) //时发生错误的标志寄存器内容
{ //缺页中断处理函数
void page_fault_handler(u32 vec_no, // 异常编号此时应该是14代表缺页异常
u32 err_code, // 错误码
u32 eip, // 导致缺页的指令的线性地址
u32 cs, // 发生错误时的代码段寄存器内容
u32 eflags) // 时发生错误的标志寄存器内容
{ // 缺页中断处理函数
u32 pde_addr_phy_temp;
u32 pte_addr_phy_temp;
u32 cr2;
@ -89,29 +89,29 @@ void page_fault_handler(u32 vec_no, //异常编号此时应该是14
halt();
}
//获取该进程页目录物理地址
// 获取该进程页目录物理地址
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);
kprintf("\n");
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[91mCR3=0x%08x, PDE=%p, PTE=%p\033[0m\n",
p_proc_current->task.cr3,
*((u32 *)K_PHY2LIN(pde_addr_phy_temp) + get_pde_index(cr2)),
*((u32 *)K_PHY2LIN(pte_addr_phy_temp) + get_pte_index(cr2)));
kprintf("\033[91mCR3=0x%08x, PDE=%p, PTE=%p\033[0m\n",
p_proc_current->task.cr3,
*((u32 *)K_PHY2LIN(pde_addr_phy_temp) + get_pde_index(cr2)),
*((u32 *)K_PHY2LIN(pte_addr_phy_temp) + get_pte_index(cr2)));
disable_int();
halt();
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);
(*((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);
}
else
{ //只是缺少物理页
{ // 只是缺少物理页
// 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;
// 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
*======================================================================*/
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
*======================================================================*/
inline u32 get_pte_index(u32 AddrLin)
{ //由 线性地址 得到 页表项编号
return (((AddrLin)&0x003FFFFF) >> 12); //中间10位A21~A12,0x3FFFFF = 0000 0000 0011 1111 1111 1111 1111 1111
inline u32 get_pte_index(u32 AddrLin)
{ // 由 线性地址 得到 页表项编号
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
*======================================================================*/
inline u32 get_pde_phy_addr(u32 pid)
{ //获取页目录物理地址
{ // 获取页目录物理地址
if (proc_table[pid].task.cr3 == 0)
{ //还没有初始化页目录
{ // 还没有初始化页目录
return -1;
}
else
@ -164,19 +164,19 @@ inline u32 get_pde_phy_addr(u32 pid)
/*======================================================================*
get_pte_phy_addr add by visual 2016.4.28
*======================================================================*/
inline u32 get_pte_phy_addr(u32 pid, //页目录物理地址 //edit by visual 2016.5.19
u32 AddrLin) //线性地址
{ //获取该线性地址所属页表的物理地址
u32 PageDirPhyAddr = get_pde_phy_addr(pid); // add by visual 2016.5.19
return (*((u32 *)K_PHY2LIN(PageDirPhyAddr) + get_pde_index(AddrLin))) & 0xFFFFF000; //先找到该进程页目录首地址,然后计算出该线性地址对应的页目录项,再访问,最后注意4k对齐
inline u32 get_pte_phy_addr(u32 pid, // 页目录物理地址 //edit by visual 2016.5.19
u32 AddrLin) // 线性地址
{ // 获取该线性地址所属页表的物理地址
u32 PageDirPhyAddr = get_pde_phy_addr(pid); // add by visual 2016.5.19
return (*((u32 *)K_PHY2LIN(PageDirPhyAddr) + get_pde_index(AddrLin))) & 0xFFFFF000; // 先找到该进程页目录首地址,然后计算出该线性地址对应的页目录项,再访问,最后注意4k对齐
}
/*======================================================================*
get_page_phy_addr add by visual 2016.5.9
*======================================================================*/
inline u32 get_page_phy_addr(u32 pid, //页表物理地址 //edit by visual 2016.5.19
u32 AddrLin) //线性地址
{ //获取该线性地址对应的物理页物理地址
inline u32 get_page_phy_addr(u32 pid, // 页表物理地址 //edit by visual 2016.5.19
u32 AddrLin) // 线性地址
{ // 获取该线性地址对应的物理页物理地址
u32 PageTblPhyAddr = get_pte_phy_addr(pid, AddrLin); // add by visual 2016.5.19
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
*======================================================================*/
u32 pte_exist(u32 PageDirPhyAddr, //页目录物理地址
u32 AddrLin) //线性地址
{ //判断 有没有 页表
if ((0x00000001 & (*((u32 *)K_PHY2LIN(PageDirPhyAddr) + get_pde_index(AddrLin)))) == 0) //先找到该进程页目录,然后计算出该线性地址对应的页目录项,访问并判断其是否存在
{ //标志位为0不存在
u32 pte_exist(u32 PageDirPhyAddr, // 页目录物理地址
u32 AddrLin) // 线性地址
{ // 判断 有没有 页表
if ((0x00000001 & (*((u32 *)K_PHY2LIN(PageDirPhyAddr) + get_pde_index(AddrLin)))) == 0) // 先找到该进程页目录,然后计算出该线性地址对应的页目录项,访问并判断其是否存在
{ // 标志位为0不存在
return 0;
}
else
@ -200,11 +200,11 @@ u32 pte_exist(u32 PageDirPhyAddr, //页目录物理地址
/*======================================================================*
phy_exist add by visual 2016.4.28
*======================================================================*/
u32 phy_exist(u32 PageTblPhyAddr, //页表物理地址
u32 AddrLin) //线性地址
{ //判断 该线性地址 有没有 对应的 物理页
u32 phy_exist(u32 PageTblPhyAddr, // 页表物理地址
u32 AddrLin) // 线性地址
{ // 判断 该线性地址 有没有 对应的 物理页
if ((0x00000001 & (*((u32 *)K_PHY2LIN(PageTblPhyAddr) + get_pte_index(AddrLin)))) == 0)
{ //标志位为0不存在
{ // 标志位为0不存在
return 0;
}
else
@ -216,25 +216,25 @@ u32 phy_exist(u32 PageTblPhyAddr, //页表物理地址
/*======================================================================*
write_page_pde add by visual 2016.4.28
*======================================================================*/
void write_page_pde(u32 PageDirPhyAddr, //页目录物理地址
u32 AddrLin, //线性地址
u32 TblPhyAddr, //要填写的页表的物理地址函数会进行4k对齐
u32 Attribute) //属性
{ //填写页目录
void write_page_pde(u32 PageDirPhyAddr, // 页目录物理地址
u32 AddrLin, // 线性地址
u32 TblPhyAddr, // 要填写的页表的物理地址函数会进行4k对齐
u32 Attribute) // 属性
{ // 填写页目录
(*((u32 *)K_PHY2LIN(PageDirPhyAddr) + get_pde_index(AddrLin))) = (TblPhyAddr & 0xFFFFF000) | Attribute;
//进程页目录起始地址+每一项的大小*所属的项
// 进程页目录起始地址+每一项的大小*所属的项
}
/*======================================================================*
write_page_pte add by visual 2016.4.28
*======================================================================*/
void write_page_pte(u32 TblPhyAddr, //页表物理地址
u32 AddrLin, //线性地址
u32 PhyAddr, //要填写的物理页物理地址(任意的物理地址函数会进行4k对齐)
u32 Attribute) //属性
{ //填写页目录,会添加属性
void write_page_pte(u32 TblPhyAddr, // 页表物理地址
u32 AddrLin, // 线性地址
u32 PhyAddr, // 要填写的物理页物理地址(任意的物理地址函数会进行4k对齐)
u32 Attribute) // 属性
{ // 填写页目录,会添加属性
(*((u32 *)K_PHY2LIN(TblPhyAddr) + get_pte_index(AddrLin))) = (PhyAddr & 0xFFFFF000) | Attribute;
//页表起始地址+一项的大小*所属的项
// 页表起始地址+一项的大小*所属的项
}
/*======================================================================*
@ -245,12 +245,12 @@ u32 vmalloc(u32 size)
{
u32 temp;
if (p_proc_current->task.info.type == TYPE_PROCESS)
{ //进程直接就是标识
{ // 进程直接就是标识
temp = p_proc_current->task.memmap.heap_lin_limit;
p_proc_current->task.memmap.heap_lin_limit += size;
}
else
{ //线程需要取父进程的标识
{ // 线程需要取父进程的标识
temp = *((u32 *)p_proc_current->task.memmap.heap_lin_limit);
(*((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
*线,
*======================================================================*/
int lin_mapping_phy(u32 AddrLin, //线性地址
u32 phy_addr, //物理地址,若为MAX_UNSIGNED_INT(0xFFFFFFFF)则表示需要由该函数判断是否分配物理地址否则将phy_addr直接和AddrLin建立映射
u32 pid, //进程pid //edit by visual 2016.5.19
u32 pde_Attribute, //页目录中的属性位
u32 pte_Attribute) //页表中的属性位
int lin_mapping_phy(u32 AddrLin, // 线性地址
u32 phy_addr, // 物理地址,若为MAX_UNSIGNED_INT(0xFFFFFFFF)则表示需要由该函数判断是否分配物理地址否则将phy_addr直接和AddrLin建立映射
u32 pid, // 进程pid //edit by visual 2016.5.19
u32 pde_Attribute, // 页目录中的属性位
u32 pte_Attribute) // 页表中的属性位
{
u32 pte_addr_phy;
u32 pde_addr_phy = get_pde_phy_addr(pid); // add by visual 2016.5.19
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
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;
}
write_page_pde(pde_addr_phy, //页目录物理地址
AddrLin, //线性地址
pte_addr_phy, //页表物理地址
pde_Attribute); //属性
write_page_pde(pde_addr_phy, // 页目录物理地址
AddrLin, // 线性地址
pte_addr_phy, // 页表物理地址
pde_Attribute); // 属性
}
else
{ //页表存在,获取该页表物理地址
pte_addr_phy = get_pte_phy_addr(pid, //进程pid //edit by visual 2016.5.19
AddrLin); //线性地址
{ // 页表存在,获取该页表物理地址
pte_addr_phy = get_pte_phy_addr(pid, // 进程pid //edit by visual 2016.5.19
AddrLin); // 线性地址
}
if (MAX_UNSIGNED_INT == phy_addr) // add by visual 2016.5.19
{ //由函数申请内存
{ // 由函数申请内存
if (0 == phy_exist(pte_addr_phy, AddrLin))
{ //无物理页申请物理页并修改phy_addr
{ // 无物理页申请物理页并修改phy_addr
if (AddrLin >= K_PHY2LIN(0))
phy_addr = do_kmalloc_4k(); //从内核物理地址申请一页
phy_addr = do_kmalloc_4k(); // 从内核物理地址申请一页
else
{
// disp_str("%");
phy_addr = do_malloc_4k(); //从用户物理地址空间申请一页
phy_addr = do_malloc_4k(); // 从用户物理地址空间申请一页
}
}
else
{
//有物理页,什么也不做,直接返回,必须返回
// 有物理页,什么也不做,直接返回,必须返回
return 0;
}
}
else
{ //指定填写phy_addr
//不用修改phy_addr
{ // 指定填写phy_addr
// 不用修改phy_addr
}
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;
}
write_page_pte(pte_addr_phy, //页表物理地址
AddrLin, //线性地址
phy_addr, //物理页物理地址
pte_Attribute); //属性
write_page_pte(pte_addr_phy, // 页表物理地址
AddrLin, // 线性地址
phy_addr, // 物理页物理地址
pte_Attribute); // 属性
refresh_page_cache();
return 0;
@ -338,7 +337,7 @@ int lin_mapping_phy(u32 AddrLin, //线性地址
void clear_kernel_pagepte_low()
{
u32 page_num = *(u32 *)PageTblNumAddr;
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)), 0, 4 * page_num); // 从内核页目录中清除内核页目录项前8项
memset((void *)(K_PHY2LIN(KernelPageTblAddr + 0x1000)), 0, 4096 * page_num); // 从内核页表中清除线性地址的低端映射关系
refresh_page_cache();
}

View File

@ -1,8 +1,8 @@
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
protect.c
protect.c
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Forrest Yu, 2005
Forrest Yu, 2005
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
#include "type.h"
@ -13,49 +13,46 @@
#include "proto.h"
#include "string.h"
/* 本文件内函数声明 */
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 single_step_exception();
void nmi();
void breakpoint_exception();
void overflow();
void bounds_check();
void inval_opcode();
void copr_not_available();
void double_fault();
void copr_seg_overrun();
void inval_tss();
void segment_not_present();
void stack_exception();
void general_protection();
void page_fault();
void copr_error();
void hwint00();
void hwint01();
void hwint02();
void hwint03();
void hwint04();
void hwint05();
void hwint06();
void hwint07();
void hwint08();
void hwint09();
void hwint10();
void hwint11();
void hwint12();
void hwint13();
void hwint14();
void hwint15();
void divide_error();
void single_step_exception();
void nmi();
void breakpoint_exception();
void overflow();
void bounds_check();
void inval_opcode();
void copr_not_available();
void double_fault();
void copr_seg_overrun();
void inval_tss();
void segment_not_present();
void stack_exception();
void general_protection();
void page_fault();
void copr_error();
void hwint00();
void hwint01();
void hwint02();
void hwint03();
void hwint04();
void hwint05();
void hwint06();
void hwint07();
void hwint08();
void hwint09();
void hwint10();
void hwint11();
void hwint12();
void hwint13();
void hwint14();
void hwint15();
/*======================================================================*
init_prot
init_prot
*----------------------------------------------------------------------*
IDT
*======================================================================*/
@ -64,271 +61,270 @@ void init_prot()
init_8259A();
// 全部初始化成中断门(没有陷阱门)
init_idt_desc(INT_VECTOR_DIVIDE, DA_386IGate,
divide_error, PRIVILEGE_KRNL);
init_idt_desc(INT_VECTOR_DIVIDE, DA_386IGate,
divide_error, PRIVILEGE_KRNL);
init_idt_desc(INT_VECTOR_DEBUG, DA_386IGate,
single_step_exception, PRIVILEGE_KRNL);
init_idt_desc(INT_VECTOR_DEBUG, DA_386IGate,
single_step_exception, PRIVILEGE_KRNL);
init_idt_desc(INT_VECTOR_NMI, DA_386IGate,
nmi, PRIVILEGE_KRNL);
init_idt_desc(INT_VECTOR_NMI, DA_386IGate,
nmi, PRIVILEGE_KRNL);
init_idt_desc(INT_VECTOR_BREAKPOINT, DA_386IGate,
breakpoint_exception, PRIVILEGE_USER);
init_idt_desc(INT_VECTOR_BREAKPOINT, DA_386IGate,
breakpoint_exception, PRIVILEGE_USER);
init_idt_desc(INT_VECTOR_OVERFLOW, DA_386IGate,
overflow, PRIVILEGE_USER);
init_idt_desc(INT_VECTOR_OVERFLOW, DA_386IGate,
overflow, PRIVILEGE_USER);
init_idt_desc(INT_VECTOR_BOUNDS, DA_386IGate,
bounds_check, PRIVILEGE_KRNL);
init_idt_desc(INT_VECTOR_BOUNDS, DA_386IGate,
bounds_check, PRIVILEGE_KRNL);
init_idt_desc(INT_VECTOR_INVAL_OP, DA_386IGate,
inval_opcode, PRIVILEGE_KRNL);
init_idt_desc(INT_VECTOR_INVAL_OP, DA_386IGate,
inval_opcode, PRIVILEGE_KRNL);
init_idt_desc(INT_VECTOR_COPROC_NOT, DA_386IGate,
copr_not_available, PRIVILEGE_KRNL);
init_idt_desc(INT_VECTOR_COPROC_NOT, DA_386IGate,
copr_not_available, PRIVILEGE_KRNL);
init_idt_desc(INT_VECTOR_DOUBLE_FAULT, DA_386IGate,
double_fault, PRIVILEGE_KRNL);
init_idt_desc(INT_VECTOR_DOUBLE_FAULT, DA_386IGate,
double_fault, PRIVILEGE_KRNL);
init_idt_desc(INT_VECTOR_COPROC_SEG, DA_386IGate,
copr_seg_overrun, PRIVILEGE_KRNL);
init_idt_desc(INT_VECTOR_COPROC_SEG, DA_386IGate,
copr_seg_overrun, PRIVILEGE_KRNL);
init_idt_desc(INT_VECTOR_INVAL_TSS, DA_386IGate,
inval_tss, PRIVILEGE_KRNL);
init_idt_desc(INT_VECTOR_INVAL_TSS, DA_386IGate,
inval_tss, PRIVILEGE_KRNL);
init_idt_desc(INT_VECTOR_SEG_NOT, DA_386IGate,
segment_not_present, PRIVILEGE_KRNL);
init_idt_desc(INT_VECTOR_SEG_NOT, DA_386IGate,
segment_not_present, PRIVILEGE_KRNL);
init_idt_desc(INT_VECTOR_STACK_FAULT, DA_386IGate,
stack_exception, PRIVILEGE_KRNL);
init_idt_desc(INT_VECTOR_STACK_FAULT, DA_386IGate,
stack_exception, PRIVILEGE_KRNL);
init_idt_desc(INT_VECTOR_PROTECTION, DA_386IGate,
general_protection, PRIVILEGE_KRNL);
init_idt_desc(INT_VECTOR_PROTECTION, DA_386IGate,
general_protection, PRIVILEGE_KRNL);
init_idt_desc(INT_VECTOR_PAGE_FAULT, DA_386IGate,
page_fault, PRIVILEGE_KRNL);
init_idt_desc(INT_VECTOR_PAGE_FAULT, DA_386IGate,
page_fault, PRIVILEGE_KRNL);
init_idt_desc(INT_VECTOR_COPROC_ERR, DA_386IGate,
copr_error, PRIVILEGE_KRNL);
init_idt_desc(INT_VECTOR_COPROC_ERR, DA_386IGate,
copr_error, PRIVILEGE_KRNL);
init_idt_desc(INT_VECTOR_IRQ0 + 0, DA_386IGate,
hwint00, PRIVILEGE_KRNL);
init_idt_desc(INT_VECTOR_IRQ0 + 0, DA_386IGate,
hwint00, PRIVILEGE_KRNL);
init_idt_desc(INT_VECTOR_IRQ0 + 1, DA_386IGate,
hwint01, PRIVILEGE_KRNL);
init_idt_desc(INT_VECTOR_IRQ0 + 1, DA_386IGate,
hwint01, PRIVILEGE_KRNL);
init_idt_desc(INT_VECTOR_IRQ0 + 2, DA_386IGate,
hwint02, PRIVILEGE_KRNL);
init_idt_desc(INT_VECTOR_IRQ0 + 2, DA_386IGate,
hwint02, PRIVILEGE_KRNL);
init_idt_desc(INT_VECTOR_IRQ0 + 3, DA_386IGate,
hwint03, PRIVILEGE_KRNL);
init_idt_desc(INT_VECTOR_IRQ0 + 3, DA_386IGate,
hwint03, PRIVILEGE_KRNL);
init_idt_desc(INT_VECTOR_IRQ0 + 4, DA_386IGate,
hwint04, PRIVILEGE_KRNL);
init_idt_desc(INT_VECTOR_IRQ0 + 4, DA_386IGate,
hwint04, PRIVILEGE_KRNL);
init_idt_desc(INT_VECTOR_IRQ0 + 5, DA_386IGate,
hwint05, PRIVILEGE_KRNL);
init_idt_desc(INT_VECTOR_IRQ0 + 5, DA_386IGate,
hwint05, PRIVILEGE_KRNL);
init_idt_desc(INT_VECTOR_IRQ0 + 6, DA_386IGate,
hwint06, PRIVILEGE_KRNL);
init_idt_desc(INT_VECTOR_IRQ0 + 6, DA_386IGate,
hwint06, PRIVILEGE_KRNL);
init_idt_desc(INT_VECTOR_IRQ0 + 7, DA_386IGate,
hwint07, PRIVILEGE_KRNL);
init_idt_desc(INT_VECTOR_IRQ0 + 7, DA_386IGate,
hwint07, PRIVILEGE_KRNL);
init_idt_desc(INT_VECTOR_IRQ8 + 0, DA_386IGate,
hwint08, PRIVILEGE_KRNL);
init_idt_desc(INT_VECTOR_IRQ8 + 0, DA_386IGate,
hwint08, PRIVILEGE_KRNL);
init_idt_desc(INT_VECTOR_IRQ8 + 1, DA_386IGate,
hwint09, PRIVILEGE_KRNL);
init_idt_desc(INT_VECTOR_IRQ8 + 1, DA_386IGate,
hwint09, PRIVILEGE_KRNL);
init_idt_desc(INT_VECTOR_IRQ8 + 2, DA_386IGate,
hwint10, PRIVILEGE_KRNL);
init_idt_desc(INT_VECTOR_IRQ8 + 2, DA_386IGate,
hwint10, PRIVILEGE_KRNL);
init_idt_desc(INT_VECTOR_IRQ8 + 3, DA_386IGate,
hwint11, PRIVILEGE_KRNL);
init_idt_desc(INT_VECTOR_IRQ8 + 3, DA_386IGate,
hwint11, PRIVILEGE_KRNL);
init_idt_desc(INT_VECTOR_IRQ8 + 4, DA_386IGate,
hwint12, PRIVILEGE_KRNL);
init_idt_desc(INT_VECTOR_IRQ8 + 4, DA_386IGate,
hwint12, PRIVILEGE_KRNL);
init_idt_desc(INT_VECTOR_IRQ8 + 5, DA_386IGate,
hwint13, PRIVILEGE_KRNL);
init_idt_desc(INT_VECTOR_IRQ8 + 5, DA_386IGate,
hwint13, PRIVILEGE_KRNL);
init_idt_desc(INT_VECTOR_IRQ8 + 6, DA_386IGate,
hwint14, PRIVILEGE_KRNL);
init_idt_desc(INT_VECTOR_IRQ8 + 6, DA_386IGate,
hwint14, PRIVILEGE_KRNL);
init_idt_desc(INT_VECTOR_IRQ8 + 7, DA_386IGate,
hwint15, PRIVILEGE_KRNL);
init_idt_desc(INT_VECTOR_IRQ8 + 7, DA_386IGate,
hwint15, PRIVILEGE_KRNL);
init_idt_desc(INT_VECTOR_SYS_CALL, DA_386IGate,
sys_call, PRIVILEGE_USER);
/*修改显存描述符*/ //add by visual 2016.5.12
init_idt_desc(INT_VECTOR_SYS_CALL, DA_386IGate,
sys_call, PRIVILEGE_USER);
/*修改显存描述符*/ // add by visual 2016.5.12
init_descriptor(&gdt[INDEX_VIDEO],
K_PHY2LIN(0x0B8000),
0x0ffff,
DA_DRW | DA_DPL3);
DA_DRW | DA_DPL3);
/* 填充 GDT 中 TSS 这个描述符 */
memset(&tss, 0, sizeof(tss));
tss.ss0 = SELECTOR_KERNEL_DS;
tss.ss0 = SELECTOR_KERNEL_DS;
init_descriptor(&gdt[INDEX_TSS],
vir2phys(seg2phys(SELECTOR_KERNEL_DS), &tss),
sizeof(tss) - 1,
DA_386TSS);
tss.iobase = sizeof(tss); /* 没有I/O许可位图 */
vir2phys(seg2phys(SELECTOR_KERNEL_DS), &tss),
sizeof(tss) - 1,
DA_386TSS);
tss.iobase = sizeof(tss); /* 没有I/O许可位图 */
// 填充 GDT 中进程的 LDT 的描述符
int i;
PROCESS* p_proc = proc_table;
PROCESS *p_proc = proc_table;
u16 selector_ldt = INDEX_LDT_FIRST << 3;
for(i=0;i<NR_PCBS;i++){ //edit by visual 2016.4.5
init_descriptor(&gdt[selector_ldt>>3],
vir2phys(seg2phys(SELECTOR_KERNEL_DS),proc_table[i].task.ldts),
LDT_SIZE * sizeof(DESCRIPTOR) - 1,
DA_LDT);
for (i = 0; i < NR_PCBS; i++)
{ // edit by visual 2016.4.5
init_descriptor(&gdt[selector_ldt >> 3],
vir2phys(seg2phys(SELECTOR_KERNEL_DS), proc_table[i].task.ldts),
LDT_SIZE * sizeof(DESCRIPTOR) - 1,
DA_LDT);
p_proc++;
selector_ldt += 1 << 3;
}
}
/*======================================================================*
init_idt_desc
init_idt_desc
*----------------------------------------------------------------------*
386
*======================================================================*/
void init_idt_desc(unsigned char vector, u8 desc_type, int_handler handler, unsigned char privilege)
{
GATE * p_gate = &idt[vector];
u32 base = (u32)handler;
p_gate->offset_low = base & 0xFFFF;
p_gate->selector = SELECTOR_KERNEL_CS;
p_gate->dcount = 0;
p_gate->attr = desc_type | (privilege << 5);
p_gate->offset_high = (base >> 16) & 0xFFFF;
GATE *p_gate = &idt[vector];
u32 base = (u32)handler;
p_gate->offset_low = base & 0xFFFF;
p_gate->selector = SELECTOR_KERNEL_CS;
p_gate->dcount = 0;
p_gate->attr = desc_type | (privilege << 5);
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);
}
/*======================================================================*
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->base_low = base & 0x0FFFF; // 段基址 1 (2 字节)
p_desc->base_mid = (base >> 16) & 0x0FF; // 段基址 2 (1 字节)
p_desc->attr1 = attribute & 0xFF; // 属性 1
p_desc->limit_high_attr2 = ((limit >> 16) & 0x0F) |
((attribute >> 8) & 0xF0);// 段界限 2 + 属性 2
p_desc->base_high = (base >> 24) & 0x0FF; // 段基址 3 (1 字节)
p_desc->limit_low = limit & 0x0FFFF; // 段界限 1 (2 字节)
p_desc->base_low = base & 0x0FFFF; // 段基址 1 (2 字节)
p_desc->base_mid = (base >> 16) & 0x0FF; // 段基址 2 (1 字节)
p_desc->attr1 = attribute & 0xFF; // 属性 1
p_desc->limit_high_attr2 = ((limit >> 16) & 0x0F) |
((attribute >> 8) & 0xF0); // 段界限 2 + 属性 2
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 text_color = 0x74; /* 灰底红字 */
char err_description[][64] = { "#DE Divide Error",
"#DB RESERVED",
"— NMI Interrupt",
"#BP Breakpoint",
"#OF Overflow",
"#BR BOUND Range Exceeded",
"#UD Invalid Opcode (Undefined Opcode)",
"#NM Device Not Available (No Math Coprocessor)",
"#DF Double Fault",
" Coprocessor Segment Overrun (reserved)",
"#TS Invalid TSS",
"#NP Segment Not Present",
"#SS Stack-Segment Fault",
"#GP General Protection",
"#PF Page Fault",
"— (Intel reserved. Do not use.)",
"#MF x87 FPU Floating-Point Error (Math Fault)",
"#AC Alignment Check",
"#MC Machine Check",
"#XF SIMD Floating-Point Exception"
};
char err_description[][64] = {"#DE Divide Error",
"#DB RESERVED",
"— NMI Interrupt",
"#BP Breakpoint",
"#OF Overflow",
"#BR BOUND Range Exceeded",
"#UD Invalid Opcode (Undefined Opcode)",
"#NM Device Not Available (No Math Coprocessor)",
"#DF Double Fault",
" Coprocessor Segment Overrun (reserved)",
"#TS Invalid TSS",
"#NP Segment Not Present",
"#SS Stack-Segment Fault",
"#GP General Protection",
"#PF Page Fault",
"— (Intel reserved. Do not use.)",
"#MF x87 FPU Floating-Point Error (Math Fault)",
"#AC Alignment Check",
"#MC Machine Check",
"#XF SIMD Floating-Point Exception"};
/* 通过打印空格的方式清空屏幕的前五行,并把 disp_pos 清零 */
disp_pos = 0;
for(i=0;i<80*5;i++){
disp_str(" ");
for (i = 0; i < 80 * 5; i++)
{
printf(" ");
}
disp_pos = 0;
disp_color_str("Exception! --> ", text_color);
disp_color_str(err_description[vec_no], text_color);
disp_color_str("\n\n", text_color);
disp_color_str("EFLAGS:", text_color);
disp_int(eflags);
disp_color_str("CS:", text_color);
disp_int(cs);
disp_color_str("EIP:", text_color);
disp_int(eip);
printf("\x1b[31;47mException! --> ");
printf(err_description[vec_no]);
printf("\n\n");
printf("EFLAGS:\x1b[m");
printf("%d", eflags);
printf("\x1b[31;47mCS:\x1b[m");
printf("%d", cs);
printf("\x1b[31;47mEIP:\x1b[m");
printf("%d", eip);
if(err_code != 0xFFFFFFFF){
disp_color_str("Error code:", text_color);
disp_int(err_code);
if (err_code != 0xFFFFFFFF)
{
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;
}
/*======================================================================*
divide error handler
*======================================================================*/
//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
void divide_error_handler()
// 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
void divide_error_handler()
{
int vec_no, err_code, eip, cs, eflags;
int i, j;
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 16(%%ebp), %2\n\t" //get eip from stack
"mov 20(%%ebp), %3\n\t" //get cs from stack
"mov 24(%%ebp), %4\n\t" //get eflags from stack
: "=r"(vec_no), "=r"(err_code), "=r"(eip),
"=r"(cs), "=r"(eflags)
);
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 16(%%ebp), %2\n\t" // get eip from stack
"mov 20(%%ebp), %3\n\t" // get cs from stack
"mov 24(%%ebp), %4\n\t" // get eflags from stack
: "=r"(vec_no), "=r"(err_code), "=r"(eip),
"=r"(cs), "=r"(eflags));
exception_handler(vec_no, err_code, eip, cs, eflags);
while (1)
{
disp_str("Loop in divide error handler...\n");
printf("Loop in divide error handler...\n");
i = 100;
while(--i){
while (--i)
{
j = 1000;
while(--j){}
while (--j)
{
}
}
}
}

View File

@ -1,7 +1,7 @@
/******************************************************************
* pthread.c //add by visual 2016.5.26
*pthread()
*******************************************************************/
* pthread.c //add by visual 2016.5.26
*pthread()
*******************************************************************/
#include "type.h"
#include "const.h"
#include "protect.h"
@ -10,204 +10,201 @@
#include "global.h"
#include "proto.h"
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_stack_init(PROCESS *p_child,PROCESS *p_parent);
static int pthread_heap_init(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_stack_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的具体实现部分
*************************************************************/
* sys_pthread //add by visual 2016.5.25
*sys_pthread的具体实现部分
*************************************************************/
int sys_pthread(void *entry)
{
PROCESS* p_child;
char* p_reg; //point to a register in the new kernel stack, added by xw, 17/12/11
PROCESS *p_child;
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 )
{//线程不能创建线程
disp_color_str("[pthread failed:",0x74);
disp_color_str(p_proc_current->task.p_name,0x74);
disp_color_str("]",0x74);
printf("\x1b[31;47m[pthread failed:");
printf(p_proc_current->task.p_name);
printf("]\x1b[m");
return -1;
}*/
/*****************申请空白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;
}
else
{
{
PROCESS *p_parent;
if( p_proc_current->task.info.type == TYPE_THREAD )
{//线程
p_parent = &(proc_table[p_proc_current->task.info.ppid]);//父进程
if (p_proc_current->task.info.type == TYPE_THREAD)
{ // 线程
p_parent = &(proc_table[p_proc_current->task.info.ppid]); // 父进程
}
else
{//进程
p_parent = p_proc_current;//父进程就是父线程
{ // 进程
p_parent = p_proc_current; // 父进程就是父线程
}
/************复制父进程的PCB部分内容保留了自己的标识信息,但cr3使用的是父进程的**************/
pthread_pcb_cpy(p_child,p_parent);
pthread_pcb_cpy(p_child, p_parent);
/************在父进程的栈中分配子线程的栈从进程栈的低地址分配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_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
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
/**************更新进程树标识info信息************************/
pthread_update_info(p_child,p_parent);
/************修改子进程的名字***************/
strcpy(p_child->task.p_name,"pthread"); // 所有的子进程都叫pthread
pthread_update_info(p_child, p_parent);
/************修改子进程的名字***************/
strcpy(p_child->task.p_name, "pthread"); // 所有的子进程都叫pthread
/*************子进程返回值在其eax寄存器***************/
p_child->task.regs.eax = 0;//return child with 0
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
p_child->task.regs.eax = 0; // return child with 0
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
/****************用户进程数+1****************************/
u_proc_sum += 1;
disp_color_str("[pthread success:",0x72);
disp_color_str(p_proc_current->task.p_name,0x72);
disp_color_str("]",0x72);
//anything child need is prepared now, set its state to ready. added by xw, 17/12/11
p_child->task.stat = READY;
printf("\x1b[32;47m[pthread success:");
printf(p_proc_current->task.p_name);
printf("]\x1b[m");
// anything child need is prepared now, set its state to ready. added by xw, 17/12/11
p_child->task.stat = READY;
}
return p_child->task.pid;
return p_child->task.pid;
}
/**********************************************************
* pthread_pcb_cpy //add by visual 2016.5.26
*PCB表
*************************************************************/
static int pthread_pcb_cpy(PROCESS *p_child,PROCESS *p_parent)
* pthread_pcb_cpy //add by visual 2016.5.26
*PCB表
*************************************************************/
static int pthread_pcb_cpy(PROCESS *p_child, PROCESS *p_parent)
{
int pid;
u32 eflags,selector_ldt;
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
//暂存标识信息
u32 eflags, selector_ldt;
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
// 暂存标识信息
pid = p_child->task.pid;
//eflags = p_child->task.regs.eflags; //deleted 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 = p_child->task.regs.eflags; //deleted 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
selector_ldt = p_child->task.ldt_sel;
//复制PCB内容
//modified by xw, 17/12/11
//modified begin
// 复制PCB内容
// modified by xw, 17/12/11
// modified begin
//*p_child = *p_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.
//Added by xw, 18/4/21
// 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.
// Added by xw, 18/4/21
esp_save_int = p_child->task.esp_save_int;
esp_save_context = p_child->task.esp_save_context;
p_child->task = p_parent->task;
//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,
//an error will still occur.
// 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,
// an error will still occur.
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_context = esp_save_context; //same above
memcpy(((char*)(p_child + 1) - P_STACKTOP), ((char*)(p_parent + 1) - P_STACKTOP), 18 * 4);
//modified end
//恢复标识信息
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
memcpy(((char *)(p_child + 1) - P_STACKTOP), ((char *)(p_parent + 1) - P_STACKTOP), 18 * 4);
// modified end
// 恢复标识信息
p_child->task.pid = pid;
//p_child->task.regs.eflags = eflags;
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
p_child->task.ldt_sel = selector_ldt;
// p_child->task.regs.eflags = eflags;
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
p_child->task.ldt_sel = selector_ldt;
return 0;
}
/**********************************************************
* pthread_update_info //add by visual 2016.5.26
*线info
*************************************************************/
static int pthread_update_info(PROCESS* p_child,PROCESS *p_parent)
* pthread_update_info //add by visual 2016.5.26
*线info
*************************************************************/
static int pthread_update_info(PROCESS *p_child, PROCESS *p_parent)
{
/************更新父进程的info***************///注意 父进程 父进程 父进程
if( p_parent!=p_proc_current )
{//只有在线程创建线程的时候才会执行 p_parent事实上是父进程
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;//子线程列表
/************更新父进程的info***************/ // 注意 父进程 父进程 父进程
if (p_parent != p_proc_current)
{ // 只有在线程创建线程的时候才会执行 p_parent事实上是父进程
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; // 子线程列表
}
/************更新父线程的info**************/
//p_proc_current->task.info.type; //当前是进程还是线程
//p_proc_current->task.info.real_ppid; //亲父进程,创建它的那个进程
//p_proc_current->task.info.ppid; //当前父进程
//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_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.text_hold; //是否拥有代码
//p_proc_current->task.data_hold; //是否拥有数据
/************更新子线程的info***************/
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.ppid = p_parent->task.pid; //当前父进程
p_child->task.info.child_p_num = 0; //子进程数量
//p_child->task.info.child_process[NR_CHILD_MAX] = pid;//子进程列表
p_child->task.info.child_t_num = 0; //子线程数量
//p_child->task.info.child_thread[NR_CHILD_MAX];//子线程列表
p_child->task.info.text_hold = 0; //是否拥有代码,子进程不拥有代码
p_child->task.info.data_hold = 0; //是否拥有数据,子进程拥有数据
/************更新父线程的info**************/
// p_proc_current->task.info.type; //当前是进程还是线程
// p_proc_current->task.info.real_ppid; //亲父进程,创建它的那个进程
// p_proc_current->task.info.ppid; //当前父进程
// 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_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.text_hold; //是否拥有代码
// p_proc_current->task.data_hold; //是否拥有数据
/************更新子线程的info***************/
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.ppid = p_parent->task.pid; // 当前父进程
p_child->task.info.child_p_num = 0; // 子进程数量
// p_child->task.info.child_process[NR_CHILD_MAX] = pid;//子进程列表
p_child->task.info.child_t_num = 0; // 子线程数量
// p_child->task.info.child_thread[NR_CHILD_MAX];//子线程列表
p_child->task.info.text_hold = 0; // 是否拥有代码,子进程不拥有代码
p_child->task.info.data_hold = 0; // 是否拥有数据,子进程拥有数据
return 0;
}
/**********************************************************
* pthread_stack_init //add by visual 2016.5.26
*线esp
*************************************************************/
static int pthread_stack_init(PROCESS* p_child,PROCESS *p_parent)
* pthread_stack_init //add by visual 2016.5.26
*线esp
*************************************************************/
static int pthread_stack_init(PROCESS *p_child, PROCESS *p_parent)
{
int addr_lin;
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_parent->task.memmap.stack_child_limit += 0x4000; //分配16K
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)//申请物理地址
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_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
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_parent->task.memmap.stack_child_limit += 0x4000; // 分配16K
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) // 申请物理地址
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_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
return 0;
}
/**********************************************************
* pthread_stack_init //add by visual 2016.5.26
*线使
*************************************************************/
static int pthread_heap_init(PROCESS* p_child,PROCESS *p_parent)
* pthread_stack_init //add by visual 2016.5.26
*线使
*************************************************************/
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_limit = (u32)&(p_parent->task.memmap.heap_lin_limit);
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);
return 0;
}

View File

@ -12,27 +12,30 @@
#include "global.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.
* added by xw, 18/4/27
*/
void sys_print_E()
{
{
int i, j;
disp_str("E( ");
printf("E( ");
i = 100;
while(--i){
while (--i)
{
j = 1000;
while(--j){}
while (--j)
{
}
}
disp_str(") ");
printf(") ");
}
/*
/*
* This syscall needs long time to finish, so we can use it
* to check if our os is kernel-preemptive.
* added by xw, 18/4/27
@ -40,14 +43,17 @@ void sys_print_E()
void sys_print_F()
{
int i, j;
disp_str("F( ");
printf("F( ");
i = 100;
while(--i){
while (--i)
{
j = 1000;
while(--j){}
while (--j)
{
}
}
disp_str(") ");
printf(") ");
}

View File

@ -127,7 +127,7 @@ void vga_tty_init(NTTY *tty)
assert(tty->driver_type == 1);
assert(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++];
// kprintf("malloced %p %p %p\n", vga->buf, &vga->buf, &vga->scr_top_line);
vga->cur_col = vga->cur_row = 0;
@ -357,7 +357,7 @@ static void set_color(vga_buf *vgabuf)
{
warn("unsupport CSI: color");
}
if (vgabuf->CSI == CSI_PARAM2)
if (vgabuf->Is2param == true)
{
if (vgabuf->param2 == 0 && vgabuf->param1 == 0)
{
@ -564,6 +564,7 @@ void vga_tty_write(NTTY *tty, char ch)
break;
case '\x1b':
vga->CSI = CSI_BRACKET;
vga->Is2param = false;
break;
default:
if (vga->color == 0)
@ -615,6 +616,7 @@ void vga_tty_write(NTTY *tty, char ch)
break;
case ';':
vga->CSI = CSI_PARAM2;
vga->Is2param = true;
break;
default:
if (!(0x20 <= ch && ch <= 0x7e))

View File

@ -6,31 +6,23 @@
#include "tty.h"
#include "serialport.h"
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)
static void serialputch(int ch, void *cnt)
{
char buf[2]={(char)ch,'\0'};
disp_str(buf);
// write_serial(ch);
char _ch = ch;
tty_write(cur_ntty, &_ch, 1);
}
int
vkprintf(const char *fmt, va_list ap)
int vkprintf(const char *fmt, va_list ap)
{
// vprintfmt((void*)kprintfputch, NULL, fmt, ap);
vprintfmt((void*)serialputch, NULL, fmt, ap);
vprintfmt((void *)serialputch, NULL, fmt, ap);
return 0;
}
int
kprintf(const char *fmt, ...)
int kprintf(const char *fmt, ...)
{
va_list ap;
int rc;

View File

@ -34,16 +34,18 @@ int main(int arg, char *argv[])
// printf("8888888888");
// printf("9999999999\r\b\b\n");
// }
printf("\x1b[36m");
printf("\x1b[33m");
for (int i = 0; i < 40; i++)
{
printf("%d", i);
printf("11111111111111111\n");
}
printf("\x1b[31;47mexec: path ERROR!\x1b[m");
printf("555555");
// Cursor Up
printf("\x1b[2A");
// printf("\x1b[2A");
// Cursor down
// printf("\x1b[2B");
@ -52,7 +54,7 @@ int main(int arg, char *argv[])
// printf("\x1b[20C");
// Cursor Back
printf("\x1b[2D");
// printf("\x1b[2D");
// Cursor Next Line
// printf("\x1b[3E");
@ -70,7 +72,7 @@ int main(int arg, char *argv[])
// printf("\x1b[3J");
// Erase in Line
printf("\x1b[K");
// printf("\x1b[K");
// Scroll Up
// printf("\x1b[13S");