플로피 디스크에서 512바이트까지가 부트섹터였는데

nask로 부트섹터 만들고, 나머지는 이미지 툴로 만듬

 

 

기존에 어셈블 코드

asm.bat

..\z_tools\nask.exe helloos.nas helloos.img

 

을 bin과 lst (기계어로 번역되는 명령 목록) 출력되도록 수정

..\z_tools\nask.exe ipl.nas ipl.bin ipl.lst

 

making.bat

ipl.bin으로 helloos.img 만듬

edimg.exe로 ipl.bin 먼저 놓고 helloos.img 이미지 출력

..\z_tools\edimg.exe   imgin:../z_tools/fdimg0at.tek   wbinimg src:ipl.bin len:512 from:0 to:0   imgout:helloos.img

 

 

 

ipl.bin에는 부트섹터내용만 들어가므로

helloos3의 맨 끝에 부트섹터외는 제외되어있음.

 

기존 helloos3 ipl.nas
;hello-os
;TAB

ORG 0x7c00      ;메모리내 어디에 로딩되는지

JMP entry
DB  0x90

DB "HELLOIPL" ; boot sector이름을 자유롭게 써도 좋다(8바이트)
DW 512 ; 1섹터 크기(512로 해야 함)
DB 1 ; 클러스터 크기(1섹터로 해야 함)
DW 1 ; FAT가 어디에서 시작될까(보통 1섹터째부터)
DB 2 ; FAT 개수(2로 해야 함)
DW 224 ; 루트 디렉토리 영역의 크기(보통 224엔트리로 해야 한다)
DW 2880 ; 드라이브 크기(2880섹터로 해야 함)
DB 0xf0 ; 미디어 타입(0xf0로 해야 함)
DW 9 ; FAT영역 길이(9섹터로 해야 함)
DW 18 ; 1트럭에 몇 개의 섹터가 있을까(18로 해야 함)
DW 2 ; 헤드 수(2로 해야 함)
DD 0 ; 파티션을 사용하지 않기 때문에 여기는 반드시 0
DD 2880 ; 드라이브 크기를 한번 더 write
DB 0,0,0x29 ; 잘 모르지만 이 값으로 해 두면 좋은 것 같다
DD 0xffffffff ; 아마, 볼륨 시리얼 번호
DB "HELLO-OS   " ; 디스크 이름(11바이트)
DB "FAT12   " ; 포맷 이름(8바이트)
RESB 18 ; 우선 18바이트를 비어 둔다

;프로그램 본체

entry:
    MOV AX, 0      ;레지스터 초기화
    MOV SS,AX
    MOV SP,0x7c00
    MOV DS,AX
    MOV ES,AX

    MOV SI,msg

putloop:
    MOV AL,[SI]
    ADD SI,1        ;si에 1더함
    CMP AL,0
    JE  fin
    MOV AH,0x0e     ;한문자 표시기능
    MOV BX,15       ;컬러코드
    INT 0x10        ;비디오BIOS호출
    JMP putloop

fin:
    HLT             ;cpu정지
    JMP fin         ;무한루프

msg:
    DB  0x0a, 0x0a  ;줄바꿈문자2개
    DB  "hello, world"
    DB  0x0a        ;줄바꿈문자2개
    DB  0

    RESB 0x7dfe-$   ;0x7dfe까지 0x00으로 채우기
    DB  0x55, 0xaa

; boot sector 이외부분 기술

DB      0xf0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00
RESB    4600
DB      0xf0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00
RESB    1469432
; hello-os
; TAB=4

ORG 0x7c00 ; 이 프로그램이 어디에 read되는가

; 이하는 표준적인 FAT12 포맷 플로피 디스크를 위한 기술

