Thanks for your replay. Until now, there are a process can run normally in kernel. And all of GDT,IDT,TSS etc. have been defined but not be initialized yet until each of process is initialized. And the next step, I want to add another two process to kernel. So I defined and initialized an array "task_table[3]" similar to the one in minix which is used to initialize the body of each process easily. The codes are as follows
Code: Select all
/*global.c*/
#include "type.h"
#include "const.h"
#include "protect.h"
#include "proc.h"
#include "global.h"
#include "proto.h"
struct proc_s proc_table[3];
char T_Stack[0x8000 * 3]; // Initialize task stacks;
struct task_s task_table[3] = {{process0, 0x8000, "TestA"},
{process1, 0x8000, "TestB"},
{process2, 0x8000, "TestC"}};
char a[3]={1,2,3};
And those global variables are declared in "global.h" as follows
Code: Select all
/*global.h*/
.....
struct gate_s idt[256];
unsigned int print_here;
struct tss_s tss;
struct proc_s * rp;
extern struct proc_s proc_table[3];
extern char T_Stack[0x8000 * 3];
extern struct task_s task_table[3];
The type of those variables are defined in "proc.h" as follows
Code: Select all
/*proc.h*/
.....
typedef struct proc_s {
struct stackframe_s regs; /* process' registers saved in stack frame */
unsigned short p_ldt_sel; /* selector in gdt giving ldt base and limit*/
struct descriptor_s p_ldt[LDT_SIZE]; /* local descriptors for code and data */
/* 2 is LDT_SIZE - avoid include protect.h */
unsigned int p_id; /* process id passed in from MM */
char p_name[16]; /* name of the process */
};
typedef struct task_s {
t_pf_task initial_eip;
int stacksize;
char name[32];
};
The initialization of process is handled in "main.c" as follows
Code: Select all
/*main.c*/
#include "type.h"
#include "const.h"
#include "protect.h"
#include "string.h"
#include "proc.h"
#include "global.h"
#include "proto.h"
//Initialize every process member, which consists of LDT Selector(two of them), LDT Descriptor, Registers, ID and name.
int main()
{
print("main begins!");
struct task_s * t = task_table;
// print(task_table[0].name);
struct proc_s * p = proc_table;
char * s = T_Stack + 0x8000 * 3;
unsigned short l = 8 * 5;
int i;
for(i=0;i<3;i++){
strcpy(p->p_name, t->name);
p->p_id = i;
p->p_ldt_sel = l;
/*There are, actually, two items of LDT per process, which are SELECTOR_KERNEL_CS and SELECTOR_KERNEL_DS;
Initialize both of them now. */
memcpy(&p->p_ldt[0], &gdt[1], sizeof(struct descriptor_s));
.......
There got nothing to do with bootloader, that's for sure. And GDT etc. have been initialized and loader already, besides, the single process could just run fine. The question is ,after I look up mapfile shown below and find out where task_table[] is, I check out that piece of memory and find that there's all blank.
Code: Select all
/*mapfile*/
.......
.data 0x00012060 0x7b
*(.data .data.* .gnu.linkonce.d.*)
.data 0x00012060 0x7b kernel/global.o
0x000120d8 a
0x00012060 task_table
..........
COMMON 0x00013580 0x18150 kernel/global.o
0x0 (size before relaxing)
0x00013580 T_Stack
0x0002b580 proc_table
......
Under this circumstance, the processes' body cannot be initialized normally, whose eip I guess has not been allocated or just be allocated with value "0", so there is an exception "invalid opcode" happend and CPU halted at address of cs:0x5, eip:0x3 printed out from specific exception handler when kernel is running.