Autor Thema: Grub kompatiblen C Kernel  (Gelesen 15849 mal)

JG

  • Beiträge: 189
    • Profil anzeigen
Gespeichert
« am: 27. February 2006, 11:56 »
Hallo,
vllt. kennen mich hier noch ein paar ;) Ich hab schon vor langer zeit mal versucht ein OS zu Programmiern und hab dann aber iweder aufgehört...

Da leider nicht mehr von dem Source Code übrig ist, wollte ich mal neu anfangen.
Nur bei einwas komme ich nicht weiter: Wie bekomme ich einen Kernel, den ich mit Grub booten kann (kA wie ich das damals gelöst hatte ;) )


Viele Grüße,
   Johannes

DarkThing

  • Beiträge: 652
    • Profil anzeigen
Gespeichert
« Antwort #1 am: 27. February 2006, 13:30 »
Hi
für den Anfang sollten diese Tutorials reichen:

Link 1
Link 2

Wenn du noch Fragen hast oder es Probleme gibt, kannst du natürlich fragen ;)

JG

  • Beiträge: 189
    • Profil anzeigen
Gespeichert
« Antwort #2 am: 27. February 2006, 13:44 »
Hallo,
danke ;)
nun hab ich aber erstmal ein anderes Problem... Ich hab im Moment SuSE und da gibts kein "nasm" :(
Nur "bin86 - Ein 8086 Assembler und Linker" geht das auch?


Viele Grüße,
   Johannes


Edit:
Ich hab nun eine Datei kernel.c

int main(void);

const unsigned MultibootHeader[12] =
{
0x1BADB002, // der magische Wert
0x00000000, // die Flags
0xE4524FFE, // die Checksumme
(unsigned) MultibootHeader, // Offset des Headers
(unsigned) main, // Offset von main() als Beginn des Code Segments
0x00000000, // Data Segment, da scheißen wir drauf
0x00000000, // BSS Segment, wer braucht`n sowas?
(unsigned) main, // nochmal main(), diesmal als Entry Point
0x00000000, // Grafik? Nein, danke!
0x00000050, // 80 Spalten
0x00000019, // 25 Zeilen
0x00000000 // 0 BPP, wir sind im Text-Modus
};


int main()
{
char *Text = "Welcome to Protected Mode";
char *VideoMem = (char*)0xB8000;

while(*Text)
{
*VideoMem = *Text;
*VideoMem++;
*VideoMem = 7;
*VideoMem++;
*Text++;
}

return(0);
}

dann hab ich folgende Befehle ausgefürt:
gcc -c -ffreestanding -nostdinc -O3 -Wall kernel.c
und
ld -Ttext 0x100000 --oformat elf32-i386 -O 1 -o kernel kernel.o
dann kam folgende Warung:
ld: warning: cannot find entry symbol _start; defaulting to 0000000000100000
Kann ich nun die Datei "kernel" einfach von Grub laden lassen?


Viele Grüße,
   Johannes


Edit2:
Es geht!

DarkThing

  • Beiträge: 652
    • Profil anzeigen
Gespeichert
« Antwort #3 am: 27. February 2006, 20:21 »
bin86 kenn ich zwar nicht, aber benutz den besser nicht - vielleicht hat der ne andere Syntax oder so und das verwirrt einen nur. Wenn du Nasm mit Yast nicht findest, musst du den halt als RPM-File downloaden und manuell installieren. Vielleicht ist hier was dabei:
Nasm @ RPM-Seek

JG

  • Beiträge: 189
    • Profil anzeigen
Gespeichert
« Antwort #4 am: 28. February 2006, 08:18 »
Hallo,
was soll eigentlich die Warung vom Linker bedeuten? (s. o.)

Nun hab ich noch eine Frage: was hat es mit der "multiboot_info" Struktur auf sich? Was ist da alles drinnen gespeichert (ich hab gehört, dass da drinnen steht, wie groß der Arbeitsspeicher ist, ...)


Viele Grüße,
   Johannes

DarkThing

  • Beiträge: 652
    • Profil anzeigen
Gespeichert
« Antwort #5 am: 28. February 2006, 14:57 »
Die Linkerwarnung kannst du gefahrlos ignorieren (auf jeden Fall konnte ich das immer ;) )

Die multiboot_info Struktur ist so aufgebaut:

typedef struct multiboot_info
{
unsigned long flags;
unsigned long mem_lower;
unsigned long mem_upper;
unsigned long boot_device;
unsigned long cmdline;
unsigned long mods_count;
unsigned long mods_addr;
union
{
aout_symbol_table_t aout_sym;
elf_section_header_table_t elf_sec;
} u;
unsigned long mmap_length;
unsigned long mmap_addr;
unsigned long drives_length;
unsigned long drives_addr;
unsigned long config_table;
unsigned long boot_loader_name;
unsigned long apm_table;
unsigned long vbe_control_info;
unsigned long vbe_mode_info;
unsigned long vbe_mode;
unsigned long vbe_interface_seg;
unsigned long vbe_interface_off;
unsigned long vbe_interface_len;
} multiboot_info_t;

Das meiste sollte selbsterklärend sein. Deinem Kernel wird eine Magic Number in EAX übergeben und ein Pointer auf diese Struktur in EBX. Ich gehe jetzt davon aus dass dein Entry Point in einer Assembler-Datei liegt: Da schreibst du vor den Aufruf der C-Main-Funktion diesen Code:

push ebx
push eax

Der Grund dafür ist einfach: In C werden Funktionsparameter über den Stack übergeben, und zwar von rechts nach links. Deshalb wird beides gepusht und zwar zuerst EBX und dann erst EAX. Deine C-Funktion musst du jetzt um die beiden Parameter erweitern:

void main(unsigned int iMagic, multiboot_info_t* pBootInfo)


Jetzt hast du in C einen Pointer auf diese Struktur und kannst dir z.B. so die Menge des RAM in MB holen:

unsigned int iRAM = (pBootInfo->mem_upper+1024)/1024;

JG

  • Beiträge: 189
    • Profil anzeigen
Gespeichert
« Antwort #6 am: 28. February 2006, 16:02 »
Hallo,
danke ;)
So halb hab ich das verstanden *g*
Nur ich hab eine Frage:
Zitat

Ich gehe jetzt davon aus dass dein Entry Point in einer Assembler-Datei liegt:

Was ist ein "Entry Point"? Und ich habe keine Assembler-Datei, mein Kernel ist komplett in C geschrieben. Wie kann ich die 2 Register dann auf den Stack pushen?

Und was ist die "Magic Number"?


Viele Grüße,
   Johannes

JG

  • Beiträge: 189
    • Profil anzeigen
Gespeichert
« Antwort #7 am: 01. March 2006, 16:29 »
Hallo,
ich habe noch ein Problem:
Sobald ich den Code einfüge kommen viele Fehlermeldungen von GCC:

In file included from kernel.c:3:
./include/multiboot.h:28: error: syntax error before ‘aout_symbol_table_t’
./include/multiboot.h:28: warning: no semicolon at end of struct or union
./include/multiboot.h:28: warning: no semicolon at end of struct or union
./include/multiboot.h:29: warning: type defaults to ‘int’ in declaration of ‘elf_sec’
./include/multiboot.h:29: warning: data definition has no type or storage class
./include/multiboot.h:30: warning: type defaults to ‘int’ in declaration of ‘u’
./include/multiboot.h:30: warning: data definition has no type or storage class
./include/multiboot.h:44: error: syntax error before ‘}’ token
./include/multiboot.h:44: warning: type defaults to ‘int’ in declaration of ‘multiboot_info_t’
./include/multiboot.h:44: warning: data definition has no type or storage class


DarkThing

  • Beiträge: 652
    • Profil anzeigen
Gespeichert
« Antwort #8 am: 01. March 2006, 16:36 »
Der Code den ich oben gepostet hab ist natürlich nicht vollständig. Die Struktur aout_symbol_table_t fehlt zum Beispiel, daher die Compiler Fehler.
Hier der restliche Code (muss vor die multiboot Strukur):

typedef struct aout_symbol_table
{
unsigned long tabsize;
unsigned long strsize;
unsigned long addr;
unsigned long reserved;
} aout_symbol_table_t;

typedef struct elf_section_header_table
{
unsigned long num;
unsigned long size;
unsigned long addr;
unsigned long shndx;
} elf_section_header_table_t;


Der Entry Point ist die Adresse im Kernel zu der der Bootloader springt, dort fängt also der eigentlich Code an. In einem C-Programm ist das die main()-Funktion. Wenn dein Entrypoint also in einem Assembler File liegt heißt das, dass die ersten Befehle die ausgeführt werden noch in ASM geschrieben wurden und du erst zum C-Teil springen musst.

