오늘 포스팅은 작업 일지에 가까울 거 같습니다. 아무래도 제게 주어진 시간이 많지 않은 관계로 최대한 빨리 작업을 진행하고 있거든요. 말 그대로 닥치는대로 하고있습니다. ^^
정석대로라면 부트로더를 통해 보호 모드로 진입하고 이후, 인터럽트, 디바이스, 태스크 스위칭, 페이징 등 거의 정해진 절차처럼 커널 개발을 하게 됩니다. 수많은 OS 개발자들이 해왔던 일이고 저도 그 중 한명이 되는 겁니다. 하지만 기왕지사 조금 무리를 하며 일을 진행하는 것인만큼 뭔가 의미가 있어야하지 않을까란 생각이 들었습니다. 즉, 이 일을 해야하는 이유 혹은 가치를 정할 필요가 생겼습니다.(코딩을 하며 멀티 태스킹으로 고민했습니다. ㅋㅋ)
유산의 발굴
2년전 파스칼과 관련한 글을 포스팅한 적이 있습니다.
2012/09/07 - [프로그래밍/주저리주저리] - 파스칼(Pascal) 연서(戀書) - 1 - before 1980
2012/09/11 - [프로그래밍/주저리주저리] - 파스칼(Pascal) 연서(戀書) - 2 - after 1980, by Apple
2012/09/11 - [프로그래밍/주저리주저리] - 파스칼(Pascal) 연서(戀書) - 3 - after 1980, by Hejlsberg
"유산"에 대해 알고 싶으시다면 상기 포스팅 중 1편만 보셔도 됩니다.
현재 OS 개발은 프로젝트명 미시히(MiSiHi)로 진행하고 있습니다. 막내 딸 혹은 셋째 딸아이를 가리키는 순우리말입니다. 과거 제가 취미로 판타지 소설을 썼을 때 여주인공 이름이기도 합니다. ^^;;;;
당분간은 OS 개발을 위한 기술적 구현 검토 단계로 마구잡이식 개발이 진행될 겁니다. 그리고 자료가 구축된 후, 정해둔 컨셉에 맞춰 아키텍처를 잡아 정식 개발을 할 계획(과연...)입니다. 하지만 꼭 실현하고 싶은 기능은 어느 정도 정해져 있습니다.
- 어플리케이션 개발환경으로 FPC 및 라자루스 지원
- OS 에서 파스칼 RTL 기본 지원(다른 놈들은 런타임 라이브러리가 필요할 지도... 알게 뭐야.)
- p-System 지원(마땅한 이름이 없어 그대로 썼지만 개선 후 탑재할 겁니다. OS 에 통합된 VM 이라고 보시면 됩니다.)
- 객체지향 OS
특별히 범용 OS 로 개발할 생각은 없는 터라 최종 결과물은 아주 개성이 강한 놈이 될 수도 있습니다. 아무튼 상기 계획을 실현하기 위해서 가장 중요한 키 역할을 하는 놈은 FPC 가 됩니다. 하여, FPC 의 RTL 을 건드리는 작업을 해보았습니다.
닥치고 FPC RTL(Linux, i386)을 커널에 집어넣어 버리자.
(그외 참고: 2014/04/10 - [프로그래밍/언어 - Pascal] - FPC 2.6 지원 CPU 및 OS)
현재, GRUB 으로 부팅할 수 있게되었지만 커널은 말 그대로 깡통인 상태... resource manager 로서의 본연의 임무와 상관없이 앞으로의 목표를 위해 RTL 을 막무가내로 올려보기로 마음 먹었습니다. 후반부 작업을 미리 땡겨 간을 보는 거죠.
System 유닛을 빌드하기 위하여 디렉토리를 구성하였습니다. FPC 소스 중 rtl/linux(이하 서브디렉토리), rtl/i386, rtl/inc, rtl/unix 를 복사하였습니다.
사실, 윈도우즈랑 유사한 형태(NT 소스가 돌아 다니더라구요. ㅋㅋ)로 진행할 생각도 있었지만... 가장 빠르고 안전한 진행을 위하여 리눅스 진영의 자원을 사용하기로 마음 먹었습니다.
linux 디렉토리에 kernel.pas 를 다음과 같이 작성하고 linux 디렉토리에서 컴파일 합니다.
### delphi
unit kernel;
interface
procedure kernelmain; stdcall;
implementation
type
TVGAText = packed record
CH: Char;
Attr: Byte;
end;
TBufferScreen = array[1..25, 1..80] of TVGAText;
procedure kernelmain; stdcall; [public, alias: 'kernelmain'];
var
Screen: TBufferScreen absolute $B8000;
ScreenSave: TBufferScreen;
Buffer: array[1..80] of Byte;
x, y, i: Integer;
begin
ScreenSave := Screen;
for y := 1 to 25 do
begin
Screen[y,40].CH := ' ';
Screen[y,41].CH := ' ';
end;
for x := 40 downto 1 do
begin
for i := 1 to 25 do
begin
Move(Screen[i,2], Buffer, 78);
Move(Buffer, Screen[i,1], 78);
Move(Screen[i,41], Buffer, 78);
Move(Buffer, Screen[i,42], 78);
end;
end;
end;
end.
뭐하는 소스일까요? 후후~ 뒤에 알려드리겠습니다. 아무튼 System 의 Move 함수를 사용하고 있습니다. ^^
ppcross386 -Tlinux -b -Fi../inc -Fi../i386 -Fi../unix -Fi./i386 -FE. -di386 kernel.pas
정상적으로 컴파일하면, system.o 와 kernel.o 파일이 생성됩니다. 이것을 가지고 링킹 작업을 합니다.
ld -m elf_i386 --gc-sections -s -Tlinker.script -o kernel.bin stub.o kernel.o system.o
여기서 에러들이 주루룩 나오더군요. 하여 스타트업 코드를 참고하여 stub.asm 을 고쳐야했습니다.(이건 그냥 아무 생각없이 두들겨 넣은겁니다. 되는지 확인만 하면 되니까요.)
[bits 32]
; header flag
MULTIBOOT_MODULE_ALIGN equ 1<<0
MULTIBOOT_MEMORY_MAP equ 1<<1
MULTIBOOT_GRAPHICS_FIELDS equ 1<<2
MULTIBOOT_ADDRESS_FIELDS equ 1<<16
; header defines
MULTIBOOT_HEADER_MAGIC equ 0x1BADB002
MULTIBOOT_HEADER_FLAGS equ MULTIBOOT_MODULE_ALIGN | MULTIBOOT_MEMORY_MAP
MULTIBOOT_HEADER_CHECKSUM equ -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)
; kernel stack size
KERNEL_STACKSIZE equ 0x4000
; for fpc rtl
section .text
global _start
global _haltproc
global __fpc_valgrind
global INITFINAL
global FPC_THREADVARTABLES
global __stkptr
global operatingsystem_parameter_envp
global operatingsystem_parameter_argc
global operatingsystem_parameter_argv
extern kernelmain
; multiboot header
align 4
dd MULTIBOOT_HEADER_MAGIC
dd MULTIBOOT_HEADER_FLAGS
dd MULTIBOOT_HEADER_CHECKSUM
; entry point
_start:
mov esp, KERNEL_STACK+KERNEL_STACKSIZE ; create kernel
push eax
push ebx
call kernelmain
_haltproc:
cli
hlt
section .data
__fpc_valgrind: db 0
section .data
align 8
INITFINAL:
dw 2, 0
; dq INIT$_SYSTEM
; dq 0
; dq INIT$_LNFODWRF
; dq FINALIZE$_LNFODWRF
section .data
align 8
FPC_THREADVARTABLES:
dw 2
; dq THREADVARLIST_SYSTEM
; dq THREADVARLIST_STRINGS
; dq THREADVARLIST_EXEINFO
; dq THREADVARLIST_LNFODWRF
; dq THREADVARLIST_P$PROJECT1
section .bss
__stkptr: resb 4
operatingsystem_parameter_envp: resb 12
operatingsystem_parameter_argc equ operatingsystem_parameter_envp-8
operatingsystem_parameter_argv equ operatingsystem_parameter_envp-4
___fpc_threadvar_offset: resb 4
; kernel stack
;align 32
KERNEL_STACK: resb KERNEL_STACKSIZE
FPC 의 스타트업 소스들 확장자가 .S 인데요. 이게 GAS(GNU Assembler)의 소스 파일 확장자더군요. NASM(Netwide Assembler) 을 사용(간신히 검색하며 보는 정도?)하고 있던 터라 이 녀석들 구문을 살펴봤는데... 멘붕이 왔습니다. NASM 은 Intel 구문이고 GAS 는 AT&T 구문이더군요. 그러니까 어셈이긴 어셈인데 문법이 다르다는거죠.ㅋㅋㅋㅋ 생각보다 많이 다릅니다. 때려칠까 잠시 망설였지만... 구굴신께서 도와주시더군요.
왜나라 언어는 번역이 잘 되는 편이라 수월하게 귀가하는 지하철 안에서 탐독하고 오늘 오전 stub.asm 을 수정하고 적용해 보았습니다. 그리고 그 결과물...
과거 90년대 이야기(Iyagi)를 오마쥬합니다. ^^ㅋ
'프로그래밍 > PC' 카테고리의 다른 글
FPC 로 OS 커널 만들기... - 3 - (0) | 2014.04.30 |
---|---|
FPC 오브젝트(object) 형 (0) | 2014.04.17 |
FPC 2.6 지원 CPU 및 OS (0) | 2014.04.10 |
FPC 로 OS 커널 만들기... - 1 - (1) | 2014.04.09 |
CodeTyphon 으로 FPC 크로스 컴파일러 생성하기... (0) | 2014.04.08 |
댓글