JMP entry
DB 0x90
DB "HELLOIPL" ; boot sector이름을 자유롭게 써도 좋다(8바이트)
DW 512 ; 1섹터 크기(512로 해야 함)
DB 1 ; 클러스터 크기(1섹터로 해야 함)
DW 1 ; FAT가 어디에서 시작될까(보통은 1섹터째부터)
DB 2 ; FAT 개수(2로 해야 함)
DW 224 ; 루트 디렉토리 영역의 크기(보통은 224엔트리로 한다)
DW 2880 ; 드라이브 크기(2880섹터로 해야 함)
DB 0xf0 ; 미디어 타입(0xf0로 해야 함)
DW 9 ; FAT영역의 길이(9섹터로 해야 함)
DW 18 ; 1트럭에 몇 개의 섹터가 있을까(18로 해야 함)
DW 2 ; 헤드 수(2로 해야 함)
DD 0 ; 파티션을 사용하지 않기 때문에 여기는 반드시 0
DD 2880 ; 드라이브 크기를 한번 더 write
DB 0,0,0x29 ; 잘 모르지만 이 값으로 해 두면 좋은 것 같다
DD 0xffffffff ; 아마, 볼륨 시리얼 번호
DB "HELLO-OS   " ; 디스크 이름(11바이트)
DB "FAT12   " ; 포맷 이름(8바이트)
RESB 18 ; 우선 18바이트를 비어 둔다

; 프로그램 본체

entry:
MOV AX, 0 ; 레지스터 초기화
MOV SS,AX
MOV SP,0x7c00
MOV DS,AX
MOV ES,AX

MOV SI,msg
putloop:
MOV AL,[SI]
ADD SI, 1 ; SI에 1을 더한다
CMP AL,0
JE fin
MOV AH, 0x0e ; 한 글자 표시 Function
MOV BX, 15 ; 칼라 코드
INT 0x10 ; 비디오 BIOS 호출
JMP putloop
fin:
HLT ; 무엇인가 있을 때까지 CPU를 정지시킨다
JMP fin ; Endless Loop

msg:
DB 0x0a, 0x0a ; 개행을 2개
DB "hello, world"
DB 0x0a ; 개행
DB 0

RESB 0x7dfe-$ ; 0x7dfe까지를 0x00로 채우는 명령

DB 0x55, 0xaa 

 

 

 

 

부트섹터 이외부분이 제거되어있는데 왜 정상동작하는지는 모르겠다.

거의 0으로 채우는거긴했는데

생각해보니 msg 맨 뒷부분에 0x7fde까지 0으로 채우고 마지막에 0x55,0xaa를 넣어놧구나

512바이트 맨 마지막에 0x55,0xaa가 있으면 부팅가능 디스크로 판단했다고 정리했었다.

 

 

 

메이크파일 만들기

Makefile

# 파일 생성 규칙
ipl.bin : ipl.nas Makefile
	..\z_tools\nask.exe ipl.nas ipl.bin ipl.lst

helloos.img : ipl.bin Makefile
	..\z_tools\edimg.exe	imgin:..\z_tools\fdimg0at.tek \
	wbinimg src:ipl.bin len:512 from:0 to:0 imgout:helloos.img

 

make -r helloos.img 로 

bin과 lst 생성 후 img까지 생성

 

 

 

 

 

make file 개선

make run만 해주면

img 만들고 실행

소스만 남기도록 비우는 코드도 추가

# 파일 생성 규칙
ipl.bin : ipl.nas Makefile
	..\z_tools\nask.exe ipl.nas ipl.bin ipl.lst

helloos.img : ipl.bin Makefile
	..\z_tools\edimg.exe	imgin:..\z_tools\fdimg0at.tek \
	wbinimg src:ipl.bin len:512 from:0 to:0 imgout:helloos.img


img :
	..\z_tools\make.exe -r helloos.img


asm:
	..\z_tools\make.exe -r ipl.bin

run :
	..\z_tools/make.exe img
	copy helloos.img ..\z_tools\qemu\fdimage0.bin
	..\z_tools\make.exe -C ..\z_tools\qemu

install :
	..\z_tools\make.exe img
	..\z_tools\imgtol.com w a: helloos.img

clean :
	-del ipl.bin
	-del ipl.lst

src_only :
	..\z_tools\make.exe clean
	-del helloos.img

 

 

 

day02.zip
0.00MB

 

 

이번에 사용할 helloos3 이미지 어셈블리파일

 

;hello-os
;TAB

ORG 0x7c00      ;메모리내 어디에 로딩되는지

