From: brian on
I've been poring over megabytes of documentation until my eyes started
bleeding, but I just cannot figure out how to tell GNAT to create a
raw binary (no header) executable using GNAT hosted on Windows. I
need to write code that runs on x86/x64 bare metal (no operating
system).

Any pointers would be greatly appreciated!

-Brian
From: Stephen Leake on
brian <brian.catlin(a)gmail.com> writes:

> I've been poring over megabytes of documentation until my eyes started
> bleeding, but I just cannot figure out how to tell GNAT to create a
> raw binary (no header) executable using GNAT hosted on Windows. I
> need to write code that runs on x86/x64 bare metal (no operating
> system).
>
> Any pointers would be greatly appreciated!

Read up on 'pragma No_Run_Time'. It's labeled obsolescent, so apparently
there's a better way to do the same thing.

I'm not clear what you mean by "no header".

You need some way to load the code into the processor. I assume you are
first writing a boot prom, which will then load the rest of the code. So
you need a tool that will translate the object file into hex for a prom
burner. Gnu binutils must have that somewhere.

--
-- Stephe
From: brian on
On Apr 5, 9:39 am, Stephen Leake <stephen_le...(a)stephe-leake.org>
wrote:
> Read up on 'pragma No_Run_Time'. It's labeled obsolescent, so apparently
> there's a better way to do the same thing.

There is a new pragma, Restrictions, which provides a much finer
degree of control

> I'm not clear what you mean by "no header".

The first byte of the file is the code (i.e. no ELF or COFF
descriptors)

> You need some way to load the code into the processor. I assume you are
> first writing a boot prom, which will then load the rest of the code. So
> you need a tool that will translate the object file into hex for a prom
> burner. Gnu binutils must have that somewhere.

Jie Zhang (Code Sourcery) recommended ObjCopy (from BinUtils), which
appears to be able to take any GCC executable/object format and
convert it to any other - including just a raw binary file containing
just the code, which is exactly what I want.

The code will be written to disk. The MBR (Master Boot Record), which
is sector 0 on a PC boot disk, is loaded and called by the BIOS when
the PC is powered-on/reset. The partition table is also part of the
MBR, so it only leaves 440 bytes for the boot code, so I'm doing it in
multiple phases, with my MBR code (written is assembly) loading my
much larger standalone code (written in Ada).

I'm still fighting with GNAT GPL 2009 to build my standalone Ada code,
from a Windows development host. What I need is a bare bones (no
tasking, exceptions, files, etc.) GNAT Run Time Library for x86. I'm
going to try to create the GNAT ZFP (Zero Foot Print) RTL, but there
isn't any documentation on this (and I'm not even sure all the
necessary sources are in the GPL verrsion), so I'm flailing around a
bit.

-Brian
From: Tero Koskinen on
On Sun, 4 Apr 2010 05:44:36 -0700 (PDT) brian wrote:

> I've been poring over megabytes of documentation until my eyes started
> bleeding, but I just cannot figure out how to tell GNAT to create a
> raw binary (no header) executable using GNAT hosted on Windows. I
> need to write code that runs on x86/x64 bare metal (no operating
> system).
>
> Any pointers would be greatly appreciated!

For AVR, I use following commands:
$ make
ADA_PROJECT_PATH=/usr/local/avr/ada avr-gnatmake -XMCU=atmega328p -Phello.gpr --RTS=rts/atmega328p
avr-gcc -c -gnatec=/usr/local/avr/ada/gnat.adc -gdwarf-2 -gnatwp -gnatwu -gnatn -gnatp -gnatVn -Os -gnatef -fverbose-asm -frename-registers -mmcu=atmega328p -gnateDMCU=atmega328p -fdata-sections -ffunction-sections --RTS=rts/atmega328p -I- -gnatA /home/tkoskine/work/arduino/hello/hello.adb
avr-gnatbind -freestanding --RTS=rts/atmega328p -I- -x /home/tkoskine/work/arduino/hello/objects/hello.ali
avr-gnatlink /home/tkoskine/work/arduino/hello/objects/hello.ali -Wl,--gc-sections -gdwarf-2 -Wl,--relax --GCC=avr-gcc -Os -mmcu=atmega328p --RTS=rts/atmega328p -fdata-sections -ffunction-sections -Wl,-Map=../hello.map,--cref -L/usr/local/avr/ada/avr_lib/atmega328p/lib -lavrada -o /home/tkoskine/work/arduino/hello/hello.elf
avr-objcopy -O ihex -R .eeprom hello.elf hello.hex
$

