OSDev in Pascal..

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
crg

OSDev in Pascal..

Post by crg »

Hi,

Ive started trying to code simple OS under FreePascalCompiler. If anyone is interested in it, or in OSDEV in Pascal then please read this:

If you want to skip RTL ommit the linking stage using the "-a" switch. FPC requires some external symbols, like:

FPC_INITIALIZEUNITS ; this function should initialize all the units
FPC_DO_EXIT         ; what to do if the program ends
INIT$$SYSTEM        ; init for basic system routines

It can looks like:

;--

global FPC_INITIALIZEUNITS
global FPC_DO_EXIT
global INIT$$SYSTEM

extern program_init


INIT$$SYSTEM:
start:
    call program_init

    ret

FPC_INITIALIZEUNITS:
    ret

FPC_DO_EXIT:
ret

; --

compile this file, for example "nasm filename.asm -f aout"

all you have to do later is to link main pascal program and this tiny asm loader.

To output "flat binary":

ld asmout.o pascalprog.o --oformat binary -Ttext 0xtextsectionstart

If you`ll use some procedures/functions in the linking stage some errors will be displayed.. these are functions which FPC requires for property working, like copying parameters to a function. Look at FPC sources (it might be "rtl sources\inc\i386.inc"), if you dont find this procedure out there try to find it somewhere else in the sources tree.

Another useful thing is old, good intel syntax. To enable it use "-Rintel" switch in ppc386 command-line. You can then use assembler syntax like:

mov eax, $0DEADBEEF
mov esi, $012345
mov [esi], eax

...

This things are really basic. Its quite weird, but not difficult. When I`ll have some more free time I`ll try to describe this things much more clearier, and deeper.

If you have any questions, or you have write some your own piece of code, please write me: [email protected]

I hope this small text could help someone in Pascal-OSDEV.

Greetings, Crg.
crg

RE:OSDev in Pascal..

Post by crg »

Ah, and a small example:

Remember to switch under pmode before that.. :)

BTW: Every `uses' unit has initialization code, called INIT$$UNIT_NAME. <- this is a main procedure after Implementation and Interface stuff.

{

begin

code..

end.

}

!!!!!!!!!!!!!!!!!! i386.inc !!!!!!!!!!!!

{

THIS CODE IS GRABBED FROM THE FREEPASCALCOMPILER SOURCES

rtl_sources_dir\inc\i386.inc

}

{$asmmode ATT}
{$define FPC_SYSTEM_HAS_FPC_SHORTSTR_COPY}
procedure int_strcopy(len:longint;sstr,dstr:pointer);[public,alias:'FPC_SHORTSTR_COPY'];

begin
  asm
        pushl   %eax
        pushl   %ecx
        cld
        movl    dstr,%edi
        movl    sstr,%esi
        xorl    %eax,%eax
        movl    len,%ecx
        lodsb
        cmpl    %ecx,%eax
        jbe     .LStrCopy1
        movl    %ecx,%eax
.LStrCopy1:
        stosb
        cmpl    $7,%eax
        jl      .LStrCopy2
        movl    %edi,%ecx       { Align on 32bits }
        negl    %ecx
        andl    $3,%ecx
        subl    %ecx,%eax
        rep
        movsb
        movl    %eax,%ecx
        andl    $3,%eax
        shrl    $2,%ecx
        rep
        movsl
.LStrCopy2:
        movl    %eax,%ecx
        rep
        movsb
        popl    %ecx
        popl    %eax
  end ['ESI','EDI'];
end;

!!!!!!!!!!!!!!!!!! i386.inc END !!!!!!!!!!!!

!!!!!!!!!!!!!!!!!! kernel.pas !!!!!!!!!!!!!!

{$I i386.inc}

var
        screen             : array [0..4000] of byte absolute $b8000;
        i, j               : word;
        screen_x, screen_y : word;

procedure write_char(c:char); forward;
procedure puts(text: string); forward;

procedure puts(text: string);

var

    i    :  word;

begin

    i:= 1;

    while 1 > 0 do begin

        if (text[i] = #0) then break;
        write_char(text[i]);
        i:=i + 1;

    end;

end;

procedure write_char(c : char);

var
    addr : ^char;

begin

    if ((screen_x > 79) or (c = #10)) then begin
       screen_x:= 0;
       screen_y:= screen_y + 1;
    end;

    addr:= $0b8000;
    addr:= addr + screen_x * 2 + screen_y * 160;
    addr[0]:= c;
    addr[1]:= #7;

    screen_x := screen_x + 1;

end;

begin

     screen_x:= 0;
     screen_y:= 0;

     puts('This is simple kernel..');

end.

!!!!!!!!!!!!!!!!!! kernel.pas END !!!!!!!!!!!!!!

!!!!!!!!!!!!!!!!!! loader.asm !!!!!!!!!!!!!!


global FPC_INITIALIZEUNITS
global FPC_DO_EXIT
global INIT$$SYSTEM

extern program_init


INIT$$SYSTEM:

start:
    call program_init

    ret

FPC_INITIALIZEUNITS:
    ret

FPC_DO_EXIT:
ret

!!!!!!!!!!!!!!!!!! loader.asm END !!!!!!!!!!!!!!


to compile this type:

ppc386 kernel.pas -Cn -a -Rintel
nasm loader.asm -f aout -o loader.o
ld loader.o kernel.o --oformat binary -o kernel.img -Ttext 0xTEXTBASE


I hope I havent forgot about anything..
kazio0
Posts: 4
Joined: Sat Dec 09, 2006 6:02 am

Post by kazio0 »

Code: Select all

os.pas(45,12) Error: Incompatible types: got "LongInt" expected "^Char"
os.pas(62) Fatal: There were 1 errors compiling module, stopping
os.pas(62) Fatal: Compilation aborted
addr:= $0b8000;

Why??
kazio0
Posts: 4
Joined: Sat Dec 09, 2006 6:02 am

Post by kazio0 »

yhey people!! help my :P
nick8325
Member
Member
Posts: 200
Joined: Wed Oct 18, 2006 5:49 am

Post by nick8325 »

kazio0 wrote:

Code: Select all

os.pas(45,12) Error: Incompatible types: got "LongInt" expected "^Char"
os.pas(62) Fatal: There were 1 errors compiling module, stopping
os.pas(62) Fatal: Compilation aborted
addr:= $0b8000;

Why??
addr := PChar($0b8000) should work. ($0b8000 is an integer; you need to type-cast it to a pointer.)
Post Reply