JMP entry
DB  0x90

DB		"HELLOIPL"		; boot sector이름을 자유롭게 써도 좋다(8바이트)
DW		512			; 1섹터 크기(512로 해야 함)
DB		1			; 클러스터 크기(1섹터로 해야 함)
DW		1			; FAT가 어디에서 시작될까(보통 1섹터째부터)
DB		2			; FAT 개수(2로 해야 함)
DW		224			; 루트 디렉토리 영역의 크기(보통 224엔트리로 해야 한다)
DW		2880			; 드라이브 크기(2880섹터로 해야 함)
DB		0xf0			; 미디어 타입(0xf0로 해야 함)
DW		9			; FAT영역 길이(9섹터로 해야 함)
DW		18			; 1트럭에 몇 개의 섹터가 있을까(18로 해야 함)
DW		2			; 헤드 수(2로 해야 함)
DD		0			; 파티션을 사용하지 않기 때문에 여기는 반드시 0
DD		2880			; 드라이브 크기를 한번 더 write
DB		0,0,0x29		; 잘 모르지만 이 값으로 해 두면 좋은 것 같다
DD		0xffffffff		; 아마, 볼륨 시리얼 번호
DB		"HELLO-OS   "		; 디스크 이름(11바이트)
DB		"FAT12   "		; 포맷 이름(8바이트)
RESB	18				; 우선 18바이트를 비어 둔다

;프로그램 본체

entry:
    MOV AX, 0      ;레지스터 초기화
    MOV SS,AX
    MOV SP,0x7c00
    MOV DS,AX
    MOV ES,AX

    MOV SI,msg

putloop:
    MOV AL,[SI]
    ADD SI,1        ;si에 1더함
    CMP AL,0
    JE  fin
    MOV AH,0x0e     ;한문자 표시기능
    MOV BX,15       ;컬러코드
    INT 0x10        ;비디오BIOS호출
    JMP putloop

fin:
    HLT             ;cpu정지
    JMP fin         ;무한루프

msg:
    DB  0x0a, 0x0a  ;줄바꿈문자2개
    DB  "hello, world"
    DB  0x0a        ;줄바꿈문자2개
    DB  0

    RESB 0x7dfe-$   ;0x7dfe까지 0x00으로 채우기
    DB  0x55, 0xaa

; boot sector 이외부분 기술

DB      0xf0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00
RESB    4600
DB      0xf0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00
RESB    1469432

 

 

실행결과

 

 

 

어셈블리 정리

ORG : 여기부터 프로그램 시작점, 여기 기준으로 로드됨

JMP : goto

entry : 레이블 선언

MOV AX,0 : AX에 0 대입

 

16비트 레지스터들

AX(누산기), CX(카운터), DX(데이터), BX(베이스), SP(스텍포인터), BP(베이스 포인터), SI(소스인덱스), DI(목적인덱스)

 

세그먼트 레지스터들

ES 엑스트라 세그먼트, CS 코드 세그먼트, SS 스택세그먼트, DS 데이터세그먼트

 

 

ORG와 레이블 이해

ORG로 0x7c00에서 시작

entry는 0x7c50

msg는 0x7c74

MOV SI, msg => SI 소스인덱스 레지스터에 0x7c74 대입

 

 

[]이해하기

MOV WORD [678], 123 : 678, 679번지에 123 입력(리틀엔디언식)

데이터크기 [번지]

ex : BYTE [SI], WORD[BX], SI에 987이 있을떄 : BYTE[987] == BYTE[SI]

 

MOV AL, [SI] 이해하기

MOV AL, BYTE[SI]에서 데이터크기 BYTE 생략(AL은 8비트 레지스터이므로 크기 생략가능)

MOV AL, [SI] : SI번지의 1바이트를 AL로 대입하라

 

ADD 연산

ADD SI, 1 : SI = SI + 1

 

CMP 비교 연산

CMP AL, 0

JE fin 

AL == 0 이면 fin으로 가라

 

INT

- 인터럽트

- INT 주소 : 주소 함수 호출

- INT 0x10 : 16번 비디오제어 함수 호출

 

BIOS 문자 표시 적기

