c++ - C compilation on cygwin to target standalone platform -


i have code below i'd compile statically run on tiny os (almost no os! load machine code specific address in memory after protected mode has been activated). attempts have far been unsuccessful. possible in first place? if not, easiest way accomplish this?

#include <stdio.h> #define txt_color 7 #define printf(...) {sprintf(str,__va_args__);\                 int i=0; while(str[i])\                 write_string(txt_color, &str[i++] );}                  // sprintf takes printf arguments , format data                 // write_string outputs data video buffer  int write_string( int colour, const char *string );  int _start()   {   char str[256]="";   char c='z';   int j=9;   float f=9.76777;    printf("%d\t%f\t%c\this test\n test more!\n\n",j,f,c); }  int write_string( int colour, const char *string )    {            /* function write character video buffer*/    volatile char *videobuff = (volatile char*)0xb8000;   while( *string != 0 )        {        *videobuff++ = *string++;        *videobuff++ = colour;       } return 0; } 

for answer i'm assuming tiny os simple kernel boots 32-bit protected mode , doesn't else.

no c standard library :-(

to begin with, program has problem in using sprintf c standard library. i'm afraid have either write own sprintf (relatively easy) or port implementation of *libc os (slightly more challenging). recommend first test, call raw write_string function. let's put infinite loop @ end of _start -- remember "returning main" involves lot happening behind scenes won't yet implemented on bare metal os:

#define txt_color 7  int write_string( int colour, const char *string );  int _start() {   write_string(txt_color, "this test");   (;;); }  /* function write character video buffer*/ int write_string( int colour, const char *string ) {               volatile char *videobuff = (volatile char*)0xb8000;   while( *string != 0 ) {     *videobuff++ = *string++;     *videobuff++ = colour;   }   return 0; } 

compilation

with cygwin gcc, can compile source file (i've named prog.c) raw binary in 3 stages.

first, run through c compiler produce intermediate object file (prog.o), making sure specify it's 32-bit machine:

cc -m32 -c -o prog.o prog.c 

next, feed prog.o linker, specifying 32-bit pe output format (this 32-bit elf on linux) , address loaded in memory (2mb in example). need specify function entry point, i.e., _start (gcc prepends underscore function names default real name __start):

ld -mi386pe -ttext 0x200000 --entry __start -o prog.pe prog.o 

finally, convert pe binary prog.pe raw, flat binary (prog.bin) doesn't require os-provided infrastructure run. load memory , directly execute:

objcopy -o binary prog.pe prog.bin 

sanity check

to sanity-check output before try loading os, take @ disassembly:

objdump -d prog.pe 

you should see _start function @ top, load address specified. example:

disassembly of section .text:  00200000 <__start>:   200000:       55                      push   %ebp   200001:       89 e5                   mov    %esp,%ebp   200003:       83 ec 18                sub    $0x18,%esp   ... 

then make sure raw bytes of disassembly of prog.bin matches 1 above (symbols/name not visible they've been stripped out). example:

$ objdump -d -b binary -m i386 prog.bin  disassembly of section .data:  00000000 <.data>:        0:       55                      push   %ebp        1:       89 e5                   mov    %esp,%ebp        3:       83 ec 18                sub    $0x18,%esp        ... 

Comments

Popular posts from this blog

jquery - How do you format the date used in the popover widget title of FullCalendar? -

asp.net mvc - SSO between MVCForum and Umbraco7 -

Python Tkinter keyboard using bind -