Beiträge anzeigen

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.


Nachrichten - OdinX

Seiten: [1] 2
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.
2
Lowlevel-Coding / Re: anfängerfrage: problem mit tutorial
« am: 21. January 2016, 16:40 »
Ich habe das gerade mal so geändert, was da so anstand und es scheint jetzt zu funktionieren. Na dann gehts für mich mal weiter zu den Interrupts :).

Ich danke euch viel mal für eure Hilfe!

Ich hätte da aber noch eine theoretische Frage.

Warum kann man Paging nicht ohne Segmentation nutzen? Bzw welchen Protection Mechanismus wird vom Paging nicht zur verfügung gestellt, den Segmentation bietet? Ich hatte als, ich die Theorie über Paging und Segmentation gelernt habe, immer das Gefühl, dass Paging quasi Segmentation ersetzt. Scheint aber nicht der Fall zu sein, denn man muss Segmentation trotzdem noch konfigurieren.
3
Lowlevel-Coding / Re: anfängerfrage: problem mit tutorial
« am: 21. January 2016, 16:02 »
Ach so. Das würde dann also heissen, dass ich möglicherweise nur darum keine Probleme bekommen habe mit dem .s, weil ich bisher keinen Präprozessor für Assembler benutzt hatte, und dementsprechend würde ich da später in den Hammer laufen.

Ich habe das so gemacht, weil es im Tutorial so gemacht wurde. Ist aber gut zu wissen, da ich mir damit viel Fehlersuche ersparen kann.
4
Lowlevel-Coding / Re: anfängerfrage: problem mit tutorial
« am: 21. January 2016, 14:14 »
Ich wollte die GDT in Assembler laden, weil das so im Tutorial erklärt wurde. Ich benutze das Tutorial https://littleosbook.github.io/.

Im von dir verlinkten Tutorial finde ich aber nur dass die Funktionen set_entry und load_gdt aufgerufen werden, aber die sind nirgendwo definiert, oder zu mindest habe ich die nicht gefunden.

Die Datentypen werde ich dann noch ändern, ist ja nur wein wenig stupide Fleissarbeit.

Von welchem Bitfeld redest du? Die gdt_entry struct? Und wenn ja, was bringen mir da unions? Ich weiss eigentlich schon wie unions funktionieren, ich seh nur den Anwendungszweck in dem Zusammenhang gerade nicht.

Das mit dem cast von  int zu unsigned int ist zwar unschön, sollte aber keinen Unterschied machen, da das Bitmuster bei diesem cast nicht verändert wird.

Sieht aus als sei das das Problem, dass ich nicht die Adresse übergebe, hoffentlich funktioniert es dann.

Ich benutze im Übrigen eine Ubuntu vm um das ganze zu programmieren, und ich habe noch keine Probleme mit dem kleinen .s. Warum würde das denn zu Problemen kommen? Gibt es da build tools die die entsprechende .S Endung voraussetzen?

Danke viel mal für eure schnelle Hilfe, ich seid wirklich sehr schnell und lehrreich.
5
Lowlevel-Coding / Re: anfängerfrage: problem mit tutorial
« am: 20. January 2016, 23:15 »
Hey, schon eine weile her seit ich an meinem kleinen OS gearbeitet habe, und hab das darum noch nicht zum laufen gebracht. Hab heute wieder angefangen und wollte mal das ganze ohne IDT, also nur mit GDT testen, schein aber immer noch nicht zu funktionieren. Ich poste mal den relevanten Code.

segmentation.c
#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);
}

io.s
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

Ich hoffe ich hab diesmal nichts relevanes vergessen.

 :-o ich bin ja beim letzten mal plötzlich auf englisch umgestiegen in meinem Kommentar, hatte ich bisher gar nicht gemerkt.

edit:

bzw noch die wichtigere Frage wäre eigentlich: wie debuggt man so etwas? Wie weiss ich, dass die GDT geladen ist? Momentan weiss ich, dass es nicht geht, weil es rebootet, aber wenn es nun nicht rebooten würde wüsste ich ja trotzdem nicht, ob es funktioniert hat.
6
Lowlevel-Coding / Re: anfängerfrage: problem mit tutorial
« am: 09. November 2015, 23:54 »
I am an idiot... Should have been super obvious that it must be a struct for the gdt, when I had to make a struct for the idt.

I'll try making that work this week.

