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 - OS_3000

Seiten: [1]
1
Softwareentwicklung / In Eclipse OS in Qemu mit GDB debuggen
« am: 03. September 2013, 14:36 »
Ich versuche momentan wiedereinmal mein OS zu debuggen.
Vor einiger Zeit habe ich bereits einmal einen Anlauf gestartet:
Softwareentwicklung -> Thema: Kerneldebugging unter Windows mit QEmu & GDB
Inzwischen bin ich auf Eclipse umgestiegen.

Jetzt habe ich im Moment wieder zwei Probleme mit dem Debugging:
1. Wenn ich die Debuginformationen einschalte(egal ob g1, g2 oder g3), kann GRUB den Kernel nicht mehr starten.
Meldung von Grub:
  Booting 'start'
kernel /kernel.bin
Error 13: Invalid or unsupported executable format
Press any key to continue...
Ohne Debuginformationen hat GRUB keine Probleme den Kernel zu starten.

Als Postbuild führe ich noch folgende Befehle aus:
copy "%CD%\kernel.bin" "%CD%\..\cd\kernel.bin"
cd ..
mkisofs -R -J -b boot/grub/stage2_eltorito -no-emul-boot -boot-load-size 4 -boot-info-table -o "cdrom.iso" "cd/"
i586-elf-objcopy --only-keep-debug "cd\kernel.bin" "kernel.sym"
copy "cd\kernel.bin" "kernel.sym"
i586-elf-objcopy --strip-debug "cd\kernel.bin"
Das Problem tritt auch auf, wenn ich die letzten drei Befehle zum extrahieren der Debuginformation auskommentiere.

2. Eclipse weigert sich im Moment beharrlich Qemu zu starten ("${project_loc}\RunDebugQemu.bat") und kommt immer mit einen nichtssagenden Fehlerfenster:
Excetion occurred during lauch
Reason:
Program is not a recognized executable.
Details:
Program is not a recognized executable.
  Program is not a recognized executable.
  Program is not a recognized executable.
Die oben erwähnte Batchdatei startet Qemu im Debugmodus und scheint zu funktionieren.

Im Moment habe ich meine Debug-Konfiguration im Abschnitt "C/C++ Application" erstellt. Vorher habe ich schonmal einen Versuch mit "C/C++ Remote Application" gestartet.

Da es schwierig ist alle möglicherweise wichtigen Einstellungen hier anzugeben, habe ich einen(/mehrere) Screens von den Einstellungen angehängt.
Meine "gdb.gdbinit" sieht so aus:
symbol kernel.sym
target remote 127.0.0.1:1234

Hoffentlich wisst ihr eine Lösung.
Ich bin inzwischen schon sehr genervt von meinen Debuggingproblemen...
2
Softwareentwicklung / ld: "cannot find object file"?
« am: 31. May 2013, 23:44 »
Weil mir mit zunehmender "Größe" meines Betriebssystems der einfache Texteditor mir immer mehr zu umständlich wird, wollte ich heute mal Eclipse ausprobieren. Ich hab es geschafft die Umgebung passend einzurichten und die Sources richtig kompilieren zu lassen. Aber beim Linken kommt immer ein sehr seltsamer von mir nicht nachvollziehbarer Fehler "cannot find obj\init_S.o".
Bisher habe ich immer so gelinkt: (mit einer BAT)
i586-elf-ld -L "%GCC_PATH%\lib" -L "%GCC_PATH%\lib\gcc\i586-elf\%GCC_VERSION%" -T linkconf.ld -o obj\kernel.bin obj\*.o "%LIBGCC_FILE_NAME%" -Ttext=0x100000
In Eclipse sieht die Kommandozeile dann so aus:
Building target: kernel.bin
Invoking: Cross GCC Linker
i586-elf-ld -nodefaultlibs -nostdlib -static -L"C:\Programmordner\MinGW\OSprogramming\lib" -L"C:\Programmordner\MinGW\OSprogramming\lib\gcc\i586-elf\4.4.0" -Ttext=0x100000 -T "C:/Eigenes/Programmierung/Betriebssystem/System001\linkconf.ld" -o "kernel.bin"  ./stdlib/sysapi/api.o ./stdlib/sysapi/asm.o ./stdlib/sysapi/charconv.o ./stdlib/sysapi/console.o ./stdlib/sysapi/cpuid.o ./stdlib/sysapi/textio.o  ./stdlib/assert.o ./stdlib/errno.o ./stdlib/math.o ./stdlib/stdlib.o ./stdlib/string.o ./stdlib/time.o ./stdlib/uchar.o ./stdlib/wchar.o  ./kernel/api_intr.o ./kernel/com.o ./kernel/cpustate.o ./kernel/gdt.o ./kernel/intr.o ./kernel/lowlevelbeep.o ./kernel/lowlevelconsole.o ./kernel/lowleveltime.o ./kernel/mm.o ./kernel/mmp.o ./kernel/mmv.o ./kernel/pic.o ./kernel/process.o ./kernel/thread.o ./kernel/tss.o  ./init.o   -llibgcc.a
c:\Programmordner\MinGW\OSprogramming\bin\i586-elf-ld.exe: cannot find obj\init_S.o
make: *** [kernel.bin] Error 1