Die Magic Number... tja... hm.. keine Ahnung, maximal zur Kontrolle, aber wirklich wichtig ist die nicht.

JG

  • Beiträge: 189
    • Profil anzeigen
Gespeichert
« Antwort #9 am: 01. March 2006, 16:42 »
Hallo,
und wie soll ebx und eax pushen, wenn mein Kernel komplett in C geschrieben ist?

DarkThing

  • Beiträge: 652
    • Profil anzeigen
Gespeichert
« Antwort #10 am: 01. March 2006, 17:16 »
Hi,
also hier ist ein Beispiel-Kernel, der Grub kompatibel ist und der einen Text ausgeben sollte. Wenn noch jemand Fragen hat, kann er die ja hier stellen.
Link: home.pages.at/darkthing/grubkernel.tar.gz
Noch eine kurze Erklärung:
Nach dem Entpacken, in der Konsole in den Ordner gehen in dem alle Dateien sind. Dort kann man mit "make all" den Kernel compilieren, mit "make install" ein Image erstellen (geht nur unter Linux) und mit "make run" sollte man als Qemu-User das Image booten können.

JG

  • Beiträge: 189
    • Profil anzeigen
Gespeichert
« Antwort #11 am: 01. March 2006, 18:31 »
Kann man das ganze auch ohne ASM machen?

Viele Grüße,
   Johannes

DarkThing

  • Beiträge: 652
    • Profil anzeigen
Gespeichert
« Antwort #12 am: 01. March 2006, 19:09 »
Vielleicht gehts. Vorraussetzung wär, dass der Compiler den Code so generiert dass EAX und EBX erhalten bleiben, dann könntest du per Inline ASM dir den Pointer holen. Aber das ist sicher nicht die beste Methode. Nimms einfach hin, so schlimm ist eine ASM-Datei ja auch nicht ;) Im Endeffekt hast du dadurch eher Vorteile als Nachteile und den Asm-File kannste ja kopieren und nie wieder ändern  :)

JG

  • Beiträge: 189
    • Profil anzeigen
Gespeichert
« Antwort #13 am: 01. March 2006, 20:00 »
Nur ich hab im Moment kein nasm  :wink:
mal schaun ob ich das irgendwie hin kriege ;)

DarkThing

  • Beiträge: 652
    • Profil anzeigen
Gespeichert
« Antwort #14 am: 01. March 2006, 20:13 »
Also nasm installieren sollte kein Problem sein. Versuchs mal hiermit

JG

  • Beiträge: 189
    • Profil anzeigen
Gespeichert
« Antwort #15 am: 02. March 2006, 14:14 »
Ist NASM frei (bzw. kostenlos)?

DarkThing

  • Beiträge: 652
    • Profil anzeigen
Gespeichert
« Antwort #16 am: 02. March 2006, 14:32 »
Ja, ist auch Open Source (Source Code).

Coffee

  • Beiträge: 470
    • Profil anzeigen
Gespeichert
« Antwort #17 am: 08. March 2006, 11:46 »
andere frage: darf ich open source programme für mein os compilen und dort verwenden??

DarkThing

  • Beiträge: 652
    • Profil anzeigen
Gespeichert
« Antwort #18 am: 08. March 2006, 16:13 »
Die meisten Open Source Programme stehen ja unter der GPL. Du darfst also den Source nehmen und das Tool für dein OS kompilieren. Nur musst du eventuelle Änderungen am Source Code wieder veröffentlichen.

Coffee

  • Beiträge: 470
    • Profil anzeigen
Gespeichert
« Antwort #19 am: 08. March 2006, 17:47 »
hatte ich zwar nich vor trotzdem danke..... wie macht ihr das mit anwendungen für euer os... entwerft ihr n eigenes format oder wollt ihr "laufzeitkompilieren" also sourcecodes speichern und beim benutzen compilieren...
ich mein das so:

ich hab kein "exe(oder sons was)-format sondern speichere in meinem source z.B. den source von nasm
dann bracuht ein benutzer von meinem os nur noch den source aufrufen -> der geht durch nasm-> kann benutzt werden
so währen viele programmme(open source....etc.) zu meinem os kompatibel..


würde das gehen??

 

Einloggen