Thank you very much for your help.
7
Lowlevel-Coding / Re: anfängerfrage: problem mit tutorial
« am: 07. November 2015, 19:27 »
Ich habe das mal so angepasst:

in segmentation.h
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);
}

und in io.s
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

Rebootet aber immer noch dauernd.
Wie kann ich das debuggen? Den bochs debugger hab ich bis jetzt auf jeden Fall noch nicht zum laufen bekommen

edit: ich hab jetzt den debugger hinbekommen, aber bin noch nicht dazu gekommen, weiter zu machen.
8
Lowlevel-Coding / Re: anfängerfrage: problem mit tutorial
« am: 06. November 2015, 19:52 »
Ich hab mal alles geändert, was so von den vorherigen Posts angestanden ist. Nun rebootet bochs dauernd, wie bereits gesagt. Ich kriege folgende Meldung im log von bochs:

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)

Müsste gate descriptor 0x20 nicht valid sein, wenn ich so was in meiner initializeIDT funktion habe:

#define CREATE_IDT_GATE(i) createIDTEntry(i, &interrupt_handler_##i)
void initializeIDT() {
    ...
    CREATE_IDT_GATE(32);
    ...
}
9
Lowlevel-Coding / Re: anfängerfrage: problem mit tutorial
« am: 06. November 2015, 19:05 »
Woah... das ging ja schnell mit den Antworten.

Das mit dem Interrupt interrupt_handler_1 der allen zugeteilt wird habe ich extra gemacht, weil ich erst testen wollte ob es funktioniert, und erst danach die Zuteilung fixen. Ich denke das war aber eine dumme Idee, da ja die einen Interrupt Handler Parameter auf dem Stack übergeben bekommen, und die anderen nicht.

Ich hab jetzt mal geschaut, ob ich die funktion enable_interrupts aufgerufen habe, und das war wohl mein grösstes problem... so trivial kann es sein. Nun rebootet bochs aber sofort, nachdem ganz kurz mein restlicher output angezeigt wird. Mal schauen ob ich diesmal rausfinde, was es sein könnte.

Danke für eure schnelle Hilfe.
10
Lowlevel-Coding / anfängerfrage: problem mit tutorial
« am: 06. November 2015, 16:27 »
Hallo zusammen

Ich bin gerade daran, das Tutorial https://littleosbook.github.io/ durchzuarbeiten. Das hat gut geklappt, ich konnte den Framebuffer und den Serial Port benutzen. Dann habe ich die GDT initialisiert, da weiss ich aber nicht, ob es funktioniert hat, keine Ahnung an was man das sehen soll. Auf jeden Fall wurden meine Framebuffer ausgaben nach dem LGDT immer noch ausgeführt. Dann habe ich die IDT und die PICs initialisiert und die Interrupthandler gebaut, und da passiert mal einfach rein gar nichts. Die interrupt_handler Funktion sollte etwas in den Framebuffer schreiben, um zu zeigen, dass sie aufgerufen wird, das passiert aber nicht. Bin jetzt wirklich langsam ratlos. Aber am besten zeige ich mal ein bisschen Code.

kmain.c
#include "segmentation.h"
#include "interrupts.h"
#include "pic.h"
void kmain() {
    initializeGDT();
    initializeIDT();
    initializePIC();
}

segmentation.c
#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;
}

interrupts.c
#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;
}

interrupt_handler.s
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

pic.c
#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);
}

io.s
#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);
}

header files und so habe ich mal weggelassen, ich denke das ist jetzt schon viel zu viel code für so eine frage.

Warum wird die interrupt_handler funktion in interrupts.c nicht aufgerufen, wenn ein interrupt passiert, also zB ich eine Taste drücke?

Danke schon mal für alle, die so weit gelesen haben.
11
Offtopic / Re: NSA und die Sicherheit von Betriebssystemen
« am: 21. January 2014, 22:09 »
Ich dachte eigentlich eher, dass man durch einen kleinen Mikrokernel mehr Sicherheit auf Betriebssystem-Ebene erreichen könnte, da die Komplexität so viel einfacher zu handhaben wäre. Vielleicht könnte man sogar für Teile des Kernels beweisen, dass sie korrekt sind und bestimmte Sicherheitslücken nicht enthalten. Das geht mit Windows und Linux ja ziemlich sicher nicht, da zu viel Code.
12
Offtopic / NSA und die Sicherheit von Betriebssystemen
« am: 19. January 2014, 21:40 »
Hallo

