I'm trying to write hardware multitasking it consists of two tasks,
task() and main(),I really don't know what the problem is but Bochs
gives me this message: "task_switch: CS NULL",so can any one help me
here is the code....
Code: Select all
#define ACS_PRESENT 0X80 /* present segment */
#define ACS_CSEG 0X18 /* code segment */
#define ACS_DSEG 0X10 /* data segment */
#define ACS_CONIFORM 0X04
#define ACS_READ 0X02
#define ACS_WRITE 0X02
#define ACS_TSS_GATE 0X09
#define ACS_TSS (ACS_PRESENT | ACS_TSS_GATE)
/* ready-made values */
#define ACS_CODE (ACS_PRESENT | ACS_CSEG | ACS_READ)
#define ACS_DATA (ACS_PRESENT | ACS_DSEG | ACS_WRITE)
Code: Select all
#define max_gdt_entrys 5
struct gdt_entry
{
unsigned short limit_low;
unsigned short base_low;
unsigned char base_middle;
unsigned char access;
unsigned char granularity;
unsigned char base_high;
} __attribute__((packed));
/* Special pointer which includes the limit: The max bytes
* taken up by the GDT, minus 1. Again, this NEEDS to be packed */
struct gdt_ptr
{
unsigned short limit;
unsigned int base;
} __attribute__((packed));
/* Our GDT, with 5 entries, and finally our special GDT pointer */
struct gdt_entry gdt[max_gdt_entrys];
struct gdt_ptr gp;
extern gdt_flush();
/* Setup a descriptor in the Global Descriptor Table */
void gdt_set_gate(int num, unsigned long base, unsigned long limit, unsigned char access, unsigned char gran)
{
/* Setup the descriptor base address */
gdt[num].base_low = (base & 0xFFFF);
gdt[num].base_middle = (base >> 16) & 0xFF;
gdt[num].base_high = (base >> 24) & 0xFF;
/* Setup the descriptor limits */
gdt[num].limit_low = (limit & 0xFFFF);
gdt[num].granularity = ((limit >> 16) & 0x0F);
/* Finally, set up the granularity and access flags */
gdt[num].granularity |= (gran & 0xF0);
gdt[num].access = access;
}
void gdt_install()
{
printf("Installing GDT...");
/* Setup the GDT pointer and limit */
gp.limit = (sizeof(struct gdt_entry) * max_gdt_entrys) - 1;
gp.base = &gdt;
/* Our NULL descriptor 0x00 */
gdt_set_gate(0, 0, 0, 0, 0);
/* code descriptor */
gdt_set_gate(1, 0, 0xFFFF, ACS_CODE , 0xCF);
/* data descriptor */
gdt_set_gate(2, 0,0xFFFF, ACS_DATA , 0xCF);
/* -- 0x18 TSS for main() */
gdt_set_gate(3,(word)&tss[0],sizeof(TSS),ACS_TSS,0xCF);
/* -- 0x20 TSS for task() */
gdt_set_gate(4,(word)&tss[1],sizeof(TSS),ACS_TSS,0xCF);
/* Flush out the old GDT and install the new changes! */
gdt_flush();
printf("[Done]\n");
}
Code: Select all
struct tss_t
{
dword link,
esp0,
ss0,
esp1,
ss1,
esp2,
ss2,
cr3,
eip,
eflags,
eax,
ecx,
edx,
ebx,
esp,
ebp,
esi,
edi,
es,
cs,
ss,
ds,
fs,
gs,
ldtr;
word trace,
io_map_addr;
};
typedef struct tss_t TSS;
#define max_tasks 2
TSS tss[max_tasks];
#define stack_size 1024
byte task_stack[stack_size];
void init_task()
{
disable();
tss[0].trace=tss[1].trace=0;
tss[0].io_map_addr=tss[1].io_map_addr=sizeof(TSS);
tss[0].ldtr=tss[1].ldtr=0;
tss[1].fs=tss[1].gs=0;
tss[1].ds=tss[1].es=tss[1].ss=0x10;
tss[1].esp=(word)&task_stack+stack_size;
tss[1].cs=0x8;
tss[1].eip=(word)&task;
tss[1].eflags=0x202L;
ltr(0x18);
enable();
}
void ltr(unsigned short selector)
{
asm ("ltr %0": :"r" (selector));
}
void task()
{
printf("Hello form task()\n");
}
void far_jmp(unsigned int selector)
{
unsigned int sel[2];
sel[1] = selector;
asm ("ljmp %0": :"m" (*sel));
}
far jump to "task()" descriptor i get that message.
Thanx