This is the mail archive of the
gcc-help@gcc.gnu.org
mailing list for the GCC project.
Building an OS kernel with GNAT
- From: "Luke A. Guest" <laguest at archangeli dot co dot uk>
- To: GCC-Help ML <gcc-help at gcc dot gnu dot org>
- Date: Sat, 13 Oct 2007 12:24:20 +0100
- Subject: Building an OS kernel with GNAT
Hi,
I've looked everywhere I can think and just cannot find the info I need.
A few years ago I messed around with a hello world style kernel in Ada.
This was when pragma No_Run_Time existed, but they've removed this now.
That kernel did build and worked fine.
Now, I'm attempting it again with a view to expanding it further. I
downloaded binutils-2.18.50 and gcc-4.2.2 (core/ada) and built as much
of a i386-elf target as it would build. So, I have gnat1 and gnatbind
for those targets, no runtime and no tools (why the tools can't be built
for these kinds of targets is beyond me).
I found some parameters in system.ads which I copied over and changed:
Run_Time_Name : constant String := "Zero Footprint Run Time";
Command_Line_Args : constant Boolean := False;
Configurable_Run_Time : constant Boolean := True;
Exit_Status_Supported : constant Boolean := False;
Suppress_Standard_Library : constant Boolean := True;
This seems to work, but when I try to compile my old vga console package
it fails on an assignment line:
nucleus-console.adb:12:21: construct not allowed in configurable
run-time mode
If I change the Configurable_Run_Time constant to false, I get:
nucleus-console.adb:12:21: run-time library configuration error
nucleus-console.adb:12:21: file interfac.ads not found
Ok, it's expecting some interfacing package for this line:
Video_Memory(Y)(X).Char := Char;
I have no idea why, does anyone else?
I'll include the vga console packages here for you to peruse:
with System;
package Nucleus.Console is
type Background_Colour_T is (
Black,
Blue,
Green,
Cyan,
Red,
Magenta,
Brown,
Light_Grey);
for Background_Colour_T use (
Black => 16#0#,
Blue => 16#1#,
Green => 16#2#,
Cyan => 16#3#,
Red => 16#4#,
Magenta => 16#5#,
Brown => 16#6#,
Light_Grey => 16#7#);
for Background_Colour_T'Size use 4;
type Foreground_Colour_T is (
Black,
Blue,
Green,
Cyan,
Red,
Magenta,
Brown,
Light_Grey,
Dark_Grey,
Light_Blue,
Light_Green,
Light_Cyan,
Light_Red,
Light_Magenta,
Yellow,
White);
for Foreground_Colour_T use (
Black => 16#0#,
Blue => 16#1#,
Green => 16#2#,
Cyan => 16#3#,
Red => 16#4#,
Magenta => 16#5#,
Brown => 16#6#,
Light_Grey => 16#7#,
Dark_Grey => 16#8#,
Light_Blue => 16#9#,
Light_Green => 16#A#,
Light_Cyan => 16#B#,
Light_Red => 16#C#,
Light_Magenta => 16#D#,
Yellow => 16#E#,
White => 16#F#);
for Foreground_Colour_T'Size use 4;
type Cell_Colour_T is
record
Foreground : Foreground_Colour_T;
Background : Background_Colour_T;
end record;
for Cell_Colour_T use
record
Foreground at 0 range 0 .. 3;
Background at 0 range 4 .. 7;
end record;
for Cell_Colour_T'Size use 8;
type Cell_T is
record
Char : Character;
Colour : Cell_Colour_T;
end record;
for Cell_T'Size use 16;
Screen_Width : constant UInt32_T := 80;
Screen_Height : constant UInt32_T := 25;
subtype Screen_Width_Range_T is UInt32_T range 1 .. Screen_Width;
subtype Screen_Height_Range_T is UInt32_T range 1 .. Screen_Height;
type Row_T is array (Screen_Width_Range_T) of Cell_T;
type Screen_T is array (Screen_Height_Range_T) of Row_T;
Video_Memory : Screen_T;
for Video_Memory'Address use System'To_Address(16#000B8000#);
pragma Import(Ada, Video_Memory);
procedure PutCharAt(
Char : in Character;
X : in Screen_Width_Range_T;
Y : in Screen_Height_Range_T;
Foreground : in Foreground_Colour_T;
Background : in Background_Colour_T);
procedure PutString(
Str : in String;
X : in Screen_Width_Range_T;
Y : in Screen_Height_Range_T;
Foreground : in Foreground_Colour_T;
Background : in Background_Colour_T);
procedure PutUInt32(
Data : in UInt32_T;
X : in Screen_Width_Range_T;
Y : in Screen_Height_Range_T;
Foreground : in Foreground_Colour_T;
Background : in Background_Colour_T);
procedure Clear(Background : in Background_Colour_T);
end Nucleus.Console;
package body Nucleus.Console is
procedure PutCharAt(
Char : in Character;
X : in Screen_Width_Range_T;
Y : in Screen_Height_Range_T;
Foreground : in Foreground_Colour_T;
Background : in Background_Colour_T) is
begin
Video_Memory(Y)(X).Char := Char;
Video_Memory(Y)(X).Colour.Foreground := Foreground;
Video_Memory(Y)(X).Colour.Background := Background;
end PutCharAt;
procedure PutString(
Str : in String;
X : in Screen_Width_Range_T;
Y : in Screen_Height_Range_T;
Foreground : in Foreground_Colour_T;
Background : in Background_Colour_T) is
begin
for Index in Str'First .. Str'Last loop
PutCharAt(Str(Index), X + Screen_Width_Range_T(Index) - 1, Y,
Foreground, Background);
end loop;
end PutString;
procedure PutUInt32(
Data : in UInt32_T;
X : in Screen_Width_Range_T;
Y : in Screen_Height_Range_T;
Foreground : in Foreground_Colour_T;
Background : in Background_Colour_T) is
type Numbers_Type is array (0 .. 9) of Character;
Numbers : constant Numbers_Type := ('0', '1', '2', '3', '4', '5',
'6', '7', '8', '9');
Str : String(1 .. 20);
Value : UInt32_T := Data;
Length : UInt32_T := 1;
Mask : UInt32_T := 16#0000_000F#;
procedure PutStringBackwards(
Str : in String;
Length : in UInt32_T;
X : in Screen_Width_Range_T;
Y : in Screen_Height_Range_T;
Foreground : in Foreground_Colour_T;
Background : in Background_Colour_T) is
begin
for Index in reverse Integer(Str'First) .. Integer(Length) loop
PutCharAt(Str(Index), X + Screen_Width_Range_T(Index) - 1,
Y, Foreground, Background);
end loop;
end PutStringBackwards;
begin
-- Find how many digits we need for this value.
while Value /= 0 loop
Str(Integer(Length)) := Numbers(Integer(Value and Mask));
Value := Value / 10;
Length := Length + 1;
end loop;
PutStringBackwards(Str, Length, X, Y, Foreground, Background);
end PutUInt32;
procedure Clear(Background : in Background_Colour_T) is
begin
for X in Screen_Width_Range_T'First .. Screen_Width_Range_T'Last
loop
for Y in Screen_Height_Range_T'First ..
Screen_Height_Range_T'Last loop
PutCharAt(' ', X, Y, White, Background);
end loop;
end loop;
end Clear;
end Nucleus.Console;