Gå til innhold

Problem: Flat binær kompilasjon med GCC (MinGW)!


Anbefalte innlegg

Jeg kan litt C, og tenkte jeg skulle lage ett par små kernels som jeg kan laste over på en floppy, bare for morroskyld, men jeg har en del problemer med compileren her. Har lasta ned GCC MinGW, som er en bra C kompiler, som kjører på NT, men den nekter meg å linke objekt filer jeg vil ha ut som flat binary (uten headers for hverken Windows, Linux, eller noe, bare CPU kode fra starten med unntak av strings, og andre ressurser).

 

Jeg lagde en kernel som ikke gjør en drit først for å se om compileren kompilerer:

 

int main()
{
 return 0;
}

 

 

Den gjør ikke mye den, hehe :), however, når jeg prøver å compile den med disse kommandoene, går det ikke:

 

gcc -c test.c

ld test.o -o test.bin --oformat binary -Ttext $100000

 

Resultatet:

ld: PE operations on non PE file.

 

 

Why? Den lille .c fila har jo ingen PE kode, og jeg prøver ikke å gjøre en PE operasjon jeg. Alt jeg gjør er å kompilere en C fil som ikke gjør en dritt, om til flat binary, som også bare ville halta PC'en hvis jeg prøvde å starte opp med den.

 

Har lest at dette kanskje er en bug i LCC for Windows. Er det sant? Workarounds?

Endret av chrml
Lenke til kommentar
Videoannonse
Annonse

gcc -ffreestanding -c test.c

 

^- Den fjerner alle "precompiled headers", og gir deg en ren binær fil.

Tror dette skal funke.

 

Du er ikke den eneste som har prøvd dette :D

Det er drittgøy, for når du skriver alt fra scratch, så lærer du hvordan alt funker også, selv om det kan være litt vanskelig.

 

EDIT: Og ja, det er TO f'er. Ikke leif.

Endret av kr1570ffz0r
Lenke til kommentar
gcc -ffreestanding -c test.c

 

^- Den fjerner alle "precompiled headers", og gir deg en ren binær fil.

Tror dette skal funke.

 

Du er ikke den eneste som har prøvd dette :D

Det er drittgøy, for når du skriver alt fra scratch, så lærer du hvordan alt funker også, selv om det kan være litt vanskelig.

 

EDIT: Og ja, det er TO f'er. Ikke leif.

En ting, det der, creater ikke det en objekt fil, og ikke det ferdige kompilerte resultatet?

 

Isåfall, ld.exe klager enda på "PE operations on non PE file".

 

Åpna test.o som blei resultatet, og det så veldig ut som en objekt fil (hadde til og med stringen test.c inni seg).

Lenke til kommentar

Her er noe jeg fannt som ser ut til å kompilere som det skal under Linux (GCC-3.4.0):

 

Kernel.cpp:

#include "Video.h"

int main(void)
{
       Video vid;  //local, (global variables need some Run-Time support code)

       vid.write("Hello, world!");
}

 

Link.ld:

OUTPUT_FORMAT("binary")
ENTRY(start)
SECTIONS
{
   .text 0x100000 :
   {
       code = .; _code = .; __code = .;
       *(.text)
       . = ALIGN(4096);
   }

   .data :
   {
       data = .; _data = .; __data = .;
       *(.data)
       . = ALIGN(4096);
   }

   .bss :
   {
       bss = .; _bss = .; __bss = .;
       *(.bss)
       . = ALIGN(4096);
   }

   end = .; _end = .; __end = .;
}

 

Loader.asm:

[BITS 32]; protected mode

[global start]
[extern main]; this is in our C++ code

start:
call main; call int main(void) from our C++ code
cli; interrupts could disturb the halt
hlt; halt the CPU

 

Video.cpp:

#include "Video.h"

Video::Video()
{
       pos=0;        off=0;
       videomem = (unsigned short*) 0xb8000;
}

Video::~Video() {}

void Video::clear()
{
       unsigned int i;

       for(i=0; i<(80*25); i++)
       {
               videomem[i] = (unsigned char) ' ' | 0x0700;
       }
       pos=0; off=0;
}

void Video::write(char *cp)
{
       char *str = cp, *ch;

       for (ch = str; *ch; ch++)
       {
               put(*ch);
       }
}

void Video::put(char c)
{
       if(pos>=80)
       {
               pos=0;
               off += 80;
       }

       if(off>=(80*25))
       {
               clear(); //should scroll the screen, but for now, just clear
       }

       videomem[off + pos] = (unsigned char) c | 0x0700;
       pos++;
}

 

Video.h:

#ifndef VIDEO_H
#define VIDEO_H        //so we don't get multiple definitions of Video

class Video
{
public:
       Video();
       ~Video();
       void clear();
       void write(char *cp);
       void put(char c);
private:
       unsigned short *videomem;   //pointer to video memory
       unsigned int off;                    //offset, used like a y cord
       unsigned int pos;                  //position, used like x cord

}; //don't forget the semicolon!

#endif

 

Kompilering:

g++ -c Video.cpp -nostdlib -fno-builtin -fno-rtti -fno-exceptions