Weshalb sucht der Linker immer nach "init_S.o"?
Es gab vorher mal versehentlich eine so benannte Datei im Projekt, aber die ist schon lange gelöscht und sie taucht ja auch nicht in den Kommandozeilenparametern von Ld auf. Daher erschließt sich mir nicht ganz weshalb der Linker immer meint, er würde immer diese Datei brauchen.

Habt ihr eine Idee woher das kommen kann? Ich habe das Gefühl das ich ziemlich auf den Schlauch stehe.
3
Da ich vor ein paar Tagen mich wieder der Betriebssystementwicklung zugwandt habe und momentan gerade dabei bin die virtuelle Speicherverwaltung zu implementieren in der einige nicht ganz triviale Algorithmen vorkommen, würde ich jetzt auch gerne Debugger nutzen. Ich habe bereits den Wikieintrag und diesen Forenbeitrag gelesen.

Leider funktioniert das ganze aber noch nicht so recht.  :-(
Qemu verharrt im schwarzen Fenster während GDB folgendes ausgibt...
?:\*\*>gdb
GNU gdb (GDB) 7.4
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-pc-mingw32".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
(gdb) target remote 127.0.0.1:1234
Remote debugging using 127.0.0.1:1234
Ignoring packet error, continuing...
warning: unrecognized item "timeout" in "qSupported" response
Ignoring packet error, continuing...
Ignoring packet error, continuing...
Ignoring packet error, continuing...
Ignoring packet error, continuing...
Ignoring packet error, continuing...
warning: Invalid remote reply: timeout

QEmu rufe ich folgendermaßen auf...
SET IMAGENAME=cdrom.iso
SET DEBUGPARAMS=-gdb tcp:127.0.0.1:1234 -S
FOR /f "tokens=*" %%i IN ('cd') DO SET AKTPFAD=%%i
call ..\QemuFolder.bat
qemu-system-i386.exe %DEBUGPARAMS% -m 4 -cdrom "%AKTPFAD%\%IMAGENAME%" -cpu pentium3 -L "%cd%\pc-bios" -localtime -soundhw all -D "%AKTPFAD%\qemu.log" -d int

Der Kernel würde momentan noch ohne Debuginfos erstellt, aber das sollte nicht der Grund sein, weshalb die Konnektion zu GDB fehlschlägt.

Was ich mich aber auch noch frage ist, ob man mit MinGW Binärcode debuggen kann, der mit "i586-elf-gcc" aus dem Wiki erstellt wurde?

EDIT:
Ich sehe gerade, das das Thema wohl eher in die Kategorie "Softwareentwicklung" gepasst hätte.
Vlt kann das bitte nochmal ein freundlicher Moderator verschieben.  :wink:
4
Lowlevel-Coding / Exception bei Mutitasking
« am: 03. December 2012, 18:39 »
Also ich wollte mal nach langer Zeit mal wieder an meinem OS weiterarbeiten.
Das Problem ist, der Kernel löst nach dem 400 Timerinterupt beim Taskwechsel vom 1. Prozess zurück in den 0. eine Generall Protection Exception (13) aus.

Da das Multitasking aus mehreren größeren Dateien besteht, hab ich es angehängt.
Wäre um einen Tipp, wie ich dem Fehler zu Leibe rücken kann, sehr dankbar.  :-)
Was mich so irritiert ist, dass der Taskwechsel vorher einigemale klappt.

