1
Lowlevel-Coding / Re: anfängerfrage: problem mit tutorial
« am: 21. January 2016, 20:40 »
Super, danke, das hilft mir für das Verständnis.
05. October 2024, 04:16
Diese Sektion erlaubt es dir alle Beiträge dieses Mitglieds zu sehen. Beachte, dass du nur solche Beiträge sehen kannst, zu denen du auch Zugriffsrechte hast.
#include "segmentation.h"
#include "io.h"
struct gdt_entry {
unsigned short limit_low;
unsigned short base_low;
unsigned char base_mid;
unsigned char access_flags;
unsigned char granularity;
unsigned char base_high;
} __attribute__((packed));
struct gdt_ptr {
unsigned short size;
unsigned int offset;
} __attribute__((packed));
#define GRANULARITY_4KB (1 << 7)
#define IS_32_BIT_CODE (1 << 6)
#define PRIVILEGE(lvl) ((lvl & 3) << 6)
#define PRESENT (1 << 7)
#define GDT_NUM_ENTRIES 3
struct gdt_entry gdt[GDT_NUM_ENTRIES];
void createGDTEntry(int n, unsigned int base, unsigned int limit, char type, char pl) {
gdt[n].base_low = base & 0xffff;
gdt[n].base_mid = (base >> 16) & 0xff;
gdt[n].base_high = (base >> 24) & 0xff;
gdt[n].limit_low = limit & 0xffff;
gdt[n].granularity = GRANULARITY_4KB | IS_32_BIT_CODE | ((limit >> 16) & 0xf);
gdt[n].access_flags = PRESENT | PRIVILEGE(pl) | (1 << 4) | (type & 0xf);
}
#define RX 0xa
#define RW 0x2
void initializeGDT() {
createGDTEntry(0, 0, 0, 0 , 0);
createGDTEntry(1, 0, ~0, RX, 0);
createGDTEntry(2, 0, ~0, RW, 0);
struct gdt_ptr ptr;
ptr.size = sizeof(struct gdt_entry) * GDT_NUM_ENTRIES - 1;
ptr.offset = (int) &gdt;
lgdt(ptr);
}
lgdt:
mov eax, [esp + 4]
lgdt [eax]
jmp SEGSEL_KERNEL_CS:.load_segments
.load_segments
mov ax, SEGSEL_KERNEL_DS
mov ds, ax
mov ss, ax
mov es, ax
mov gs, ax
mov fs, ax
ret
void initializeGDT() {
gdt[0] = createGDTEntry(0, 0, 0, 0);
gdt[1] = createGDTEntry(0, ~0, READABLE | EXECUTABLE, 0);
gdt[2] = createGDTEntry(0, ~0, READABLE, 0);
lgdt(&gdt);
}
lgdt:
mov eax, [esp + 4]
lgdt [eax]
jmp SEGSEL_KERNEL_CS:.load_segments
.load_segments
mov ax, SEGSEL_KERNEL_DS
mov ds, ax
mov ss, ax
mov es, ax
mov gs, ax
mov fs, ax
ret
01187800207e[CPU0 ] interrupt(): gate descriptor is not valid sys seg (vector=0x20)
01187800207e[CPU0 ] interrupt(): gate descriptor is not valid sys seg (vector=0x0d)
01187800207e[CPU0 ] interrupt(): gate descriptor is not valid sys seg (vector=0x08)
#define CREATE_IDT_GATE(i) createIDTEntry(i, &interrupt_handler_##i)
void initializeIDT() {
...
CREATE_IDT_GATE(32);
...
}
#include "segmentation.h"
#include "interrupts.h"
#include "pic.h"
void kmain() {
initializeGDT();
initializeIDT();
initializePIC();
}
#include "segmentation.h"
#include "io.h"
struct gdt_entry createGDTEntry(unsigned int, unsigned int, char, char);
struct gdt_entry {
unsigned short limit_low;
unsigned short base_low;
unsigned char base_mid;
unsigned char access_flags;
unsigned char granularity;
unsigned char base_high;
} __attribute__((packed));
struct gdt_entry gdt[3];
#define EXECUTABLE 0x8
#define READABLE 0x2
void initializeGDT() {
gdt[0] = createGDTEntry(0, 0, 0, 0);
gdt[1] = createGDTEntry(0, ~0, READABLE, 0);
gdt[2] = createGDTEntry(0, ~0, READABLE | EXECUTABLE, 0);
lgdt(gdt);
}
#define GRANULARITY_4KB 0x80
#define IS_32_BIT_CODE 0x40
#define PRIVILEGE(lvl) ((lvl & 2) << 5)
#define PRESENT 0x80
struct gdt_entry createGDTEntry(unsigned int base, unsigned int limit, char type, char pl) {
struct gdt_entry result;
result.base_low = base & 0xffff;
result.base_mid = (base >> 16) & 0xff;
result.base_high = (base >> 24) & 0xff;
result.limit_low = limit & 0xff;
result.granularity = GRANULARITY_4KB | IS_32_BIT_CODE | ((limit >> 16) & 0xf);
result.access_flags = PRESENT | PRIVILEGE(pl) | type;
return result;
}
#include "interrupts.h"
#include "io.h"
#include "framebuffer.h"
#include "interrupt_handler.h"
void handler();
void createIDTEntry();
struct idt_entry {
unsigned short offset_low;
unsigned short selector;
unsigned char unused; //but must be zeroed
unsigned char flags;
unsigned short offset_high;
} __attribute__((packed));
struct idt_ptr {
unsigned short limit;
unsigned int base;
} __attribute__((packed));
struct idt_entry idt[256];
void initializeIDT() {
int i;
for (i = 0; i < 256; i++) {
createIDTEntry(i, &interrupt_handler_1);
}
struct idt_ptr ptr;
ptr.limit = (sizeof (struct idt_entry) * 256) - 1;
ptr.base = (unsigned int) &idt;
lidt(&ptr);
}
void interrupt_handler () {
fb_write("interrupt happend!", 18);
fb_newLine();
}
#define TRAP_GATE_32BIT 0xf
#define PRIVILEGE(lvl) ((lvl & 2) << 5)
#define SEGSEL_KERNEL_CS 0x08
void createIDTEntry(int n, int address) {
idt[n].offset_low = address & 0xffff;
idt[n].offset_high = (address >> 16) & 0xffff;
idt[n].flags = TRAP_GATE_32BIT | PRIVILEGE(4);
idt[n].selector = SEGSEL_KERNEL_CS;
idt[n].unused = 0;
}
extern interrupt_handler
global enable_interrupts
global disable_interrupts
%macro no_error_handler 1
global interrupt_handler_%1
interrupt_handler_%1:
push dword 0
push dword %1
jmp common_interrupt_handler
%endmacro
%macro error_code_handler 1
global interrupt_handler_%1
interrupt_handler_%1:
push dword %1
jmp common_interrupt_handler
%endmacro
section .text:
common_interrupt_handler:
push esp
add dword [esp], 8
push eax
push ebx
push ecx
push edx
push ebp
push esi
push edi
call interrupt_handler
pop edi
pop esi
pop ebp
pop edx
pop ecx
pop ebx
pop eax
pop esp
iret
enable_interrupts:
sti
ret
disable_interrupts:
cli
ret
no_error_handler 0
no_error_handler 1
no_error_handler 2
no_error_handler 3
no_error_handler 4
no_error_handler 5
no_error_handler 6
no_error_handler 7
error_code_handler 8
no_error_handler 9
error_code_handler 10
error_code_handler 11
error_code_handler 12
error_code_handler 13
error_code_handler 14
no_error_handler 15
no_error_handler 16
error_code_handler 17
no_error_handler 18
no_error_handler 19
no_error_handler 32
no_error_handler 33
no_error_handler 34
no_error_handler 35
no_error_handler 36
no_error_handler 37
no_error_handler 38
no_error_handler 39
no_error_handler 40
no_error_handler 41
no_error_handler 42
no_error_handler 43
no_error_handler 44
no_error_handler 45
no_error_handler 46
no_error_handler 47
#include "pic.h"
#include "io.h"
void pic_mask(unsigned int, unsigned int);
#define PIC1_PORT_A 0x20
#define PIC1_PORT_B 0x21
#define PIC1_ICW1 0x11
#define PIC1_ICW2 0x20
#define PIC1_ICW3 0x4
#define PIC1_ICW4 0x5
#define PIC2_PORT_A 0xa0
#define PIC2_PORT_B 0xa1
#define PIC2_ICW1 0x11
#define PIC2_ICW2 0x28
#define PIC2_ICW3 0x2
#define PIC2_ICW4 0x1
#define PIC_EOI 0x20
void initializePIC() {
outb(PIC1_PORT_A, PIC1_ICW1);
outb(PIC2_PORT_A, PIC2_ICW1);
outb(PIC1_PORT_B, PIC1_ICW2);
outb(PIC2_PORT_B, PIC2_ICW2);
outb(PIC1_PORT_B, PIC1_ICW3);
outb(PIC2_PORT_B, PIC2_ICW3);
outb(PIC1_PORT_B, PIC1_ICW4);
outb(PIC2_PORT_B, PIC2_ICW4);
pic_mask(0xec, 0xff);
}
void pic_acknowledge() {
outb(PIC1_PORT_A, PIC_EOI);
outb(PIC2_PORT_A, PIC_EOI);
}
void pic_mask(unsigned int mask1, unsigned int mask2) {
outb(PIC1_PORT_B, mask1);
outb(PIC2_PORT_B, mask2);
}
#include "pic.h"
#include "io.h"
void pic_mask(unsigned int, unsigned int);
#define PIC1_PORT_A 0x20
#define PIC1_PORT_B 0x21
#define PIC1_ICW1 0x11
#define PIC1_ICW2 0x20
#define PIC1_ICW3 0x4
#define PIC1_ICW4 0x5
#define PIC2_PORT_A 0xa0
#define PIC2_PORT_B 0xa1
#define PIC2_ICW1 0x11
#define PIC2_ICW2 0x28
#define PIC2_ICW3 0x2
#define PIC2_ICW4 0x1
#define PIC_EOI 0x20
void initializePIC() {
outb(PIC1_PORT_A, PIC1_ICW1);
outb(PIC2_PORT_A, PIC2_ICW1);
outb(PIC1_PORT_B, PIC1_ICW2);
outb(PIC2_PORT_B, PIC2_ICW2);
outb(PIC1_PORT_B, PIC1_ICW3);
outb(PIC2_PORT_B, PIC2_ICW3);
outb(PIC1_PORT_B, PIC1_ICW4);
outb(PIC2_PORT_B, PIC2_ICW4);
pic_mask(0xec, 0xff);
}
void pic_acknowledge() {
outb(PIC1_PORT_A, PIC_EOI);
outb(PIC2_PORT_A, PIC_EOI);
}
void pic_mask(unsigned int mask1, unsigned int mask2) {
outb(PIC1_PORT_B, mask1);
outb(PIC2_PORT_B, mask2);
}
Der Multiboot-Header wurde an Offset 0x00100000 gefunden.
Der Bootloader wird den Multiboot-Header nicht finden, weil die Signatur sich außerhalb der ersten 8 KByte befindet.
Tip: Verwende ein Linker-Skript um den Header entsprechend zu platzieren. Das wird zum Beispiel in diesem Tutorial beschrieben.
#!/bin/bash
nasm -f elf -o kernel_asm.o kernel.asm
gcc -m32 -ffreestanding -o kernel_c.o -c kernel.c -Wall -Werror -nostdinc
ld -T kernel.ld -o kernel.bin kernel_asm.o kernel_c.o
rm kernel_c.o
rm kernel_asm.o
multiboot /boot/kernel.bin
die Fehlermeldung: error: no multiboot header found
multiboot /boot/kernel.bin
eingebe, dann reklamiert er: "error: no multiboot header found"
GNU GRUB version 1.99-12ubuntu5.1
Minimal BASH-like line editing is supported. For the first word, TAB lists possible command completions. Anywhere else TAB lists possible device or file completions
grub>