Verbreitete Betriebssysteme (Windows, MacOS, Linux) stammen ja grösstenteils aus den USA.
Nun, da Snowden das Wahre Gesicht der USA präsentiert hat, stelle ich mir die Frage, ob es nicht ein neues USA-freies offenes Betriebssystem braucht.

Was meint ihr dazu?
Könnte man dadurch mehr Sicherheit erreichen?
Wie liesse sich soetwas realisieren?

Kompatibilität zu POSIX könnte man dabei ja leicht erreichen, und damit hätte man schon viel Software zur Verfügung.
Ich war ehrlich gesagt, etwas erstaunt, dass es noch keinen NSA-Thread hier gibt, da das Thema gerade für Betriebssysteme sehr wichtig zu sein scheint.

Ich kann mir persönlich durchaus vorstellen, dass man mit einem neuen Betriebssystem erfolgreich sein könnte, wenn es nicht aus den USA kommt und wenn es zusätzlich einige einzigartige Features mitliefert. Ich habe mir da schon einiges überlegt, aber ich werde es nicht ausführen.
13
Lowlevel-Coding / Re: Kernel booten mit Grub2
« am: 20. June 2013, 23:41 »
Keine Ahnung, ich habe "oder" also logisches oder verstanden und direkt beides gemacht.

Aber ich probiers mal kurz aus und editier dann diesen Beitrag hier.

edit:  es war " -z max-page-size=0x1000"
14
Lowlevel-Coding / Re: Kernel booten mit Grub2
« am: 20. June 2013, 23:21 »
Super, hat funktioniert. Jetzt gibt er mein hello world endlich aus ^^

Danke für die tolle und schnelle hilfe
15
Lowlevel-Coding / Re: Kernel booten mit Grub2
« am: 20. June 2013, 23:06 »
Sorry, hab noch eine Frage.

Im tutorial http://www.lowlevel.eu/wiki/C-Kernel_mit_GRUB#Kernel wird ja explizit alles auf die Adresse 0x00100000 geladen (kapitel "linken").
Das scheint aber nun genau das problem zu sein, welches ich habe. Hat das tutorial da einen fehler, oder versteh ich was falsch?
16
Lowlevel-Coding / Re: Kernel booten mit Grub2
« am: 20. June 2013, 22:56 »
Super, das hilft mir schon sehr viel weiter, denke ich.

Das script sagt foldendes:
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.

Ich werde mir das Tutorial also erst mal durchlesen.

Danke für die Hilfe
17
Lowlevel-Coding / Re: Kernel booten mit Grub2
« am: 20. June 2013, 22:41 »
Ich habe folgendes Script geschrieben zum kompillieren und linken:

#!/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

Grub bringt aber nach dem Befehl multiboot /boot/kernel.bin die Fehlermeldung: error: no multiboot header found
Ich habe auch noch mal nachgeprüft, ob ich mich nicht verschrieben habe oder so etwas blödes, scheint aber nicht der fall zu sein.
18
Lowlevel-Coding / Re: Kernel booten mit Grub2
« am: 20. June 2013, 22:30 »
Hab gerade gesehen, dass es doch ein Fehlermeldung gibt, sie verschwindet nur so schnell wieder, dass man sie nicht lesen kann.

Ich krieg es nicht hin, mein file manuell zu booten, der "kernel" befehl ist aber anscheinend nicht für GRUB2, wies aussieht.

Bin also noch am suchen, wie ich das hinkriege

Also, wenn ich multiboot /boot/kernel.bin eingebe, dann reklamiert er: "error: no multiboot header found"
19
Lowlevel-Coding / Re: Kernel booten mit Grub2
« am: 20. June 2013, 21:39 »
Nein, gar nichts.
Es steht nur:

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>

Vielleicht könnte ich also manuell meinen Code aus GRUB raus booten, um zu sehen ob das funktioniert?
20
Lowlevel-Coding / Re: Kernel booten mit Grub2
« am: 20. June 2013, 12:16 »
Ups, sorry

Was also passiert, wenn ich das daraus resultierende ISO image in einer Virtualbox VM boote ist folgendes:
Es wird grub geladen, aber grub lädt mein .bin-file nicht
Seiten: [1] 2

Einloggen