Die Textdatei im Anhang ist eine falsche 7-Zip-Datei, damit ich sie hochladen kann.
Warum sind hier keine Zipdateien erlaubt? Finde ich ziemlich umständlich.  :wink:
5
Lowlevel-Coding / Usermode Multitasking
« am: 26. April 2012, 21:18 »
Ich habe vor ein paar Tagen ein bisschen weiter mit meinen Kernel gemacht und schon habe ich das nächste Problem.
Es geht um Multitasking im Usermode.
Interrupts und Multitasking mit Thread\Prozess-Strukturen haben bereits funktioniert, doch im Ring 3 hängt sich QEmu kommentarlos auf und Bochs rebootet.

Erstmal habe ich schon ein paar Verständnisprobleme:
  • Wozu brauche ich diesen UserStack? Es existiert ja bereits ein Threadeigener Stack, also wozu nocheiner?
  • Weshalb wird dieses TSS gebraucht? Die UserStack-Adresse übergebe ich ja bereits im CPU-State

Nun zum konkreten Problem und Code:
Ich vermute, dass die Emulatoren beim GDT abstürzen.
Daher dieser Code: ("gdt.c")
#include "gdt.h"
#include <stdint.h>
#include "console.h"
#include "tss.h"

#define GDT_FLAG_DATASEG 0x02
#define GDT_FLAG_CODESEG 0x0a
#define GDT_FLAG_TSS     0x09

#define GDT_FLAG_SEGMENT 0x10
#define GDT_FLAG_RING0   0x00
#define GDT_FLAG_RING3   0x60
#define GDT_FLAG_PRESENT 0x80

#define GDT_FLAG_4K      0x800
#define GDT_FLAG_32_BIT  0x400

#define GDT_ENTRIECOUNT 5
static uint64_t Gdt_Gdt[GDT_ENTRIECOUNT];

static inline void Gdt_SetEntry(int i, unsigned int Base, unsigned int Limit, int Flags)
{
    Gdt_Gdt[i] = Limit & 0xffffLL;
    Gdt_Gdt[i] |= (Base & 0xffffffLL) << 16;
    Gdt_Gdt[i] |= (Flags & 0xffLL) << 40;
    Gdt_Gdt[i] |= ((Limit >> 16) & 0xfLL) << 48;
    Gdt_Gdt[i] |= ((Flags >> 8 )& 0xffLL) << 52;
    Gdt_Gdt[i] |= ((Base >> 24) & 0xffLL) << 56;
}

void Gdt_Init()
{
    Console_WriteLine("Lade GDT");
    struct
    {
        uint16_t Limit;
        void* Ptr;
    } __attribute__((packed)) GdtP = {.Limit = GDT_ENTRIECOUNT * 8 - 1, .Ptr = Gdt_Gdt, };

    // GDT-Eintraege aufbauen
 
    Gdt_SetEntry(1, 0, 0xfffff, GDT_FLAG_SEGMENT | GDT_FLAG_32_BIT | GDT_FLAG_CODESEG | GDT_FLAG_4K | GDT_FLAG_PRESENT);
    Gdt_SetEntry(2, 0, 0xfffff, GDT_FLAG_SEGMENT | GDT_FLAG_32_BIT | GDT_FLAG_DATASEG | GDT_FLAG_4K | GDT_FLAG_PRESENT);
    Gdt_SetEntry(3, 0, 0xfffff, GDT_FLAG_SEGMENT | GDT_FLAG_32_BIT | GDT_FLAG_CODESEG | GDT_FLAG_4K | GDT_FLAG_PRESENT | GDT_FLAG_RING3);
    Gdt_SetEntry(4, 0, 0xfffff, GDT_FLAG_SEGMENT | GDT_FLAG_32_BIT | GDT_FLAG_DATASEG | GDT_FLAG_4K | GDT_FLAG_PRESENT | GDT_FLAG_RING3);
    Gdt_SetEntry(5, (uint32_t)(&Tss_Tss), sizeof(Tss), GDT_FLAG_TSS | GDT_FLAG_PRESENT | GDT_FLAG_RING3);

    // GDT neu laden
    asm volatile("lgdt %0" : : "m" (GdtP));
   
    // Segmentregister neu laden, damit die neuen GDT-Eintraege auch wirklich
    // benutzt werden
    asm volatile(
        "mov $0x10, %ax;"
        "mov %ax, %ds;"
        "mov %ax, %es;"
        "mov %ax, %ss;"
        "ljmp $0x8, $.1;"
        ".1:"
    );
   
    // Taskregister neu laden
    asm volatile("ltr %%ax" : : "a" (5 << 3));
   
    Console_WriteLine("GDT bereit");
}
und der Code von "tss.h":
#ifndef TSS
#define TSS