- AH = 0x0e;

- AL = 캐릭터 코드

- BH = 컬러코드

- 리턴 : 없음

 

putloop 파트와 같이 보기

- AL 누산기LOW에 SI 소스인덱스 레지스터 번지 값 대입

- SI = SI +1

- 누산기 LOW가 0이면 fin으로

- MOV AH, 0x0e로 문자 표 시설정

- MOV BX,15로 컬러 설정

putloop:
    MOV AL,[SI]
    ADD SI,1        ;si에 1더함
    CMP AL,0
    JE  fin
    MOV AH,0x0e     ;한문자 표시기능
    MOV BX,15       ;컬러코드
    INT 0x10        ;비디오BIOS호출
    JMP putloop

 

 

 

helloos2에서 DB로 작성한 어셈블리 코드가

좌측과 같이 고쳐졌는데

putloop 부분이 잘 이해되지 않는다.

 

SI 소스 인덱스 레지스터에다가 msg 레이블 넣고

SI주소값을 AL에다 대입

SI 다음 주소값을 AL에다 대입

계속반복

msg 마지막엔 db 0가 있으므로

putloop CMP AL,0이 true가 되는 때가 온다.

 

 

아 JMP msg가 아니라

MOV SI, msg라 

entry: 레이블 다음에 그대로 putloop에 진행한듯보인다.

 

helloos3 helloos2

 

 

 

 

 

 

이전 글에서 내가 무엇을 했느냐,,,

전에 쓴 글을보면서 

헥스에디터로 이미지파일 만들고 qemu로 돌리기까지 했었다.

 

책 설명이 제대로 안되있는데 내가 어떻게 이걸했을까 생각하다보니 한빛미디어 자료실에 

올라와있는 자료를 보고 했었던것같다

책 링크 걸어둔다.

 

https://m.hanbit.co.kr/store/books/book_view.html?p_code=B9833754652

 

OS 구조와 원리: OS 개발 30일 프로젝트

저자가 수년 동안 개발하여 완성한 OS를 독자와 함께 30일 프로젝트로 함께 만들어가는 내용이다. OS는 플로피디스크로도 구동할 수 있고 우리가 사용하고 있는 윈도우 XP와 같은 OS에서 에뮬레이

m.hanbit.co.kr

https://dw.hanbit.co.kr/exam/1482/

 

Index of /exam/1482

 

dw.hanbit.co.kr

 

 

아무튼 다음으로 할일은 어셈블리를 쓰려고한다.

헥스에디터대신 텍스트에디터로 만들고

nasm 대신 저자가 만든 nask로 어셈블하면 이전처럼 쓸수있다고한다.

 

오랜만에 인성훈련을 위해 어셈블리 그대로 쓰고

(이전 글 헥스 에디터 사진과 같이 보면 내용 동일함)

 

이미지 파일로 빌드

 

 

 

 

방금 nask로 빌드한 이미지가 정상적으로 실행된걸 확인했다!

 

 

뜻정리하면

DB : data byte 1바이트 쓰기

RESB : reserve byte 숫자만큼 0x00으로 채우기

 

 

 

어셈블리 코드 개선 결과

; 는 주석

DW : data word 워드로 18비트, 2바이트

DD : data double word 더블 워드로 4바이트

 

 

 

 

 

추가 용어 정리

FAT12 포맷 : 플로피 디스크 포멧 형식

부트섹터 

 - 플로피디스크 처음섹터, 플로피는 512바이트씩 읽음

 - 플로피는 1,440kb로 512바이트로 나누면 2880섹터로 구성

 * 부팅가능한지 보기위해 첫 섹터의 맨뒤 2바이트를 봄. 마지막이 55 AA가 아니면 부팅할수 없다고 판단.

 =>이게 무슨소린가 싶어서 헥스에디터로보니 첫 섹터 512바이트 맨 끝부분에 55 AA가 들어가있음

IPL : initial program loader 초기 프로그램 읽기 장치, 보통 OS 로드하기위한 프로그램 위치

부트 : 부트스트랩의 약어, 자신의 힘으로 이룬다는 의미

+ Recent posts