Code: Select all
gdt_entries[num].granularity |= granularity & 0x0F;
Code: Select all
gdt_entries[num].granularity |= granularity & 0xF0;
Code: Select all
gdt_entries[num].granularity |= granularity & 0x0F;
Code: Select all
gdt_entries[num].granularity |= granularity & 0xF0;
Code: Select all
#include <stdint.h>
struct gdt_entry {
uint16_t limit_low;
uint16_t base_low;
uint8_t base_middle;
uint8_t access;
uint8_t granularity;
uint8_t base_high;
};
struct gdt_ptr {
uint16_t limit;
uint32_t base;
};
void init_gdt();
extern void gdt_flush(uint32_t);
static void gdt_set_gate(int32_t,uint32_t,uint32_t,uint8_t,uint8_t);
struct gdt_entry gdt_entries[5];
struct gdt_ptr gdt_ptr;
void init_gdt() {
gdt_ptr.limit = (sizeof(struct gdt_entry) * 5) - 1;
gdt_ptr.base = (uint32_t)&gdt_entries;
gdt_set_gate(0,0,0,0,0);
gdt_set_gate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF);
gdt_set_gate(2, 0, 0xFFFFFFFF, 0x92, 0xCF);
gdt_set_gate(3, 0, 0xFFFFFFFF, 0xFA, 0xCF);
gdt_set_gate(4, 0, 0xFFFFFFFF, 0xF2, 0xCF);
gdt_flush((uint32_t)&gdt_ptr);
}
static void gdt_set_gate(int32_t num,uint32_t base,uint32_t limit,
uint8_t access,uint8_t granularity) {
gdt_entries[num].base_low = (base & 0xFFFF);
gdt_entries[num].base_middle = (base >> 16) & 0xFF;
gdt_entries[num].base_high = (base >> 24) & 0xFF;
gdt_entries[num].limit_low = (limit & 0xFFFF);
gdt_entries[num].granularity = (limit >> 16) & 0x0F;
gdt_entries[num].granularity |= granularity & 0xF0;
gdt_entries[num].access = access;
}
Code: Select all
struct gdt_ptr {
uint16_t limit;
uint32_t base;
};
Code: Select all
struct gdt_ptr {
uint16_t limit;
uint32_t base;
} __attribute__((packed));
Code: Select all
#include <stdint.h>
#include "../../include/string.h"
struct idt_entry {
uint16_t base_low;
uint16_t selector;
uint8_t always_zero;
uint8_t flags;
uint16_t base_high;
}__attribute__((packed));
struct idt_ptr {
uint16_t limit;
uint32_t base;
}__attribute__((packed));
struct idt_ptr idt_ptr;
struct idt_entry idt_entries[256];
extern void idt_flush(uint32_t);
static void idt_set_gate(uint8_t,uint32_t,uint16_t,uint8_t);
void init_idt();
extern void isr0();
extern void isr1();
extern void isr2();
extern void isr3();
extern void isr4();
extern void isr5();
extern void isr6();
extern void isr7();
extern void isr8();
extern void isr9();
extern void isr10();
extern void isr11();
extern void isr12();
extern void isr13();
extern void isr14();
extern void isr15();
extern void isr16();
extern void isr17();
extern void isr18();
extern void isr19();
extern void isr20();
extern void isr21();
extern void isr22();
extern void isr23();
extern void isr24();
extern void isr25();
extern void isr26();
extern void isr27();
extern void isr28();
extern void isr29();
extern void isr30();
extern void isr31();
void init_idt() {
idt_ptr.limit = sizeof(struct idt_entry) * 256 - 1;
idt_ptr.base = (uint32_t)&idt_entries;
memset(&idt_entries,0,sizeof(struct idt_entry) * 256);
idt_set_gate(1,(uint32_t)isr0,0x08,0x8E);
idt_set_gate(2,(uint32_t)isr2,0x08,0x8E);
idt_set_gate(3,(uint32_t)isr3,0x08,0x8E);
idt_set_gate(4,(uint32_t)isr4,0x08,0x8E);
idt_set_gate(5,(uint32_t)isr5,0x08,0x8E);
idt_set_gate(6,(uint32_t)isr6,0x08,0x8E);
idt_set_gate(7,(uint32_t)isr7,0x08,0x8E);
idt_set_gate(8,(uint32_t)isr8,0x08,0x8E);
idt_set_gate(9,(uint32_t)isr9,0x08,0x8E);
idt_set_gate(10,(uint32_t)isr10,0x08,0x8E);
idt_set_gate(11,(uint32_t)isr11,0x08,0x8E);
idt_set_gate(12,(uint32_t)isr12,0x08,0x8E);
idt_set_gate(13,(uint32_t)isr13,0x08,0x8E);
idt_set_gate(14,(uint32_t)isr14,0x08,0x8E);
idt_set_gate(15,(uint32_t)isr15,0x08,0x8E);
idt_set_gate(16,(uint32_t)isr16,0x08,0x8E);
idt_set_gate(17,(uint32_t)isr17,0x08,0x8E);
idt_set_gate(18,(uint32_t)isr18,0x08,0x8E);
idt_set_gate(19,(uint32_t)isr19,0x08,0x8E);
idt_set_gate(20,(uint32_t)isr20,0x08,0x8E);
idt_set_gate(21,(uint32_t)isr21,0x08,0x8E);
idt_set_gate(22,(uint32_t)isr22,0x08,0x8E);
idt_set_gate(23,(uint32_t)isr23,0x08,0x8E);
idt_set_gate(24,(uint32_t)isr24,0x08,0x8E);
idt_set_gate(25,(uint32_t)isr25,0x08,0x8E);
idt_set_gate(26,(uint32_t)isr26,0x08,0x8E);
idt_set_gate(27,(uint32_t)isr27,0x08,0x8E);
idt_set_gate(28,(uint32_t)isr28,0x08,0x8E);
idt_set_gate(29,(uint32_t)isr29,0x08,0x8E);
idt_set_gate(30,(uint32_t)isr30,0x08,0x8E);
idt_set_gate(31,(uint32_t)isr31,0x08,0x8E);
idt_flush((uint32_t)&idt_ptr);
}
static void idt_set_gate(uint8_t num,uint32_t base,uint16_t selector,uint8_t flags) {
idt_entries[num].base_low = base & 0xFFFF;
idt_entries[num].base_high = (base >> 16) & 0xFFFF;
idt_entries[num].selector = selector;
idt_entries[num].always_zero = 0;
idt_entries[num].flags = flags | 0x60;
}
Code: Select all
.section .text
.align 4
.global idt_flush
.type idt_flush, @function
idt_flush:
mov 4(%esp),%eax
lidt (%eax)
ret
Code: Select all
.section .text
.align 4
.macro ISR_NOERR index
.global isr\index
isr\index:
cli
push $0
push $\index
jmp isr_common
.endm
.macro ISR_ERR index
.global isr\index
isr\index:
cli
push $\index
jmp isr_common
.endm
ISR_NOERR 0
ISR_NOERR 1
ISR_NOERR 2
ISR_NOERR 3
ISR_NOERR 4
ISR_NOERR 5
ISR_NOERR 6
ISR_NOERR 7
ISR_ERR 8
ISR_NOERR 9
ISR_ERR 10
ISR_ERR 11
ISR_ERR 12
ISR_ERR 13
ISR_ERR 14
ISR_NOERR 15
ISR_NOERR 16
ISR_NOERR 17
ISR_NOERR 18
ISR_NOERR 19
ISR_NOERR 20
ISR_NOERR 21
ISR_NOERR 22
ISR_NOERR 23
ISR_NOERR 24
ISR_NOERR 25
ISR_NOERR 26
ISR_NOERR 27
ISR_NOERR 28
ISR_NOERR 29
ISR_NOERR 30
ISR_NOERR 31
ISR_NOERR 127
.extern isr_handler
.type isr_handler, @function
isr_common:
pusha
/* Save segment registers */
push %ds
push %es
push %fs
push %gs
mov $0x10, %ax
mov %ax, %ds
mov %ax, %es
mov %ax, %fs
mov %ax, %gs
cld
push %esp
call isr_handler
add $4, %esp
pop %gs
pop %fs
pop %es
pop %ds
popa
add $8, %esp
iret
Code: Select all
idt_set_gate(1,(uint32_t)isr0,0x08,0x8E);
idt_set_gate(2,(uint32_t)isr2,0x08,0x8E);
idt_set_gate(3,(uint32_t)isr3,0x08,0x8E);
idt_set_gate(4,(uint32_t)isr4,0x08,0x8E);
...
idt_set_gate(31,(uint32_t)isr31,0x08,0x8E);
Code: Select all
idt_set_gate(0,(uint32_t)isr0,0x08,0x8E);
idt_set_gate(1,(uint32_t)isr1,0x08,0x8E);
idt_set_gate(2,(uint32_t)isr2,0x08,0x8E);
idt_set_gate(3,(uint32_t)isr3,0x08,0x8E);
...
idt_set_gate(31,(uint32_t)isr31,0x08,0x8E);
I thought there's only 256 interrupts?MichaelPetch wrote:The maximum number of interrupts supported in 32-bit protected mode is 8192. Each entry is 8 bytes so 65536/8=8192.
What does interrupt #65536 have to do with anything? And of course, if there's 65536 of something, since 0 is the first one, then the last is 65535, note the last digit. But beyond that, I don't really understand what you are talking about.Ananta96 wrote:I want to ask there is interrupt no 65536. If there is no interrupt 65536 what's wrong with mycode ???
What does "doesn't work" mean exactly? You should provide more specific details, explain what the problem is.Ananta96 wrote:I've got trouble especially pit.c (PIT doesn't work),paging.c and kheap.c what's wrong in my source code. If you can, you can also check all source code for idt and gdt. I hope you can help me. website github https://github.com/Ananta98/OSdev
Code: Select all
section .text
align 4
global gdt_flush
gdt_flush:
mov eax, [esp + 4]
lgdt [eax]
mov ax,0x10
mov ds,ax
mov es,ax
mov fs,ax
mov ss,ax
mov gs,ax
jmp 0x08:.flush
.flush:
ret
Code: Select all
#include <stdint.h>
struct gdt_entry {
uint16_t base_low;
uint16_t limit_low;
uint8_t base_middle;
uint8_t access;
uint8_t granularity;
uint8_t base_high;
} __attribute__((packed));
struct gdt_ptr {
uint16_t limit;
uint32_t base;
} __attribute__((packed));
void install_gdt();
extern void gdt_flush(uint32_t);
static void gdt_set_gate(int32_t,uint32_t,uint32_t,uint8_t,uint8_t);
struct gdt_entry gdt_entries[5];
struct gdt_ptr gdt_ptr;
Code: Select all
#include "gdt_user.h"
void install_gdt() {
gdt_ptr.limit = (sizeof(struct gdt_entry) * 5) - 1;
gdt_ptr.base = (uint32_t)&gdt_entries;
gdt_set_gate(0, 0, 0, 0, 0);
gdt_set_gate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF);
gdt_set_gate(2, 0, 0xFFFFFFFF, 0x92, 0xCF);
gdt_set_gate(3, 0, 0xFFFFFFFF, 0xFA, 0xCF);
gdt_set_gate(4, 0, 0xFFFFFFFF, 0xF2, 0xCF);
gdt_flush((uint32_t)&gdt_ptr);
}
static void gdt_set_gate(int32_t num,uint32_t base,
uint32_t limit,uint8_t access,uint8_t granularity) {
gdt_entries[num].base_low = (base & 0xFFFF);
gdt_entries[num].base_middle = (base >> 16) & 0xFF;
gdt_entries[num].base_high = (base >> 24) & 0xFF;
gdt_entries[num].limit_low = (limit & 0xFFFF);
gdt_entries[num].granularity = (limit >> 16) & 0x0F;
gdt_entries[num].granularity |= granularity & 0xF0;
gdt_entries[num].access = access;
}
Code: Select all
#include <stdint.h>
#include <stddef.h>
size_t kmalloc_int(size_t size,int align, size_t *phys);
size_t kmalloc_a(size_t size);
size_t kmalloc_p(size_t size,size_t *phys);
size_t kmalloc_ap(size_t size,size_t *phys);
size_t kmalloc(size_t size);
Code: Select all
#include "kheap.h"
extern uint32_t end;
uint32_t placement_address = (uint32_t)&end;
size_t kmalloc_int(size_t size,int align, size_t *phys) {
if (align == 1 && (placement_address & 0xFFFFF000)) {
placement_address &= 0xFFFFF000;
placement_address += 0x1000;
}
if (phys)
*phys = placement_address;
size_t tmp = placement_address;
placement_address += size;
return tmp;
}
size_t kmalloc_a(size_t size) {
return kmalloc_int(size,1,0);
}
size_t kmalloc_p(size_t size,size_t *phys) {
return kmalloc_int(size,0,phys);
}
size_t kmalloc_ap(size_t size,size_t *phys) {
return kmalloc_int(size,1,phys);
}
size_t kmalloc(size_t size) {
return kmalloc_int(size,0,0);
}
Code: Select all
#include <stdint.h>
#include "register.h"
struct page {
uint32_t present : 1;
uint32_t rw : 1;
uint32_t user : 1;
uint32_t accessed : 1;
uint32_t dirty : 1;
uint32_t unused : 7;
uint32_t frame : 20;
};
struct page_table {
struct page pages[1024];
};
struct page_directory {
struct page_table *tables[1024];
uint32_t tablesPhysical[1024];
uint32_t physicalAddr;
};
void initialise_paging();
void switch_page_directory(struct page_directory *new);
struct page *get_page(uint32_t address,int make,struct page_directory *dir);
void page_fault(struct regs *regs);
Code: Select all
#include "paging.h"
#include "stdio.h"
#include "kheap.h"
#include "irq_user.h"
uint32_t *frames;
uint32_t nframes;
struct page_directory *kernel_directory = 0;
struct page_directory *current_directory = 0;
extern uint32_t placement_address;
#define INDEX_FROM_BIT(a) (a/(8*4))
#define OFFSET_FROM_BIT(a) (a%(8*4))
static void set_frame(uint32_t frame_addr) {
uint32_t frame = frame_addr / 0x1000;
uint32_t idx = INDEX_FROM_BIT(frame);
uint32_t off = OFFSET_FROM_BIT(frame);
frames[idx] |= (0x1 << off);
}
static void clear_frame(uint32_t frame_addr) {
uint32_t frame = frame_addr / 0x1000;
uint32_t idx = INDEX_FROM_BIT(frame);
uint32_t off = OFFSET_FROM_BIT(frame);
frames[idx] &= ~(0x1 << off);
}
static uint32_t test_frame(uint32_t frame_addr) {
uint32_t frame = frame_addr / 0x1000;
uint32_t idx = INDEX_FROM_BIT(frame);
uint32_t off = OFFSET_FROM_BIT(frame);
return (frames[idx] & (0x1 << off));
}
static uint32_t fist_frame() {
int i , j;
for (i = 0; i < INDEX_FROM_BIT(nframes); i++) {
if (frames[i] != 0xFFFFFFFF) {
for (j = 0; j < 32; j++) {
uint32_t test = 0x1 << j;
if (!(frames[i] & test))
return i*4*8+j;
}
}
}
}
void alloc_frame(struct page *page,int is_kernel,int is_writeable) {
if (page->frame != 0)
return;
else {
uint32_t idx = fist_frame();
if (idx == (uint32_t)-1) {
kprintf("No free frames\n");
return;
}
set_frame(idx * 0x1000);
page->present = 1;
page->rw = (is_writeable) ? 1 : 0;
page->user = (is_kernel) ? 0 : 1;
page->frame = idx;
}
}
void free_frame(struct page *page) {
uint32_t frame;
if (!(frame=page->frame))
return;
else {
clear_frame(frame);
page->frame = 0x0;
}
}
void switch_page_directory(struct page_directory *dir) {
current_directory = dir;
asm volatile("mov %0, %%cr3":: "r"(&dir->tablesPhysical));
uint32_t cr0;
asm volatile("mov %%cr0, %0" : "=r"(cr0));
cr0 |= 0x80000000;
asm volatile("mov %0, %%cr0" :: "r"(cr0));
}
struct page *get_page(uint32_t address,int make,struct page_directory *dir) {
address /= 0x1000;
uint32_t table_idx = address / 1024;
if (dir->tables[table_idx])
return &dir->tables[table_idx]->pages[address % 1024];
else if (make) {
uint32_t tmp;
dir->tables[table_idx] = (struct page_table*)kmalloc_ap(sizeof(struct page_table),&tmp);
dir->tablesPhysical[table_idx] = tmp | 0x7;
return &dir->tables[table_idx]->pages[address%1024];
} else {
return 0;
}
}
void page_fault(struct regs *regs) {
uint32_t faulting_address;
asm volatile("mov %%cr2, %0" : "=r"(faulting_address));
int present = !(regs->err_code & 0x01);
int rw = regs->err_code & 0x02;
int us = regs->err_code & 0x04;
int reserved = regs->err_code & 0x08;
int id = regs->err_code & 0x10;
kprintf("Page fault\n");
if (rw) kprintf("Present\n");
if (us) kprintf("User mode\n");
if (reserved) kprintf("Reserved\n");
kprintf("Address : %x\n",faulting_address);
}
void initialise_paging() {
uint32_t mem_end_page = 0x1000000;
nframes = mem_end_page / 0x1000;
frames = (uint32_t*) kmalloc_a(INDEX_FROM_BIT(nframes));
memset(frames,0,INDEX_FROM_BIT(nframes));
kernel_directory = (struct page_directory*)kmalloc_a(sizeof(struct page_directory));
memset(kernel_directory,0,sizeof(struct page_directory));
current_directory = kernel_directory;
int i = 0;
while (i < placement_address) {
alloc_frame(get_page(i,1,kernel_directory),0,0);
i += 0x1000;
}
irq_install_handler(14,page_fault);
switch_page_directory(kernel_directory);
}