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.


Themen - micha

Seiten: [1]
1
Lowlevel-Coding / FASM-Portierung
« am: 27. August 2013, 17:19 »
Moin.
ich bin grad dabei, fasm zu portieren. An sich läuft das ganze schon, aber ich hab da ein paar kleine probleme, die vielleicht durch den screenshot ganz deutlich werden.
Nach dem er den Versionsstring ausgegeben hat, assembliert er und gibt dann die etwas komische ausgabe. Zwischen jedem Buchstaben stehen noch andere Zeichen (unter anderem der dateiname). Wo die herkommen würde ich gern wissen. Wenn ich aber die eigentlichen Buchstaben entziffere, dann steht da folgendes:
3 passes, 157 bytes.Also das gleiche ergebnis wie unter Linux.

Zweites Problem: die neue-programm datei wird korrekt angelegt und beschrieben. (siehe den cat aufruf). Aber wenn ich versuche, hello auszuführen, hat es angeblich nicht die richtige magic.

 :?

Der code ist auf https://github.com/michamimosa/FruityOrange zu finden.
Ich hoffe, dass mir jemand da auf die sprünge helfen kann.
2
Lowlevel-Coding / unbeschreibbare phyische pages
« am: 02. August 2013, 21:51 »
Moin,
ich hab ein kleines problem, dass mein OS sehr schnell abstürtzt, weil es auf physiche adressen schreibt, die wahrscheinlich garnicht beschreibbar sind. Egal, was ich in solche pages schreibe, es steht immer 0xfffff… drin.
ich hab dazu mal einen test gemacht.
nach der initalisierung des kernels wird dieser code ausgeführt:
  while(1) {
    int *a = vmm_find(current_context, 1, VADDR_KERNEL_HEAP_START, VADDR_KERNEL_HEAP_END);
    vmm_map_page(current_context, a, pmm_alloc(), VMM_KERNEL_FLAGS);
    *a = 10;
    printf("a = 0x%x, %d\n", a, *a);
  }

Das ergebnis:
Er bleibt beim 254 mal pmm_alloc() hängen. Die erste adresse, bei der -1 statt 10 (die ich dort hingeschrieben habe) steht ist 0xA0000.
Ich bin mir eigentlich ziemlich sicher, dass ich den pmm richtig initalisiere. (aber wahrscheinlich doch nicht ;) )
Hier der code: https://github.com/michamimosa/FruityOrange/blob/master/kernel/mm/pmm.c

ich hoffe jemand kann mir helfen!
LG, micha
3
OS-Design / Dynamische PIT-Frequenz
« am: 25. October 2012, 11:29 »
Mir kam jetzt mal eine Idee, dass man die Frequenz, mit der der Timerinterrupt und dann der Scheduler ausgelöst wird dynamisch nach der Anzahl der aktiven Prozesse optimal einstellt. Wenn ich den PIT beim Initialisieren auf 50Hz stelle und nur ein oder zwei Prozesse laufen, wird ja ständig der Interrupt ausgelöst. Bei Zwei Prozessen muss die Frequenz aber gar nicht so hoch sein. Deshalb könnte man ja die Frequenz nach der Anzahl der aktiven Tasks richten.
Lohnt es sich die PIT-Frequenz immer zu ändern?
4
Softwareentwicklung / Linkeroptimierung
« am: 17. June 2012, 13:55 »
Hi,
ich hab meine lib als .a zusammengebündelt. Diese wird an den kernel und die Programme immer dran gelinkt. Aber auch funktionen die ich garnicht verwende.

Gibt es eine Möglichkeit, dass der linker nur die labels, die benötigt werden, dazulinkt?

Grüße
5
Lowlevel-Coding / Multitasking in Ring-3
« am: 12. April 2012, 19:55 »
Hi,

Nachdem ich jetzt das Multitasking in Ring 0 hinbekommen habe, wollte ich jetzt das genze nach ring 3 verschieben.
Nur leider kommen As bis zum nächsten Timerinterrupt und dann meldet qemu: fatal: trying to execute code outside RAM or ROM.(oder so ähnlich)

