본문 바로가기
프로그래밍/PC

파스칼로 만든 부트로더... - 1 -

by 사악신 2012. 4. 9.

2006년경 OS 제작에 한창 관심을 가지고 있던 무렵, Turbo Pascal 과 Delphi 로 모든 걸 제작해보고자 마음 먹고 이리저리 머리를 굴린 결과~ TP 로 부트로더를 만드는데 성공했다.

{
000h~3FFh : Interrupt Vector Table
400h~4FFh : BIOS
500h~5FFh : DOS Parameters

1000h~7BFFh : unusable
7C00h~7DFFh : Boot Sector
7E00h~8FFFh : FAT Table
9000h~ABFFh : Directory Entry Table
10000h~1FFFFh : Stack 64 KBytes
20000h~2FFFFh : Boot Loader 64 KBytes
30000h~9FFFFh : Useable 448 KBytes(Kernel Image Location)
}

program btldr;

{$G+}

type
  TDescriptor = packed record
    Limit1, Limit2: Byte;
    Addr1, Addr2, Addr3: Byte;
    Access: Byte;
    GDOAVL_Limit3: Byte;
    Addr4: Byte;
  end;

const
  SEG_BOOT = $7C0;
  SEG_FAT = $7E0;
  SEG_STACK = $1000;
  SEG_LDR = $2000;
  SEG_IMG = $3000;

var
  Track, Head, Sector: Byte;
  gdt: array[0..63] of TDescriptor;

procedure SetVGA;
begin
  asm
    push ax
    mov ah, 0
    mov al, 12h
    int 10h
    pop ax
  end;
end;

procedure ShowChar(Chr: Char; Color: Byte);
begin
  asm
    push ax
    push bx
    mov ah, 0Eh
    mov al, Chr
    mov bh, 0
    mov bl, Color
    int 10h
    pop bx
    pop ax
  end;

  if Chr = #13 then
  begin
    asm
      push ax
      push bx
      mov ah, 0Eh
      mov al, 0Ah
      int 10h
      pop bx
      pop ax
    end;
  end;
end;

procedure ShowMessage(Msg: String; Color: Byte);
var
  i: Integer;
begin
  for i:= 1 to Ord(Msg[0]) do
  begin
    ShowChar( Msg[i], Color );
  end;
end;

function EnableA20:Boolean;
var
  State: Byte;
begin
  { for over 80486 cpu }
  State:= 0;
  asm
    mov ax, 2401h { Enable A20 }
    int 15h
    mov ax, 2402h { Check A20 0 - Disable, 1 - Enable }
    int 15h
    mov State, al
  end;

  if State = 1 then EnableA20:= True
  else EnableA20:= False;
end;

procedure ChangeProtectMode;
begin
  if EnableA20 then
  begin
    ShowMessage( 'Enable A20 Gate'#13, 14 );
  end else
  begin
    ShowMessage( 'Unable A20 Gate'#13, 3 );
    Exit;
  end;

  { GDT }
  { null Descriptor }
  with gdt[0] do
  begin
    Limit1:= $00;
    Limit2:= $00;
    Addr1:= $00;
    Addr2:= $00;
    Addr3:= $00;
    Access:= $00;
    GDOAVL_Limit3:= $00;
    Addr4:= $00;
  end;

  { Code Segment Descriptor }
  with gdt[1] do
  begin
    Limit1:= $FF;
    Limit2:= $FF;
    Addr1:= $00;
    Addr2:= $00;
    Addr3:= $01;
    Access:= $9A;
    GDOAVL_Limit3:= $CF;
    Addr4:= $00;
  end;

  { Data Segment Descriptor }
  with gdt[2] do
  begin
    Limit1:= $FF;
    Limit2:= $FF;
    Addr1:= $00;
    Addr2:= $00;
    Addr3:= $01;
    Access:= $92;
    GDOAVL_Limit3:= $CF;
    Addr4:= $00;
  end;

  { Video Segment Descriptor }
  with gdt[3] do
  begin
    Limit1:= $FF;
    Limit2:= $FF;
    Addr1:= $80;
    Addr2:= $00;
    Addr3:= $0B;
    Access:= $92;
    GDOAVL_Limit3:= $CF;
    Addr4:= $00;
  end;

end;
begin
  Track:= 0;
  Head:= 0;
  Sector:= 11;

  SetVGA;
  ShowMessage( 'MiSiHi OS Kernel Loading'#13, 14 );
  ChangeProtectMode;
end.

 

너무 오래전이라 소스 내용은 잘 모르겠지만...;; 최초 Turbo Assembler 로 작업을 하여 부트로더를 만든 후, 이를 TP 로 옮긴 것으로 기억한다. 그리고 간단한 트릭이 있는데, makebin 을 이용하여 생성된 exe 를 bin 으로 변환하는 것이다. 그리고 이것을 디스크 이미지 파일로 생성한다.

 

 

misihi.IMA
다운로드

 

FDD 에 디스크 이미지를 지정하고 부팅하면 다음과 같은 화면을 출력하게된다.

 

 

이후, 델파이의 SysInit, System 유닛을 더미로 빌드하고 특정 영역의 코드부터 커널로 취급하는 일을 진행하다 회사일이 바빠 올스톱하게되었다. 꾸준히 해왔다면 요즘 같은 때 좀 도움이 됐을 거 같긴 한데...ㅎ

 

아마, 현업에서 은퇴하고 내 나이 쉰이되면 다시 시작해보지 않을까 싶다. 바뀌게 될 부분이라면 메인 컴파일러로 Delphi 가 아닌 Free Pascal 을 사용하는 정도가 되지 않을까? ^^

 

반응형

'프로그래밍 > PC' 카테고리의 다른 글

Interface 요약 #2  (0) 2012.04.19
Interface 요약 #1  (0) 2012.04.19
GStreamer 빌드하기 - Visual Studio 2008 Express  (0) 2011.12.23
Automation Server 에서 사용할 수 있는 type  (0) 2011.05.25
Automation Server 등록/해제  (1) 2011.05.24

댓글