Here is my main.c file:
Code: Select all
//todo: eventually move printing functions into own module
unsigned char * video_mem = (unsigned char *)0xB8000; //current location of video pointer
void print(char * letter){ //print string
int i, line, offset;
for(i = 0; letter[i]; i++){
if(video_mem >= (unsigned char *)0xB8FA0){
//this occurs if the text reaches the end of the screen. insert scrolling code here
break;
}else if(letter[i] == '\n'){
offset = (unsigned int)video_mem - 0xB8000;
line = (offset / 160) + 1;
video_mem = (unsigned char *)((line * 160) + 0xB8000);
}else if(letter[i] == '\b'){
video_mem -= 2;
video_mem[0] = 0;
}else if(letter[i] == '\t'){
video_mem += 8;
}else{
video_mem[0] = letter[i];
video_mem[1] = 2;
video_mem += 2;
}
}
}
struct mb_struct{ //multiboot structure
unsigned int flags;
unsigned int mem_lower;
unsigned int mem_upper;
unsigned char boot_device_part3;
unsigned char boot_device_part2;
unsigned char boot_device_part1;
unsigned char boot_device_drive;
unsigned int cmdline;
unsigned int mods_count;
unsigned int mods_addr;
}__attribute__ ((packed));
struct gdt{ //gdt table
short segment_limit;
short base_address;
short base_address2:8;
short type:4;
short flags:4;
short segment_limit2:4;
short flags2:4;
short base_address3;
}__attribute__ ((packed));
struct segment_r{ //segment register gdt/idt/ldt
short size;
int base;
} __attribute__ ((packed));
struct segment_r gdt_register;
struct segment_r idt_register;
struct idt{ //structure of idt table
short offset;
short segment_selector;
short zero:8;
short flags:8;
short offset2;
} __attribute__ ((packed));
struct idt idt_table[33]; //idt table
void set_idt(int function, int number, int erase){ //installs isrs
if(erase){
idt_table[number].offset = 0;
idt_table[number].segment_selector = 0;
idt_table[number].zero = 0;
idt_table[number].flags = 0;
idt_table[number].offset2 = 0;
}else{
idt_table[number].offset = function & 0xFFFF;
idt_table[number].segment_selector = 0x18;
idt_table[number].zero = 0;
idt_table[number].flags = 0x8E;
idt_table[number].offset2 = function << 16;
}
}
void kpanic(){ //test code for interrupts. will be changed later
print("an interrupt was fired");
asm("iret");
}
void kernel_entry(struct mb_struct * mb_structure){ //equiv. of int main()
//load gdt
struct gdt gdt_table[3];
gdt_table[0].segment_limit = 0;
gdt_table[0].base_address = 0;
gdt_table[0].base_address2 = 0;
gdt_table[0].type = 0;
gdt_table[0].flags = 0;
gdt_table[0].segment_limit2 = 0;
gdt_table[0].flags2 = 0;
gdt_table[0].base_address3 = 0;
gdt_table[1].segment_limit = 0xFFFF;
gdt_table[1].base_address = 0;
gdt_table[1].base_address2 = 0;
gdt_table[1].type = 2; //data
gdt_table[1].flags = 8;
gdt_table[1].segment_limit2 = 0xF;
gdt_table[1].flags2 = 0xD;
gdt_table[1].base_address3 = 0;
gdt_table[2].segment_limit = 0xFFFF;
gdt_table[2].base_address = 0;
gdt_table[2].base_address2 = 0;
gdt_table[2].type = 10; //code
gdt_table[2].flags = 8;
gdt_table[2].segment_limit2 = 0xF;
gdt_table[2].flags2 = 0xD;
gdt_table[2].base_address3 = 0;
gdt_register.size = 24;
gdt_register.base = (int)&gdt_table;
asm("lgdt gdt_register");
//load idt
set_idt((int)&kpanic, 0, 0);
set_idt((int)&kpanic, 1, 0);
set_idt((int)&kpanic, 2, 0);
set_idt((int)&kpanic, 3, 0);
set_idt((int)&kpanic, 4, 0);
set_idt((int)&kpanic, 5, 0);
set_idt((int)&kpanic, 6, 0);
set_idt((int)&kpanic, 7, 0);
set_idt((int)&kpanic, 8, 0);
set_idt((int)&kpanic, 9, 0);
set_idt((int)&kpanic, 10, 0);
set_idt((int)&kpanic, 11, 0);
set_idt((int)&kpanic, 12, 0);
set_idt((int)&kpanic, 13, 0);
set_idt((int)&kpanic, 14, 0);
set_idt((int)&kpanic, 15, 0);
set_idt((int)&kpanic, 16, 0);
set_idt((int)&kpanic, 17, 0);
set_idt((int)&kpanic, 18, 0);
set_idt((int)&kpanic, 19, 0);
set_idt(0, 20, 1);
set_idt(0, 21, 1);
set_idt(0, 22, 1);
set_idt(0, 23, 1);
set_idt(0, 24, 1);
set_idt(0, 25, 1);
set_idt(0, 26, 1);
set_idt(0, 27, 1);
set_idt(0, 28, 1);
set_idt(0, 29, 1);
set_idt(0, 30, 1);
set_idt(0, 31, 1);
set_idt((int)&kpanic, 32, 0);
idt_register.size = 256; //32 * 8
idt_register.base = (int)&idt_table;
asm("lidt idt_register");
asm("sti");
print("haven't crashed yet!");
}
Code: Select all
.long 0x1BADB002 /* grub multiboot header */
.long 1<<0 | 1<<1
.long -(0x1BADB002 + 1<<0 | 1<<1)
main_loop: /* does nothing */
hlt
jmp main_loop
.comm kernel_stack, 0x8000 /* reserves for the kernel stack */
.global kernel_entry
.global entry
entry:
mov $(kernel_stack + 0x4000), %esp /* sets up stack */
push %ebx /* push multiboot structure */
call kernel_entry
jmp main_loop
thanks