könnte da mal jemand drübergucken?

multitasking.c
#include <stdint.h>
#include "gdt.h"
#include "interrupt.h"
#include "cpu.h"
#include "console.h"

/* ---------- Globale Variablen ----------------------- */
static uint8_t stack_a[4096];
static uint8_t stack_b[4096];
static uint8_t user_stack_a[4096];
static uint8_t user_stack_b[4096];

static int current_task = -1;
static int num_tasks = 2;
static cpu_state* task_states[2];
/* --------- Tasks ------------- */
void task_a(void){
  while(1){
    setColor(0x02);
    printf("A");
  }
}
void task_b(void){
  while(1){
    setColor(0x06);
    printf("B");
  }
}
/* ---------- Task initalisieren ---------------------- */
cpu_state* init_task(uint8_t *stack, uint8_t *user_stack, void *entry){
    cpu_state new_state = {
.eax = 0,
.ebx = 0,
.ecx = 0,
.edx = 0,
.esi = 0,
.edi = 0,
.ebp = 0,

        .esp = (uint32_t) user_stack + 4096,
.eip = (uint32_t) entry,

// Ring-3 Segmentregister
.cs = 0x1b /*0x18 | 0x03*/,
.ss = 0x23 /*0x20 | 0x03*/,

// IRQs einschalten
.eflags = 0x202,
    };
   
    cpu_state *state = (void*) (stack + 4096 - sizeof(new_state));
    *state = new_state;
   
    return state;
}
/* ---------- Multitasking initalisieren -------------- */
void init_multitasking(void){
    task_states[0] = init_task(stack_a, user_stack_a, task_a);
    task_states[1] = init_task(stack_b, user_stack_b, task_b);
    cpu_dump(task_states[0]);
    cpu_dump(task_states[1]);
}
/* ---------- Scheduler ------------------------------- */
cpu_state* schedule(cpu_state *cpu){
   
    // Alten zustand des Tasks sichern
    if(current_task >= 0){
task_states[current_task] = cpu;
    }
   
    // Nächsten Task auswählen
    current_task++;
    current_task %= num_tasks;
   
    // Neuen Task aktivieren
    cpu = task_states[current_task];
   
    return cpu;
}

timer_irq_handler.c
#include <stdint.h>

#include "cpu.h"
#include "gdt.h"
#include "multitasking.h"

static uint32_t tss[TSS_SIZE];

cpu_state* timer_irq_handler(cpu_state *cpu){
    cpu_state *new_cpu = schedule(cpu);
    tss[1] = (uint32_t) (new_cpu + 1);
   
    send_eoi(0);
    return new_cpu;
}

irq handler:
// Gemeinsamer interrupt handler
.extern common_intrpt_handler
.extern common_intrpt_handler_with_new_cpu
// IRQ - Handler
.extern timer_irq_handler
.extern keyboard_irq_handler

.macro irq_empty nr
.global int_handler\nr
int_handler\nr:
  iret
.endm

.macro irq nr isr
.global int_handler\nr
int_handler\nr:
  push $0
  push $\nr
  push $\isr
  jmp common_intrpt_handler
.endm

.macro irq_with_new_cpu nr isr
.global int_handler\nr
int_handler\nr:
  push $0
  push $\nr
  push $\isr
  jmp common_intrpt_handler_with_new_cpu
.endm

irq_with_new_cpu 0x20 timer_irq_handler
irq 0x21 keyboard_irq_handler
irq_empty 0x22
irq_empty 0x23
irq_empty 0x24
irq_empty 0x25
irq_empty 0x26
irq_empty 0x27
irq_empty 0x28
irq_empty 0x29
irq_empty 0x2A
irq_empty 0x2B
irq_empty 0x2C
irq_empty 0x2D
irq_empty 0x2E
irq_empty 0x2F

//Ende - handler.S

