473 lines
21 KiB
C
473 lines
21 KiB
C
|
||
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||
main.c
|
||
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||
Forrest Yu, 2005
|
||
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
|
||
|
||
#include "type.h"
|
||
#include "const.h"
|
||
#include "protect.h"
|
||
#include "string.h"
|
||
#include "proc.h"
|
||
#include "global.h"
|
||
#include "proto.h"
|
||
#include "fs_const.h"
|
||
#include "hd.h"
|
||
#include "fs.h"
|
||
#include "memman.h"
|
||
#include "vfs.h"
|
||
#include "fat32.h"
|
||
#include "x86.h"
|
||
#include "assert.h"
|
||
#include "stdio.h"
|
||
#include "tty.h"
|
||
#include "serialport.h"
|
||
|
||
static int initialize_processes(); // added by xw, 18/5/26
|
||
static int initialize_cpus(); // added by xw, 18/6/2
|
||
|
||
/*======================================================================*
|
||
kernel_main
|
||
*======================================================================*/
|
||
int kernel_main()
|
||
{
|
||
clear_kernel_pagepte_low();
|
||
|
||
init_serial();
|
||
int error;
|
||
|
||
// disp_pos = 0;
|
||
// for (int i = 0; i < 25; i++) {
|
||
// for (int j = 0; j < 80; j++) {
|
||
// disp_str(" ");
|
||
// }
|
||
// }
|
||
disp_pos = 0;
|
||
|
||
// kprintf("-----Kernel Initialization Begins-----\n");
|
||
kernel_initial = 1; // kernel is in initial state. added by xw, 18/5/31
|
||
|
||
init(); // 内存管理模块的初始化 add by liang
|
||
init_tty_main();
|
||
// initialize PCBs, added by xw, 18/5/26
|
||
error = initialize_processes();
|
||
if (error != 0)
|
||
return error;
|
||
|
||
// initialize CPUs, added by xw, 18/6/2
|
||
error = initialize_cpus();
|
||
if (error != 0)
|
||
return error;
|
||
|
||
k_reenter = 0; // record nest level of only interruption! it's different from Orange's.
|
||
// usage modified by xw
|
||
ticks = 0; // initialize system-wide ticks
|
||
p_proc_current = cpu_table;
|
||
|
||
/************************************************************************
|
||
*device initialization
|
||
added by xw, 18/6/4
|
||
*************************************************************************/
|
||
/* initialize 8253 PIT */
|
||
outb(TIMER_MODE, RATE_GENERATOR);
|
||
outb(TIMER0, (u8)(TIMER_FREQ / HZ));
|
||
outb(TIMER0, (u8)((TIMER_FREQ / HZ) >> 8));
|
||
|
||
/* initialize clock-irq */
|
||
put_irq_handler(CLOCK_IRQ, clock_handler); /* 设定时钟中断处理程序 */
|
||
enable_irq(CLOCK_IRQ); /* 让8259A可以接收时钟中断 */
|
||
|
||
init_kb(); // added by mingxuan 2019-5-19
|
||
|
||
/* initialize hd-irq and hd rdwt queue */
|
||
init_hd();
|
||
|
||
/* enable interrupt, we should read information of some devices by interrupt.
|
||
* Note that you must have initialized all devices ready before you enable
|
||
* interrupt. added by xw
|
||
*/
|
||
enable_int();
|
||
|
||
/***********************************************************************
|
||
open hard disk and initialize file system
|
||
coded by zcr on 2017.6.10. added by xw, 18/5/31
|
||
************************************************************************/
|
||
init_fileop_table(); // added by mingxuan 2019-5-17
|
||
|
||
// hd_open(MINOR(ROOT_DEV));
|
||
hd_open(PRIMARY_MASTER); // modified by mingxuan 2020-10-27
|
||
|
||
init_vfs(); // added by mingxuan 2020-10-30
|
||
init_fs();
|
||
init_fs_fat(); // added by mingxuan 2019-5-17
|
||
// init_vfs(); //added by mingxuan 2019-5-17 //deleted by mingxuan 2020-10-30
|
||
|
||
/*************************************************************************
|
||
*第一个进程开始启动执行
|
||
**************************************************************************/
|
||
/* we don't want interrupt happens before processes run.
|
||
* added by xw, 18/5/31
|
||
*/
|
||
disable_int();
|
||
|
||
kprintf("-----Processes Begin-----\n");
|
||
|
||
/* linear address 0~8M will no longer be mapped to physical address 0~8M.
|
||
* note that disp_xx can't work after this function is invoked until processes runs.
|
||
* add by visual 2016.5.13; moved by xw, 18/5/30
|
||
*/
|
||
|
||
p_proc_current = proc_table;
|
||
kernel_initial = 0; // kernel initialization is done. added by xw, 18/5/31
|
||
restart_initial(); // modified by xw, 18/4/19
|
||
while (1)
|
||
{
|
||
}
|
||
}
|
||
|
||
/*************************************************************************
|
||
return 0 if there is no error, or return -1.
|
||
added by xw, 18/6/2
|
||
***************************************************************************/
|
||
static int initialize_cpus()
|
||
{
|
||
// just use the fields of struct PCB in cpu_table, we needn't initialize
|
||
// something at present.
|
||
|
||
return 0;
|
||
}
|
||
|
||
/*************************************************************************
|
||
进程初始化部分
|
||
return 0 if there is no error, or return -1.
|
||
moved from kernel_main() by xw, 18/5/26
|
||
***************************************************************************/
|
||
static int initialize_processes()
|
||
{
|
||
TASK *p_task = task_table;
|
||
PROCESS *p_proc = proc_table;
|
||
u16 selector_ldt = SELECTOR_LDT_FIRST;
|
||
char *p_regs; // point to registers in the new kernel stack, added by xw, 17/12/11
|
||
task_f eip_context; // a funtion pointer, added by xw, 18/4/18
|
||
/*************************************************************************
|
||
*进程初始化部分 edit by visual 2016.5.4
|
||
***************************************************************************/
|
||
int pid;
|
||
u32 AddrLin, err_temp; // edit by visual 2016.5.9
|
||
|
||
/* set common fields in PCB. added by xw, 18/5/25 */
|
||
p_proc = proc_table;
|
||
for (pid = 0; pid < NR_PCBS; pid++)
|
||
{
|
||
// some operations
|
||
p_proc++;
|
||
}
|
||
|
||
p_proc = proc_table;
|
||
for (pid = 0; pid < NR_TASKS; pid++)
|
||
{ // 1>对前NR_TASKS个PCB初始化,且状态为READY(生成的进程)
|
||
/*************基本信息*********************************/
|
||
strcpy(p_proc->task.p_name, p_task->name); // 名称
|
||
p_proc->task.pid = pid; // pid
|
||
p_proc->task.stat = READY; // 状态
|
||
|
||
/**************LDT*********************************/
|
||
p_proc->task.ldt_sel = selector_ldt;
|
||
memcpy(&p_proc->task.ldts[0], &gdt[SELECTOR_KERNEL_CS >> 3], sizeof(DESCRIPTOR));
|
||
p_proc->task.ldts[0].attr1 = DA_C | PRIVILEGE_TASK << 5;
|
||
memcpy(&p_proc->task.ldts[1], &gdt[SELECTOR_KERNEL_DS >> 3], sizeof(DESCRIPTOR));
|
||
p_proc->task.ldts[1].attr1 = DA_DRW | PRIVILEGE_TASK << 5;
|
||
|
||
/**************寄存器初值**********************************/
|
||
p_proc->task.regs.cs = ((8 * 0) & SA_RPL_MASK & SA_TI_MASK) | SA_TIL | RPL_TASK;
|
||
p_proc->task.regs.ds = ((8 * 1) & SA_RPL_MASK & SA_TI_MASK) | SA_TIL | RPL_TASK;
|
||
p_proc->task.regs.es = ((8 * 1) & SA_RPL_MASK & SA_TI_MASK) | SA_TIL | RPL_TASK;
|
||
p_proc->task.regs.fs = ((8 * 1) & SA_RPL_MASK & SA_TI_MASK) | SA_TIL | RPL_TASK;
|
||
p_proc->task.regs.ss = ((8 * 1) & SA_RPL_MASK & SA_TI_MASK) | SA_TIL | RPL_TASK;
|
||
p_proc->task.regs.gs = (SELECTOR_KERNEL_GS & SA_RPL_MASK) | RPL_TASK;
|
||
p_proc->task.regs.eflags = 0x1202; /* IF=1, IOPL=1 */
|
||
// p_proc->task.cr3 在页表初始化中处理
|
||
|
||
/**************线性地址布局初始化**********************************/ // add by visual 2016.5.4
|
||
/**************task的代码数据大小及位置暂时是不会用到的,所以没有初始化************************************/
|
||
p_proc->task.memmap.heap_lin_base = HeapLinBase;
|
||
p_proc->task.memmap.heap_lin_limit = HeapLinBase; // 堆的界限将会一直动态变化
|
||
|
||
p_proc->task.memmap.stack_child_limit = StackLinLimitMAX; // add by visual 2016.5.27
|
||
p_proc->task.memmap.stack_lin_base = StackLinBase;
|
||
p_proc->task.memmap.stack_lin_limit = StackLinBase - 0x4000; // 栈的界限将会一直动态变化,目前赋值为16k,这个值会根据esp的位置进行调整,目前初始化为16K大小
|
||
|
||
p_proc->task.memmap.kernel_lin_base = KernelLinBase;
|
||
p_proc->task.memmap.kernel_lin_limit = KernelLinBase + KernelSize; // 内核大小初始化为8M //add by visual 2016.5.10
|
||
|
||
/***************初始化PID进程页表*****************************/
|
||
if (0 != init_page_pte(pid))
|
||
{
|
||
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
|
||
|
||
/****************代码数据*****************************/
|
||
p_proc->task.regs.eip = (u32)p_task->initial_eip; // 进程入口线性地址 edit by visual 2016.5.4
|
||
|
||
/****************栈(此时堆、栈已经区分,以后实验会重新规划堆的位置)*****************************/
|
||
p_proc->task.regs.esp = (u32)StackLinBase; // 栈地址最高处
|
||
for (AddrLin = StackLinBase; AddrLin > p_proc->task.memmap.stack_lin_limit; AddrLin -= num_4K)
|
||
{ // 栈
|
||
// addr_phy_temp = (u32)do_kmalloc_4k();//为栈申请一个物理页,Task的栈是在内核里面 //delete by visual 2016.5.19
|
||
// if( addr_phy_temp<0 || (addr_phy_temp&0x3FF)!=0 )
|
||
//{
|
||
// 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
|
||
MAX_UNSIGNED_INT, // 物理地址 //edit by visual 2016.5.19
|
||
pid, // 进程pid //edit by visual 2016.5.19
|
||
PG_P | PG_USU | PG_RWW, // 页目录的属性位
|
||
PG_P | PG_USU | PG_RWW); // 页表的属性位
|
||
if (err_temp != 0)
|
||
{
|
||
kprintf("\x1b[31;47mkernel_main Error:lin_mapping_phy\x1b[m");
|
||
return -1;
|
||
}
|
||
}
|
||
|
||
/***************copy registers data to kernel stack****************************/
|
||
// copy registers data to the bottom of the new kernel stack
|
||
// added by xw, 17/12/11
|
||
p_regs = (char *)(p_proc + 1);
|
||
p_regs -= P_STACKTOP;
|
||
memcpy(p_regs, (char *)p_proc, 18 * 4);
|
||
|
||
/***************some field about process switch****************************/
|
||
p_proc->task.esp_save_int = p_regs; // initialize esp_save_int, added by xw, 17/12/11
|
||
// p_proc->task.save_type = 1;
|
||
p_proc->task.esp_save_context = p_regs - 10 * 4; // when the process is chosen to run for the first time,
|
||
// sched() will fetch value from esp_save_context
|
||
eip_context = restart_restore;
|
||
*(u32 *)(p_regs - 4) = (u32)eip_context; // initialize EIP in the context, so the process can
|
||
// start run. added by xw, 18/4/18
|
||
*(u32 *)(p_regs - 8) = 0x1202; // initialize EFLAGS in the context, IF=1, IOPL=1. xw, 18/4/20
|
||
|
||
/***************变量调整****************************/
|
||
p_proc++;
|
||
p_task++;
|
||
selector_ldt += 1 << 3;
|
||
}
|
||
for (; pid < NR_K_PCBS; pid++)
|
||
{ // 2>对中NR_TASKS~NR_K_PCBS的PCB表初始化,状态为IDLE,没有初始化esp(并没有生成,所以没有代码入口,只是留位置)
|
||
/*************基本信息*********************************/
|
||
strcpy(p_proc->task.p_name, "Task"); // 名称
|
||
p_proc->task.pid = pid; // pid
|
||
p_proc->task.stat = IDLE; // 状态
|
||
|
||
/**************LDT*********************************/
|
||
p_proc->task.ldt_sel = selector_ldt;
|
||
memcpy(&p_proc->task.ldts[0], &gdt[SELECTOR_KERNEL_CS >> 3], sizeof(DESCRIPTOR));
|
||
p_proc->task.ldts[0].attr1 = DA_C | PRIVILEGE_TASK << 5;
|
||
memcpy(&p_proc->task.ldts[1], &gdt[SELECTOR_KERNEL_DS >> 3], sizeof(DESCRIPTOR));
|
||
p_proc->task.ldts[1].attr1 = DA_DRW | PRIVILEGE_TASK << 5;
|
||
|
||
/**************寄存器初值**********************************/
|
||
p_proc->task.regs.cs = ((8 * 0) & SA_RPL_MASK & SA_TI_MASK) | SA_TIL | RPL_TASK;
|
||
p_proc->task.regs.ds = ((8 * 1) & SA_RPL_MASK & SA_TI_MASK) | SA_TIL | RPL_TASK;
|
||
p_proc->task.regs.es = ((8 * 1) & SA_RPL_MASK & SA_TI_MASK) | SA_TIL | RPL_TASK;
|
||
p_proc->task.regs.fs = ((8 * 1) & SA_RPL_MASK & SA_TI_MASK) | SA_TIL | RPL_TASK;
|
||
p_proc->task.regs.ss = ((8 * 1) & SA_RPL_MASK & SA_TI_MASK) | SA_TIL | RPL_TASK;
|
||
p_proc->task.regs.gs = (SELECTOR_KERNEL_GS & SA_RPL_MASK) | RPL_TASK;
|
||
p_proc->task.regs.eflags = 0x1202; /* IF=1, IOPL=1 */
|
||
|
||
/****************页表、代码数据、堆栈*****************************/
|
||
// 无
|
||
|
||
/***************copy registers data to kernel stack****************************/
|
||
// copy registers data to the bottom of the new kernel stack
|
||
// added by xw, 17/12/11
|
||
p_regs = (char *)(p_proc + 1);
|
||
p_regs -= P_STACKTOP;
|
||
memcpy(p_regs, (char *)p_proc, 18 * 4);
|
||
|
||
/***************some field about process switch****************************/
|
||
p_proc->task.esp_save_int = p_regs; // initialize esp_save_int, added by xw, 17/12/11
|
||
// p_proc->task.save_type = 1;
|
||
p_proc->task.esp_save_context = p_regs - 10 * 4; // when the process is chosen to run for the first time,
|
||
// sched() will fetch value from esp_save_context
|
||
eip_context = restart_restore;
|
||
*(u32 *)(p_regs - 4) = (u32)eip_context; // initialize EIP in the context, so the process can
|
||
// start run. added by xw, 18/4/18
|
||
*(u32 *)(p_regs - 8) = 0x1202; // initialize EFLAGS in the context, IF=1, IOPL=1. xw, 18/4/20
|
||
|
||
/***************变量调整****************************/
|
||
p_proc++;
|
||
selector_ldt += 1 << 3;
|
||
}
|
||
for (; pid < NR_K_PCBS + 1; pid++)
|
||
{ // initial 进程的初始化 //add by visual 2016.5.17
|
||
/*************基本信息*********************************/
|
||
strcpy(p_proc->task.p_name, "initial"); // 名称
|
||
p_proc->task.pid = pid; // pid
|
||
p_proc->task.stat = READY; // 状态
|
||
|
||
/**************LDT*********************************/
|
||
p_proc->task.ldt_sel = selector_ldt;
|
||
memcpy(&p_proc->task.ldts[0], &gdt[SELECTOR_KERNEL_CS >> 3], sizeof(DESCRIPTOR));
|
||
p_proc->task.ldts[0].attr1 = DA_C | PRIVILEGE_TASK << 5;
|
||
memcpy(&p_proc->task.ldts[1], &gdt[SELECTOR_KERNEL_DS >> 3], sizeof(DESCRIPTOR));
|
||
p_proc->task.ldts[1].attr1 = DA_DRW | PRIVILEGE_TASK << 5;
|
||
|
||
/**************寄存器初值**********************************/
|
||
p_proc->task.regs.cs = ((8 * 0) & SA_RPL_MASK & SA_TI_MASK) | SA_TIL | RPL_TASK;
|
||
p_proc->task.regs.ds = ((8 * 1) & SA_RPL_MASK & SA_TI_MASK) | SA_TIL | RPL_TASK;
|
||
p_proc->task.regs.es = ((8 * 1) & SA_RPL_MASK & SA_TI_MASK) | SA_TIL | RPL_TASK;
|
||
p_proc->task.regs.fs = ((8 * 1) & SA_RPL_MASK & SA_TI_MASK) | SA_TIL | RPL_TASK;
|
||
p_proc->task.regs.ss = ((8 * 1) & SA_RPL_MASK & SA_TI_MASK) | SA_TIL | RPL_TASK;
|
||
p_proc->task.regs.gs = (SELECTOR_KERNEL_GS & SA_RPL_MASK) | RPL_TASK;
|
||
p_proc->task.regs.eflags = 0x1202; /* IF=1, IOPL=1 */
|
||
// p_proc->task.cr3 在页表初始化中处理
|
||
|
||
/**************线性地址布局初始化**********************************/ // edit by visual 2016.5.25
|
||
p_proc->task.memmap.text_lin_base = 0; // initial这些段的数据并不清楚,在变身init的时候才在中赋新值
|
||
p_proc->task.memmap.text_lin_limit = 0; // initial这些段的数据并不清楚,在变身init的时候才在exec中赋新值
|
||
p_proc->task.memmap.data_lin_base = 0; // initial这些段的数据并不清楚,在变身init的时候才在exec中赋新值
|
||
p_proc->task.memmap.data_lin_limit = 0; // initial这些段的数据并不清楚,在变身init的时候才在exec中赋新值
|
||
p_proc->task.memmap.vpage_lin_base = VpageLinBase; // 保留内存基址
|
||
p_proc->task.memmap.vpage_lin_limit = VpageLinBase; // 保留内存界限
|
||
p_proc->task.memmap.heap_lin_base = HeapLinBase; // 堆基址
|
||
p_proc->task.memmap.heap_lin_limit = HeapLinBase; // 堆界限
|
||
p_proc->task.memmap.stack_lin_base = StackLinBase; // 栈基址
|
||
p_proc->task.memmap.stack_lin_limit = StackLinBase - 0x4000; // 栈界限(使用时注意栈的生长方向)
|
||
p_proc->task.memmap.arg_lin_base = ArgLinBase; // 参数内存基址
|
||
p_proc->task.memmap.arg_lin_limit = ArgLinBase; // 参数内存界限
|
||
p_proc->task.memmap.kernel_lin_base = KernelLinBase; // 内核基址
|
||
p_proc->task.memmap.kernel_lin_limit = KernelLinBase + KernelSize; // 内核大小初始化为8M
|
||
|
||
/*************************进程树信息初始化***************************************/
|
||
p_proc->task.info.type = TYPE_PROCESS; // 当前是进程还是线程
|
||
p_proc->task.info.real_ppid = -1; // 亲父进程,创建它的那个进程
|
||
p_proc->task.info.ppid = -1; // 当前父进程
|
||
p_proc->task.info.child_p_num = 0; // 子进程数量
|
||
// p_proc->task.info.child_process[NR_CHILD_MAX];//子进程列表
|
||
p_proc->task.info.child_t_num = 0; // 子线程数量
|
||
// p_proc->task.info.child_thread[NR_CHILD_MAX];//子线程列表
|
||
p_proc->task.info.text_hold = 1; // 是否拥有代码
|
||
p_proc->task.info.data_hold = 1; // 是否拥有数据
|
||
|
||
/***************初始化PID进程页表*****************************/
|
||
if (0 != init_page_pte(pid))
|
||
{
|
||
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
|
||
|
||
/****************代码数据*****************************/
|
||
p_proc->task.regs.eip = (u32)initial; // 进程入口线性地址 edit by visual 2016.5.17
|
||
|
||
/****************栈(此时堆、栈已经区分,以后实验会重新规划堆的位置)*****************************/
|
||
p_proc->task.regs.esp = (u32)StackLinBase; // 栈地址最高处
|
||
for (AddrLin = StackLinBase; AddrLin > p_proc->task.memmap.stack_lin_limit; AddrLin -= num_4K)
|
||
{ // 栈
|
||
// addr_phy_temp = (u32)do_kmalloc_4k();//为栈申请一个物理页,Task的栈是在内核里面 //delete by visual 2016.5.19
|
||
// if( addr_phy_temp<0 || (addr_phy_temp&0x3FF)!=0 )
|
||
//{
|
||
// kprintf("\x1b[31;47mkernel_main Error:addr_phy_temp\x1b[m");
|
||
// return -1;
|
||
// }
|
||
err_temp = lin_mapping_phy(AddrLin, // 线性地址
|
||
MAX_UNSIGNED_INT, // 物理地址 //edit by visual 2016.5.19
|
||
pid, // 进程pid //edit by visual 2016.5.19
|
||
PG_P | PG_USU | PG_RWW, // 页目录的属性位
|
||
PG_P | PG_USU | PG_RWW); // 页表的属性位
|
||
if (err_temp != 0)
|
||
{
|
||
kprintf("\x1b[31;47mkernel_main Error:lin_mapping_phy\x1b[m");
|
||
return -1;
|
||
}
|
||
}
|
||
|
||
/***************copy registers data to kernel stack****************************/
|
||
// copy registers data to the bottom of the new kernel stack
|
||
// added by xw, 17/12/11
|
||
p_regs = (char *)(p_proc + 1);
|
||
p_regs -= P_STACKTOP;
|
||
memcpy(p_regs, (char *)p_proc, 18 * 4);
|
||
|
||
/***************some field about process switch****************************/
|
||
p_proc->task.esp_save_int = p_regs; // initialize esp_save_int, added by xw, 17/12/11
|
||
// p_proc->task.save_type = 1;
|
||
p_proc->task.esp_save_context = p_regs - 10 * 4; // when the process is chosen to run for the first time,
|
||
// sched() will fetch value from esp_save_context
|
||
eip_context = restart_restore;
|
||
*(u32 *)(p_regs - 4) = (u32)eip_context; // initialize EIP in the context, so the process can
|
||
// start run. added by xw, 18/4/18
|
||
*(u32 *)(p_regs - 8) = 0x1202; // initialize EFLAGS in the context, IF=1, IOPL=1. xw, 18/4/20
|
||
|
||
/***************变量调整****************************/
|
||
p_proc++;
|
||
selector_ldt += 1 << 3;
|
||
}
|
||
for (; pid < NR_PCBS; pid++)
|
||
{ // 3>对后NR_K_PCBS~NR_PCBS的PCB表部分初始化,(名称,pid,stat,LDT选择子),状态为IDLE.
|
||
/*************基本信息*********************************/
|
||
strcpy(p_proc->task.p_name, "USER"); // 名称
|
||
p_proc->task.pid = pid; // pid
|
||
p_proc->task.stat = IDLE; // 状态
|
||
|
||
/**************LDT*********************************/
|
||
p_proc->task.ldt_sel = selector_ldt;
|
||
memcpy(&p_proc->task.ldts[0], &gdt[SELECTOR_KERNEL_CS >> 3], sizeof(DESCRIPTOR));
|
||
p_proc->task.ldts[0].attr1 = DA_C | PRIVILEGE_USER << 5;
|
||
memcpy(&p_proc->task.ldts[1], &gdt[SELECTOR_KERNEL_DS >> 3], sizeof(DESCRIPTOR));
|
||
p_proc->task.ldts[1].attr1 = DA_DRW | PRIVILEGE_USER << 5;
|
||
|
||
/**************寄存器初值**********************************/
|
||
p_proc->task.regs.cs = ((8 * 0) & SA_RPL_MASK & SA_TI_MASK) | SA_TIL | RPL_USER;
|
||
p_proc->task.regs.ds = ((8 * 1) & SA_RPL_MASK & SA_TI_MASK) | SA_TIL | RPL_USER;
|
||
p_proc->task.regs.es = ((8 * 1) & SA_RPL_MASK & SA_TI_MASK) | SA_TIL | RPL_USER;
|
||
p_proc->task.regs.fs = ((8 * 1) & SA_RPL_MASK & SA_TI_MASK) | SA_TIL | RPL_USER;
|
||
p_proc->task.regs.ss = ((8 * 1) & SA_RPL_MASK & SA_TI_MASK) | SA_TIL | RPL_USER;
|
||
p_proc->task.regs.gs = (SELECTOR_KERNEL_GS & SA_RPL_MASK) | RPL_USER;
|
||
p_proc->task.regs.eflags = 0x0202; /* IF=1, 倒数第二位恒为1 */
|
||
|
||
/****************页表、代码数据、堆栈*****************************/
|
||
// 无
|
||
|
||
/***************copy registers data to kernel stack****************************/
|
||
// copy registers data to the bottom of the new kernel stack
|
||
// added by xw, 17/12/11
|
||
p_regs = (char *)(p_proc + 1);
|
||
p_regs -= P_STACKTOP;
|
||
memcpy(p_regs, (char *)p_proc, 18 * 4);
|
||
|
||
/***************some field about process switch****************************/
|
||
p_proc->task.esp_save_int = p_regs; // initialize esp_save_int, added by xw, 17/12/11
|
||
// p_proc->task.save_type = 1;
|
||
p_proc->task.esp_save_context = p_regs - 10 * 4; // when the process is chosen to run for the first time,
|
||
// sched() will fetch value from esp_save_context
|
||
eip_context = restart_restore;
|
||
*(u32 *)(p_regs - 4) = (u32)eip_context; // initialize EIP in the context, so the process can
|
||
// start run. added by xw, 18/4/18
|
||
*(u32 *)(p_regs - 8) = 0x1202; // initialize EFLAGS in the context, IF=1, IOPL=1. xw, 18/4/20
|
||
|
||
/***************变量调整****************************/
|
||
p_proc++;
|
||
selector_ldt += 1 << 3;
|
||
}
|
||
|
||
proc_table[0].task.ticks = proc_table[0].task.priority = 1;
|
||
proc_table[1].task.ticks = proc_table[1].task.priority = 1;
|
||
proc_table[2].task.ticks = proc_table[2].task.priority = 1;
|
||
proc_table[3].task.ticks = proc_table[3].task.priority = 1; // added by xw, 18/8/27
|
||
proc_table[NR_K_PCBS].task.ticks = proc_table[NR_K_PCBS].task.priority = 1;
|
||
|
||
/* When the first process begin running, a clock-interruption will happen immediately.
|
||
* If the first process's initial ticks is 1, it won't be the first process to execute its
|
||
* user code. Thus, it's will look weird, for proc_table[0] don't output first.
|
||
* added by xw, 18/4/19
|
||
*/
|
||
proc_table[0].task.ticks = 2;
|
||
|
||
return 0;
|
||
} |