g++ -c Kernel.cpp -nostdlib -fno-builtin -fno-rtti -fno-exceptions

nasm -f aout Loader.asm -o Loader.o

 

Linking:

ld -T Link.ld -o Kernel.bin Loader.o Kernel.o Video.o

 

Regner med at det fungerer med MinGW (GCC) under Win32 også.

Lenke til kommentar
gcc -ffreestanding -c test.c

 

^- Den fjerner alle "precompiled headers", og gir deg en ren binær fil.

Tror dette skal funke.

 

Du er ikke den eneste som har prøvd dette :D

Det er drittgøy, for når du skriver alt fra scratch, så lærer du hvordan alt funker også, selv om det kan være litt vanskelig.

 

EDIT: Og ja, det er TO f'er. Ikke leif.

En ting, det der, creater ikke det en objekt fil, og ikke det ferdige kompilerte resultatet?

 

Isåfall, ld.exe klager enda på "PE operations on non PE file".

 

Åpna test.o som blei resultatet, og det så veldig ut som en objekt fil (hadde til og med stringen test.c inni seg).

Det var bare et eksempel.

Lenke til kommentar
Ang. booting og sånnt, ta en titt her: http://bochs.sourceforge.net/

 

Kan spare deg for masse-masse tid. :]

Jeg bruker en test-maskin som booter kjappere enn lynet,

det er en gammal PackardBell PIII, 500 mhz med 384 mb ram,

som jeg brukte før.

 

Men uansett kan det jo være verd et forsøk, jeg må jo faktisk flytte meg et stykke for å komme til den andre maskinen, hele 5 meter faktisk :cool:

 

EDIT: Sorry for dobbelpost, det tenkte jeg ikke på :blush:

Endret av kr1570ffz0r
Lenke til kommentar

Thanks for hjelpa :)!

 

Har ett lite problem though. Akkurat nå prøver jeg å boote kernelen min fra en floppy. Først prøvde jeg å laste den 512 byte svære kernel fila mi inn i floppyens sektor 0 (kompilert med søppels eksempelkode), og la til 55AA på slutten for at den skal boote. Den boota, men den frøys opp maskina, og jeg veit hvorfor. Asm koden er kompilert 32 bit, mens jeg tviler på at Bootstar enabler Protected Mode før den prøver å laste kernelen, så derfor funka ikke det.

 

Da tenkte jeg på koden:

 

[BITS 16];starte i 16 bit

[global start]
[extern _k_main]; this is in the c file

start:
 mov eax, cr0;for å enable protected mode
 or al,1
 mov cr0,eax

 [BITS 32];gå over til 32 bit

 call _k_main;og kjøre main funksjonen i C

 cli
 hlt

 

However, jeg kan ikkeno asm (helt blank), så jeg veit ikke om det jeg kokte sammen faktisk kan funke.

 

Hvis det ikke gjør det, åssen kan jeg laste sektor 1 inn i minnet, og jumpe dit i asm, så jeg kan ha 32 bit koden der?

Endret av chrml
Lenke til kommentar

Yep, men egentlig alt den bootloaderen gjør (hvertfall fra floppy) er å loade kernelen inn i minnet (ved å tolke filsystemet, eller å loade fra en spesiell posisjon), switche til protected mode, og så jumpe til minnet den lasta kernelen inn i.

 

For å gjøre dette simpelt foreløpig, tenkte jeg at jeg skulle plassere en liten kernel på sektor 1, og lage en bootloader (16 bit (real kompatibel) i asm, som jeg ikke kan en drit i) på sektor 0 som switcher over til protected mode, laster kernelen fra sektor 1 i minnet (på 1mb streken, kanskje), og jumpe dit.

 

Prøvde GRUB, men skjønte ikke mye av åssen den funker.

Endret av chrml
Lenke til kommentar

Bootloaderen er jo simpel, den, det er jo bare å følge en tutorial første gangen, men saken er at bootloaderen har kanskje mye å gjøre, og da må du lage bootstrap (som noen kaller det) også. Det bootloaderen vil gjøre da, er å laste bootstrap'en inn i minnet, og deretter vil bootstrapen laste kernelen. Jeg har fått til å laste kernelen UFORSKYLDT, jeg bare prøvde meg litt frem, siden tutorialen jeg fulgte sluttet rett før jeg skulle jumpe inn i protected mode og laste kernelen. Men jeg tror jeg lærer meg litt mer assembly før jeg fortsetter mer med dette :roll:

 

EDIT: http://www.osdev.org/

Endret av kr1570ffz0r
Lenke til kommentar

Hehe, detta er gøy.

 

Jeg anbefaler ALLE som har litt programmering og PC kunnskaper til å prøve detta. Det er pain in the ass å få det til første gang, men seinere går det som bare det.

 

I går kunne jeg lite C, og ikkeno Assembly, og sleit med å boote dette. I dag skriver jeg C funksjoner til OS kernelen min som bare det, og kjører det på emulatoren med ett trykk :) (.bat filer), og hvis jeg gidder, også ordentlig boote kernelen med floppy.

 

Lage OS med DJGPP (C kompiler), og Nasm (assembler), anbefales på det sterkeste :D.

Endret av chrml
Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
×
×
  • Opprett ny...