common handler:
.global common_intrpt_handler_with_new_cpu
common_intrpt_handler_with_new_cpu:
  // ISR nach eax legen
  pop %ebx
 
  push %ebp
  push %edi
  push %esi
  push %edx
  push %ecx
  push %ebx
  push %eax
 
  // Kernel-Datensegmente laden
  mov $0x10, %ax
  mov %ax, %ds
  mov %eax, %es
 
  // ISR aufrufen
  push %esp
  call *%ebx
  mov %eax, %esp //Neuen Stack laden
 
  // User-Datensegmente laden
  mov $0x23, %ax
  mov %ax, %ds
  mov %ax, %es
 
  // Neue cpu herstellen
  pop %eax
  pop %ebx
  pop %ecx
  pop %edx
  pop %esi
  pop %edi
  pop %ebp
 
  // Errorcode und Interruptnummer vom Stack nehmen
  add $8, %esp
  iret

gdt.c
#include <stdint.h>
#include "gdt.h"

/* ---------- Globale Variablen ----------------------- */
static uint64_t gdt[GDT_ENTRIES]; //Global Deskriptor Table
static uint32_t tss[TSS_SIZE] = {0, 0, 0x10}; //Task State Segment
/* ---------- Eintrag in die GDT setzen --------------- */
void set_gdt_entry(int i, uint32_t limit, uint32_t base, uint8_t access, uint8_t flags){
  gdt[i] = 0;
  //untere 32-Bit
  gdt[i] = (limit & 0x0ffff) | ((base & 0x0000ffff) << 16);
  //obere 32-Bit
  gdt[i] |=(
    ( (base & 0x00ff0000) >> 16 ) |
    ( access << 8 ) |
    ( flags << 16 ) |
    ( (limit & 0xf0000) << 4) |
    ( (base & 0xff000000) << 56 )
   ) * 0x100000000;
}
/* ---------- GDT Laden (GDTR ändern) ----------------- */
void load_gdt(void){
  struct {
    uint16_t size;
    uint64_t *pointer;
  } __attribute__((packed)) gdtp = {
    .size = GDT_ENTRIES * 8 - 1,
    .pointer = gdt,
  };
  asm volatile("lgdt %0" : : "m" (gdtp));//GDT Laden
}
/* ---------- GDT initalisieren ----------------------- */
void init_gdt(void){
 
  //Nulldeskriptor
    set_gdt_entry(0, 0, 0, 0, 0);

  //Kernel - Codesegment
    set_gdt_entry(1, 0xfffff, 0, //index, limit, base
GDT_CODESEG_RD | GDT_SEGMENT | GDT_RING0 | GDT_PRESENT,//Access-Byte
GDT_32_BIT  | GDT_4K_GRAN); //Flags
     
  //Kernel - Datensegment      
    set_gdt_entry(2, 0xfffff, 0,     //index, limit, base
GDT_DATASEG_WR | GDT_SEGMENT | GDT_RING0 | GDT_PRESENT,//Access-Byte
GDT_32_BIT  | GDT_4K_GRAN);       //Flags
     
  //Userspace - Codesegment    
    set_gdt_entry(3, 0xfffff, 0, //index, limit, base
GDT_CODESEG_RD | GDT_SEGMENT | GDT_RING3 | GDT_PRESENT,//Access-Byte
GDT_32_BIT  | GDT_4K_GRAN); //Flags
     
  //Userpsace - Datensegment      
    set_gdt_entry(4, 0xfffff, 0, //index, limit, base
GDT_DATASEG_WR | GDT_SEGMENT | GDT_RING3 | GDT_PRESENT,//Access-Byte
         GDT_32_BIT  | GDT_4K_GRAN); //Flags
   
  //Task State Segment
    set_gdt_entry(5, sizeof(tss)-1, (uint32_t) &tss, //index, limit, base
GDT_TSS | GDT_PRESENT | GDT_RING3, //Access-Byte
GDT_32_BIT  | GDT_4K_GRAN); //Flags

   // nach ss0 das Kernel Datensegment legen
    tss[2] = 0x10;
}
/* ---------- GDT schnell initalisieren --------------- */
void init_gdt_fast(void){
  gdt[0] = 0x0000000000000000;//Nulldeskriptor
  gdt[1] = 0x00FC9A000000FFFF;//Kernel - Codesegment
  gdt[2] = 0x00FC92000000FFFF;//Kernel - Datensegment
  gdt[3] = 0x00FCFA000000FFFF;//Userspace - Codesegment
  gdt[4] = 0x00FCF2000000FFFF;//Userpsace - Datensegment
//   gdt[5] = 0x0000000000000000;//Task State Segment
}
/* ---------- Segmenregister neuladen ----------------- */
void reload_segment_registers(void){
  asm volatile(
"ljmpl $0x08, $1f\n\t"
"1:\n\t"
        "mov $0x10, %eax\n\t"
        "mov %eax, %ds\n\t"
        "mov %eax, %es\n\t"
        "mov %eax, %fs\n\t"
        "mov %eax, %gs\n\t"
        "mov %eax, %ss\n\t"
  );
}
/* ---------- Taskregister neuladen ------------------- */
void reload_task_registers(void){
  asm volatile("ltr %%ax" : : "a" (5 << 3));
}
6
Lowlevel-Coding / Timernterrupt kommt bei Multitasking nicht
« am: 11. April 2012, 17:01 »
Ich hab gehofft, das bekomme ich wenigstens selber hin....