Resulting file is something like:
$ cat hello.hex
:1000000033C000004CC000004AC0000048C00000DF
:1000100046C0000044C0000042C0000040C00000D4
:100020003EC000003CC000003AC0000038C00000E4
:1000300036C0000034C0000032C0000030C00000F4
:100040002EC000002CC000002AC0000028C0000004
:1000500026C0000024C0000022C0000020C0000014
:100060001EC000001CC0000011241FBECFEFD8E04E
:10007000DEBFCDBF11E0A0E0B1E0EAEBF1E002C0ED
:1000800005900D92A630B107D9F711E0A6E0B1E0D6
:1000900001C01D92A630B107E1F702D08CC0B0CFED
:1000A00000D0BF92CF92DF92EF92FF920F931F93F7
:1000B00083E390E060E029D08FEF84B91AB88BB960
:1000C00085B920E2B22E9DE0C92E15B853D0D82EA6
:1000D000B5B860E971E080E090E053D080E0E82EB0
:1000E00081E0F82E04E011E0C801B70121D0E090D2
:1000F000C000E5FEFCCFD092C600D090C000D5FE77
:10010000FCCFC092C6002ED0E0CF9093C500809364
:10011000C400662321F082E08093C00002C01092E8
:10012000C00038E13093C10026E02093C20008955A
:10013000FC0180819181482F50E0981790F0282F82
:10014000E22FF0E0E41BF50BE60FF71FE081809152
:10015000C00085FFFCCFE093C600291711F02F5F88
:10016000EFCF08958091C00085FFFCCF2AE0209357
:10017000C60008958091C00087FFFCCF8091C60023
:1001800008959B01AC01121613061406150694F48B
:1001900081E090E0A0E0B0E060ED77E0FB01319716
:1001A000F1F782179307A407B50721F00196A11D67
:0A01B000B11DF4CF0895F894FFCFBD
:0601BA00476F74200003F2
:00000001FF
$

This was for AVR/AVR-Ada, but I think the idea
applies to raw i386 programs also. By changing
the target of -O parameter, you can probably get
the output you want.

> -Brian


--
Tero Koskinen - http://iki.fi/tero.koskinen/
From: brian on
On Apr 5, 8:27 pm, Tero Koskinen <tero.koski...(a)iki.fi> wrote:
> For AVR, I use following commands:
> $ make
> ADA_PROJECT_PATH=/usr/local/avr/ada avr-gnatmake -XMCU=atmega328p -Phello.gpr --RTS=rts/atmega328p  
> avr-gcc -c -gnatec=/usr/local/avr/ada/gnat.adc -gdwarf-2 -gnatwp -gnatwu -gnatn -gnatp -gnatVn -Os -gnatef -fverbose-asm -frename-registers -mmcu=atmega328p -gnateDMCU=atmega328p -fdata-sections -ffunction-sections --RTS=rts/atmega328p -I- -gnatA /home/tkoskine/work/arduino/hello/hello.adb
> avr-gnatbind -freestanding --RTS=rts/atmega328p -I- -x /home/tkoskine/work/arduino/hello/objects/hello.ali
> avr-gnatlink /home/tkoskine/work/arduino/hello/objects/hello.ali -Wl,--gc-sections -gdwarf-2 -Wl,--relax --GCC=avr-gcc -Os -mmcu=atmega328p --RTS=rts/atmega328p -fdata-sections -ffunction-sections -Wl,-Map=../hello.map,--cref -L/usr/local/avr/ada/avr_lib/atmega328p/lib -lavrada -o /home/tkoskine/work/arduino/hello/hello.elf
> avr-objcopy -O ihex -R .eeprom hello.elf hello.hex

As you point out, the real trick is to use ObjCopy.

Now that is solved, I need to create the RTS library. Is this the
same AVR/ADA that is on SourceForge?

-Brian