#include <stdint.h>
#include <stddef.h>
typedef struct TssStruct
{
    uint32_t prevtasklink;
    uint32_t esp0;
    uint32_t ss0;
    uint32_t esp1;
    uint32_t ss1;
    uint32_t esp2;
    uint32_t ss2;
    uint32_t cr3;
   
    uint32_t eip;
    uint32_t eflags;
    uint32_t eax;
    uint32_t ecx;
    uint32_t edx;
    uint32_t ebx;
    uint32_t esp;
    uint32_t ebp;
   
    uint32_t esi;
    uint32_t edi;
    uint32_t es;
    uint32_t cs;
    uint32_t ss;
    uint32_t ds;
    uint32_t fs;
    uint32_t gs;
   
    uint32_t ldt;
    uint32_t iomapbaseaddress;
   
} __attribute__((packed)) Tss;
extern Tss Tss_Tss;
#endif
In "tss.c" setze ich eigentlich bis auf "ss0" bloß alles auf Null. "ss0" wird auf 16 gesetzt.

Nochwas anderes was ich mich seit einiger Zeit frage:
Kann man eigentlich davon ausgehen dass der Gcc das "Gdt_SetEntry" komplett so inlined und optimiert, dass es wie eine einfache Zuweißung einer LL-Konstante im Assemblercode dasteht?

Ich hoffe ihr könnt mir, wie schon bei meinen ersten Problem, sehr kompetent weiterhelfen.  :-D
6
Ich habe das Problem, dass ich einige Methoden eines Headers einfach nicht aufrufen kann.  :cry:

Zb. in meiner "AsmAcess.h":
#ifndef ASMACCESS
#define ASMACCESS

#include <stdint.h>

inline uint8_t inb(uint16_t Port)
{
    unsigned char Data = 0;
    asm volatile ("inb %1, %0" : : "a" (Data), "Nd" (Port));
    return Data;
}
inline void outb(uint16_t Port, uint8_t Data)
{
    asm volatile ("outb %0, %1" : : "a" (Data), "Nd" (Port));
}
inline void halt()
{
    StopPoint:
    asm volatile ("cli");
    asm volatile ("hlt");
    goto StopPoint;
}

#endif
Diese Datei binde ich dann zb. in meinem Kernel ein:
#include "kernel\console.h"
#include "kernel\asmaccess.h"

void main()
{
    Console_ClearScreen();
    Console_WriteLine("Hallo!");
    Console_WriteLine("Ich heiße Compi!");
    Console_WriteLine("Ich bin ein Computer");
    Console_WriteLine("und lasse hier diesen sinnfreien Text anzeigen.");
    halt();
}

Wenn ich das Ganze dann mit folgendem Code kompilieren will:
del obj\*.o
SET C_COMPILE=i586-elf-gcc -m32 -ffreestanding -Wall -nostdinc -std=gnu99 -I stdlib
SET ASM_COMPILE=nasm -f elf

%ASM_COMPILE% -o obj\start_S.o start.S
%C_COMPILE% -o obj\kernel_c.o -c kernel.c

%C_COMPILE% -o obj\beep_c.o -c kernel\beep.c
%C_COMPILE% -o obj\console_c.o -c kernel\console.c

%C_COMPILE% -o obj\rand_c.o -c stdlib\rand.c

i586-elf-ld -T linkconf.ld -o obj\kernel.bin obj\*.o -Ttext=0x100000

copy obj\kernel.bin cd\kernel.bin
mkisofs -R -J -b boot/grub/stage2_eltorito -no-emul-boot -boot-load-size 4 -boot-info-table -o cdrom.iso cd/
Kommt beim Linken immer diese Fehlermeldung:
obj\kernel.o: In Funktion "[i]main[/i]":
kernel.c(.text+0x57): undefined reference to "halt"

Ich bin absolut ratlos, was das Problem auslöst.
Eigentlich müsste der Präprozessor "#include "kernel\asmaccess.h"" mit dem Code in der Datei ersetzen und abschliessend das Ganze inlinen.
Doch weshalb tut er das nicht?  :-o

Ich hoffe ihr könnt mir helfen.  :-)
Seiten: [1]

Einloggen