Ja, sobald mein Kernel im ersten Task (task_a) ist, wird kein IRQ, also kein Timerinterrupt mehr ausgelöst.
#include <stdint.h>
#include "interrupt.h"
#include "cpu.h"
#include "console.h"


/* ---------- Globale Variablen ----------------------- */
static uint8_t stack_a[4096];
static uint8_t stack_b[4096];

static int current_task = -1;
static int num_tasks = 2;
static cpu_state* task_states[2];
/* --------- Tasks ------------- */
void task_a(void){
  while(1){
    setColor(0x02);
    printf("A");
  }
}
void task_b(void){
  while(1){
    setColor(0x06);
    printf("B");
  }
}
/* ---------- Task initalisieren ---------------------- */
cpu_state* init_task(uint8_t *stack, void *entry){
    cpu_state new_state = {
.eax = 0,
.ebx = 0,
.ecx = 0,
.edx = 0,
.esi = 0,
.edi = 0,
.ebp = 0,
        //.esp = Unbenutzt
.eip = (uint32_t) entry,

// Ring-0 Segmentregister
.cs = 0x08,
//.ss = unbenutzt

//IRQs einschalten
.eflags = 0x202,
    };
   
    cpu_state *state = (void*) (stack + 4096 - 56/*sizeof(new_state)*/);
    *state = new_state;
   
    return state;
}
/* ---------- Multitasking initalisieren -------------- */
void init_multitasking(void){
    task_states[0] = init_task(stack_a, task_a);
    task_states[1] = init_task(stack_b, task_b);
}
/* ---------- Scheduler ------------------------------- */
cpu_state* schedule(cpu_state *cpu){
   
    // Alten zustand des Tasks sichern
    if(current_task >= 0){
task_states[current_task] = cpu;
    }
   
    // Nächsten Task auswählen
    current_task++;
    current_task %= num_tasks;
   
    // Neuen Task aktivieren
    cpu = task_states[current_task];
   
    return cpu;
}

/* --------- ENDE -- multitasking.c ---*/

Also hab ich ersmal folgendes gemacht:
/* --------- Tasks ------------- */
void task_a(void){
  while(1){
    setColor(0x02);
    printf("A");
    asm("int $0x20");
  }
}
void task_b(void){
  while(1){
    setColor(0x06);
    printf("B");
    asm("int $0x20");
  }
}
Da funktionierts! aber das ist ja keine Lösung.

init_multitasking rufe ich auch vor cli auf.
7
Das Wiki / outb in Tutorials
« am: 11. April 2012, 10:11 »
Hallo

Ich habe da eine Frage zu der outb-funktion, wie sie im tutorial definiert ist.
Dort sieht sie so aus:
static inline void outb(uint16_t port, uint8_t data)
{
    asm volatile ("outb %0, %1" : : "a" (data), "Nd" (port));
}
Wieso ist das denn nicht als Macro definert?

So funktioniert es doch auch:
#define outb(port, data) asm("outb %0, %1" : : "a" ((uint8_t)data), "Nd" ((uint16_t)port))
Vielleicht könnten mir das auch die Schreiber dieses Tutorials beantworten.
8
Lyrisches Eck / Wortspiel
« am: 04. April 2012, 15:33 »
Was sagt ihr dazu?

der Quellcode quillt wie Milchreis,
die Funktionen funktionieren nicht mehr,
das Makefile hat eine Macke.

wer macht weiter (mir fällt nix nehr ein :wink:)
9
Softwareentwicklung / Qemu und Oracle...
« am: 01. April 2012, 19:46 »
Halöle (Hallo)! :wink:
Ich hatte erst die VirtualBox von Oracle als Emulator installiert. Dann wollte ich qemu ausprobieren, doch seitdem geht die VBox nichtmehr. :-(
Vertragen die sich nicht?

Mein Virtuelles Windows XP lief in VBox so schnell ... und in qemu so langsam...


Grüße
10
OS-Design / Monotholitisher Kernel oder Microkernel
« am: 26. March 2012, 17:24 »
Hallo!

Ich bin am überlegen, ob ich mich für einen Monotholitischen Kernel oder für ein Microkernel entscheide.
Dabei kann ich mich eben nicht entscheiden!
Kann mir jemand vorteile bzw. nachteile von den verschiedenen Kernelarten nennen, damit ich mich besser entscheiden kann.

Grüße
Micha
11
Das Wiki / Seite erstellen
« am: 23. March 2012, 15:09 »
Na da bin ich wieder.
Ich hatte vor für mein OS eine Seite im Wiki zu erstellen.
Ich hab mich dort auch angemeldet. Nur weiß ich nicht wie ich jetzt die Seite erstellen kann.
könnte jemand mir das bitte veraten?

Danke
12
Lowlevel-Coding / Tastaturtreiber
« am: 18. March 2012, 18:26 »
Hi
Ich bin grad dabei mir ein Tastaturtreiber zu programmieren.
Da hab ich nur ein Problem:
Wenn ich ein Befehl an die Tastatur sende wird eine #General Protection ausgelöst.

Hier der Code
kbc.h:
/**
 *  kernel/driver/kbc/kbc.h
 *  portdefinitionen & send_kbc_command
 *
 *  (C) Copyright 2012 Michael Sippel
 */
#ifndef _KBC_H
#define _KBC_H

#include <stdint.h>
#include <portio.h>

#define KBC_PORT_KBDCOMMAND   0x60 /* Befehl an Tastatur                */
#define KBC_PORT_KBCDATA      0x60 /* Daten-Puffer auslesen & schreiben */
#define KBC_PORT_KBCCOMMAND   0x64 /* Befehl an KBC                     */
#define KBC_PORT_KBCREGISTER  0x64 /* Statusregiser auslesen            */

#define KBC_COMM_P1_PORT   0xC0
#define KBC_COMM_READ_OPP  0xD0
#define KBC_COMM_WRITE_OPP 0xD1
#define KBC_COMM_READ_CCB  0x20
#define KBC_COMM_WRITE_CCB 0x60

#define KBC_COMMAND_OK 0xFA
/* ---------- Befehl an KBC senden -------------------- */
static uint8_t send_kbc_command(uint8_t port,uint8_t command){
  static int fz = 3; /// @p fz Fehlerzähler
  uint8_t ret;/// @p ret Rückgabe vom KBC
 
  //Warten bis Eigabepuffer leer ist
  while( inb(KBC_PORT_KBCREGISTER) & 0x2 );
  //KBC-Befehl senden
  outb(port, command);
  //Warten bis Antwort im Ausgabepuffer liegt
  while( inb(KBC_PORT_KBCREGISTER) & 0x1 );
  //Antwort einlesen
  ret = inb(KBC_PORT_KBCDATA);
  //Erfolgreich?
  if(ret = KBC_COMMAND_OK || fz > 2){
    fz = 3;//Fehlerzähler rücksetzen
    return ret;//ENDE
  }else{
    --fz;//Fehlerzähler dekremantieren
    send_kbc_command(port, command);//Nochmal versuchen
  }
}
/* ---------- Befehl an Tastatur senden --------------- */
static uint8_t send_kbd_command(uint8_t command){
  return send_kbc_command(KBC_PORT_KBDCOMMAND,command);
}
/* -- ENDE --- kbc.h -- */
#endif

keyboard.c:
/**
 *  kernel/driver/kbc/keyboard/init.c
 *  init_keyboard, keyboard_irq_handler
 *
 *  (C) Copyright 2012 Michael Sippel
 */
#include <stdint.h>
#include <portio.h>
#include <stdbool.h>
#include <console.h>

#include "kbc.h"

#define KBD_COMM_LEDS 0xED /* LEDS ansteuern        */
#define KBD_COMM_ECHO 0xEE /* Echo                  */
#define KBD_COMM_WDHR 0xF3 /* Wiederholrate setzen  */
#define KBD_COMM_ACTV 0xF4 /* Tastatur aktivieren   */
#define KBD_COMM_DAKV 0xF5 /* Tastatur deaktivieren */
#define KBD_COMM_STDW 0xF6 /* Standarderte setzen   */
#define KBD_COMM_KRST 0xFF /* Tastatur-Reset        */

#define KBD 0
/* ---------- Tastatur initalisieren ------------------ */
void init_keyboard(void){
  color = 0x0F;debug(KBD,"       \n");
  //Warten bis Tastatur nicht mehr im Resetmodus ist
  while(! inb(KBC_PORT_KBCREGISTER) & 0x4 );
 
  //Ausgabepuffer leeren
  while (inb(KBC_PORT_KBCREGISTER) & 0x1){
    //Solange Ausgabepuffer voll ist Datenregister lesen
    inb(KBC_PORT_KBCDATA);
  }
 
  //LEDs ausschalten
  send_kbd_command(KBD_COMM_LEDS);
  outb(KBC_PORT_KBCDATA, 0);

  //Schnellste Wiederholrate einstellen
  send_kbd_command(KBD_COMM_WDHR);
  outb(KBC_PORT_KBCDATA, 0);

  //Tastatur aktivieren
  send_kbd_command(KBD_COMM_ACTV);
}
/* ---------- IRQ handler für Tastatur ---------------- */
void keyboard_irq_handler(void){
  printf("Taste gedrückt!\n\n");
}
/* ------- ENDE -- keyboard.c --- */

Grüße
13
Lowlevel-Coding / GDT
« am: 01. March 2012, 18:33 »
Hi,
Ich bastle schon lange (sehr lange) an meiner GDT rum.
nur leider läuft der kernel nach dem neuladen der Segmentregister nicht mehr.
Ich hab mir schon die komplette GDT ausgeben lassen: kein fehler gefunden.
Nach dem `lgdt' geht's noch.
Nach dem neuladen der Segmentregister geht es nicht mehr.
So lade ich sie neu:
asm(
   "ljmpl $0x08, $1f\n\t"
        "1:\n\t"
        "mov $0x10, %eax\n\t"
        "mov %eax, %ds\n\t"
        "mov %eax, %es\n\t"
        "mov %eax, %fs\n\t"
        "mov %eax, %gs\n\t"
        "mov %eax, %ss\n\t"
      );
kann mir jemand helfen?
14
Ich habe mir OSDev für einsteiger durchgelesen.
Doch leider funktioniert die Textausgabe bei mir nicht.
Ich hab mein ISO-file mit VirtualBox gestartet und dann kommen nur irgendwelche komische Zeichen, die gerade im Videospeicher drinstehen. :evil:

Also wird warscheinlich die Adresse 0xb8000 nicht richtig angesteuert.
Ich bilde mir ein, dass ich mit den Pointern alles richig gemacht habe.

Was mach ich falsch??? :?

LG: Micha
Seiten: [1]

Einloggen