728x90
; haribote-ipl
; TAB=4

		ORG		0x7c00			; 메모리 안에서 로딩되는 곳

; 아래는 표준 FAT12 포맷 플로피 디스켓을 위한 내용들

		JMP		entry
		DB		0x90
		DB		"HELLOIPL"		; 부트섹터 이름. 마음대로해도 ok
		DW		512				; 1섹터 크기(바이트 단위, 512)
		DB		1				; 클러스터 크기(1로 해야됨)
		DW		1				; 예약된 섹터수 
		DB		2				; 디스크 FAT 테이블 수
		DW		224				; 루트 디렉토리 엔트리 수 (보통 224엔트리)
		DW		2880				; 디스크 총섹터수
		DW		0xf0				; 미디어 타입
		DW		9				; 하나의 FAT 테이블 섹터 수
		DW		18				; 1트랙에 몇 색터가있는지
		DW		2				; 헤드의 수
		DD		0				; 파티션 없으므로 0
		DD		2880				; 드라이브 크기 한번더씀
		DB		0, 0, 0x29			; 필요하다고함
		DD		0xffffffff			; 볼륨 시리얼 번호
		DB		"HELLO-OS  "		; 디스크 이름
		DB		"FAT12   "			; 포멧이름
		RESB	18				; 18바이트 남김

; 프로그램 본체

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

		MOV		SI,msg


; 추가된 부분

		MOV		AX,0x0820
		MOV		ES,AX
		MOV		CH,0			; 실린더 0
		MOV		DH,0			; 헤드 0
		MOV		CL,2			; 섹터 2 

		MOV		AH,0x02			; AH=0x02 :디스크 읽기
		MOV		AL,1			; 1섹터
		MOV		BX,0
		MOV		DL,0x00			; A 드라이브
		INT		0x13			; 디스크 BIOS 추출
		JC		error




fin:
		HLT						; CPU 정지 시킴
		JMP		fin				; 무한 루프

error:
		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

msg:
		DB		0x0a, 0x0a		; 줄바꿈 문자 2개
		DB		"good i e yo you good good good"
		DB		0x0a			; 줄바꿈
		DB		0

		RESB	0x7dfe-$		; 나머지칸 0채우기

		DB		0x55, 0xaa

IPL

-초기 프로그램 로더 Initial Progrm Loader

-이전에 만든 부트섹터

- 그러나 프로그램을 로드하지 않음

 

 

하리보테 OS

- 앞으로 만들 운영체제 이름

- 하리보테란? 영화에서 겉에 보이는 바위나 건물, 속으로 비어있고 가자인 것들

- 하리보테 OS 겉보기엔 OS이지만 속은 텅빈 천천히가자는 의미

 

 

 

하리보테 OS 시작하기

- 초기 512바이트는 부트섹터

- 다음 512바이트 정리하자

- 아래의 코드는 추가된 부분들

 

 

 

 

JC 명령어

- jumpy if carry

 => 캐리가 발생하면(= 캐리 플래그가 1이면) 점프하라

 

INT 0x13은 무엇일까? (AT-BIOS 의 인터럽트 문서 참고)

- 디스크로부터 읽기, 디스크에 쓰기, 섹터 검사 및 찾기

  - AH = 0x02 (읽을때)

  - AH = 0x03 (쓸떄)

  - AH = 0x04 (검사할떄)

  - AH = 0x0C (찾을떄)

  - AL = 처리할 섹터 수(연속된 섹터 처리 간으)

  - CH = 실린더 번호 & 0xFF

  - CL = 섹터 번호(bit 0-5) | (실린더 번호  & 0x300) >> 2

  - DH = 헤드 번호

  - DL = 드라이브번호

  - ES:BX = 버퍼 어드레스(검사 혹은 찾기시 사용 x)

  - 리턴값 : 

   => FLAGS.CF == 0 : 에러 없음, AH == 0

   => FLAGS.CF == 1 : 에러 있음, AH에 에러 코드(리셋 기능과 같음)

 

 

현재 코드 상의 인터럽트와 의미

- INT 0x13 번 인터럽트가 발생했을때 AH = 0x02 => 디스크 읽기 수행

- FLAGS.CF 캐리 플레그 -> 0x13 인터럽트(함수)가 수행중 에러가 발생하면 캐리 플래그 1,  에러 없으면 캐리플래그 0

 

캐리 플래그

- CPU의 상태를 나타내기 위한 레지스터 중 1개,

- 플래그 : 1비트밖에 저장하지 못하는 레지스터로. 들어 올리거나 내리는 두가지 경우밖에 존재하지 않으므로 플래그라 함

 

 

인터럽트시 필요한 값들

- CH, CL, DH, DL에 갑이 입력되어 있어야 함

- 현재 AH = 0x02로 인터럽트 발생시 디스크를 읽기 가 호출됨. 하지만 어디를 해야할지 모름

- CH 실린더 번호, CL 섹터 번호, DH 헤드 번호, DL 드라이브 번호

 

 

 

플로피 디스크 구조

- 실린더(원통) : 큰 원(0~79번까지 80개 존재)

- 헤드 (자기헤드): 집게같이 생긴거 - 읽기용 헤드(위의꺼 0번), 쓰기용 헤드(아래꺼 1번)로 2가지

- 섹터 :  실린더와 헤드를 지정하면 데이터를 쓰거나 읽을수 있으나 너무 많아 나눔.

            피자조각을 나눈 조각 같은거 1 ~ 18번까지 18개 존재. 하나의 섹터당 512바이트 저장 가능

- 플로피 디스크의 크기 = 80 x 2 x 18 x 512(바이트) = 1,440KB = 1.4MB 플로피 디스크다

 

- 아래의 그림은 1.4 mb 짜리 플로피 디스켓

https://www.alamy.com/stock-photo-floppy-disk-14mb-15840692.html

 

 

 

우리의 경우 인터럽트시 무엇을 읽을까?

- MOV CH, 0 => 실린더 번호 0번에서의

- MOV DH, 0 => 헤드 번호 0번의

- MOV CL, 2 => 2번 섹터에서

- MOV DL, 0x00 => 0번 드라이브(플로피 디스켓이 입력되는 A디스크)

=> IPL은 C0-H0-S1에 존재. 다음에는 C0-H0-S2를 읽음

 

 

 

300x250
728x90

Makefile

- 빌드 규칙을 정리한 파일

- make 명령을 주면 정해진 규칙대로 수행하여 출력 파일 생성

 

 

helloos5 구조

- 기존의 nas 파일, 부트섹터만 만든 bin파일, make.bat, 빌드를 위한 Makefile로 구성

 

Makefile 전체

 

default :
	../z_tools/make.exe 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

# 커멘드

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

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

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

 

Makefile 빌드 규칙 예제

- make -r ipl.bin

  => 명령을 입력하면 Makefile이 아래의 규칙을 수행하여 ipl.bin과 ipl.lst 출력

- ipl.bin : ipl.nas Makefile

  => ipl.bin을 빌드하기 위해 ipl.nas와 Makefile이 필요 (의존 관계 설명)

- 나머지 내용들도 이와 같이 빌드 수행

 

 

Make 명령 실행 결과

- 위 작성 규칙대로 ipl.bin과 ipl.lst가 생성됨

 

이미지도 만들자

- make -r helloos.img

 => 규칙대로 helloos.img 파일이 출력됨

 

Makefile 명령 정의하기

- 빌드 규칙으로 쉽게 빌드했으나 다 입력하기 힘듬

=> 명령(커멘드) 정의를 통해 자동화 하자

 

커맨트로 이미지 쉽게 만들기

- helloos.img를 지우고, make img 입력

=> make img 명령 규칙에 따라 helloos.img 생성

 

 

나머지 규칙

- make run : img 생성 후 실행

 * run 하기전에 bash 셀인 경우 copy 가아니라 cp로 변경해야함! 별도 경로 에러도 고치자

- make install : img 생성후 플로피디스켓에 저장

- make clean : img 만드는데 사용한 bin파일과 lst 파일 삭제

 

 

make run 결과

- qemu 상에서 잘 부팅되고 있음

300x250
728x90
; hello-os---------------------------------------------------------
; TAB=4

		ORG		0x7c00			; 메모리 안에서 로딩되는 곳

; 아래는 표준 FAT12 포맷 플로피 디스켓을 위한 내용들

		JMP		entry
		DB		0x90
		DB		"HELLOIPL"		; 부트섹터 이름. 마음대로해도 ok
		DW		512				; 1섹터 크기(바이트 단위, 512)
		DB		1				; 클러스터 크기(1로 해야됨)
		DW		1				; 예약된 섹터수 
		DB		2				; 디스크 FAT 테이블 수
		DW		224				; 루트 디렉토리 엔트리 수 (보통 224엔트리)
		DW		2880				; 디스크 총섹터수
		DW		0xf0				; 미디어 타입
		DW		9				; 하나의 FAT 테이블 섹터 수
		DW		18				; 1트랙에 몇 색터가있는지
		DW		2				; 헤드의 수
		DD		0				; 파티션 없으므로 0
		DD		2880				; 드라이브 크기 한번더씀
		DB		0, 0, 0x29			; 필요하다고함
		DD		0xffffffff			; 볼륨 시리얼 번호
		DB		"HELLO-OS  "		; 디스크 이름
		DB		"FAT12   "			; 포멧이름
		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		"good i e yo you good good good"
		DB		0x0a			; 줄바꿈
		DB		0

		RESB	0x7dfe-$		; 나머지칸 0채우기

		DB		0x55, 0xaa

; 부트섹터 이외 부분에 적을 내용들

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

 

JMP entry

- entry가 0x7c50이면 => JMP 0x7c50과 동일

- 0x7c50 번지로 점프

 

MOV SI, msg

- SI 레지스터에 msg 레이블의 주소를 할당

- msg 레이블이 0x7c74 이라면 => SI = 0x7c74

 

 

MOV AL, [SI]

- AL 레지스터에 소스인덱스 SI가 가리키는 값을 저장

 -> c언어로 표현하면, AL = *SI

 ex.  SI = 0x50이고 0x50번지에 0x01이 저장되어있음 -> AL 레지스터에 0x01이 대입됨

- 만약 MOV AL, SI 라면 => AL = SI와 동일

 ex. 위와 동일한 경우 AL 레지스터에 0x50이 대입됨

 

 

 

MOV {BYTE | WORD | DWORD}의 경우

- MOV BYTE [678], 123

 => 메모리 678번지에 123를 바이트로 기억

- MOV WORD [678], 123

 => 메모리 678번지에 123을 워드로 기억 

 

 

워드, 더블워드, 쿼드워드 공간의 차이

 

 

 

덧셈 명령 ADD

- ADD SI, 1

 => SI = SI + 1

 

 

비교 명령 CMP

- CMP AL, 0 => if (AL == 0)

- ex.

   CMP AL, 0

   JE fin

=> if (AL == 0)

     {

         goto fin;

      }

 

 

인터럽트 명령 INT

- INT 주소

ex. INT 0x10 => 0x10에 존재하는 함수를 호출(여기선 비디오 BIOS 호출 관련 함수)

 

 

컴퓨터 정지 명령 HLT

- CPU를 대기상태로 만듬 -> 외부 변화 있을시 다시 실행됨

 

 

ORG 0x7c00. 프로그램 시작점을 0x7c00으로 설정한 이유 1

- 컴퓨터는 매우 큰 메모리공간 가짐. 마음대로 시작점을 설정하면 동작 x

- 0xf0000에는 바이오스가 존재 -> 사용 불가

- 메모리맵 : 메모리의 영역을 나타내는 지도

 

 

IBM PC AT 호환 기종 메모리 맵

- 메모리 ,바이오스, 그래픽 등 관련 주소에 대한 정보

- IBM 엔지니어가 메모리 주소 지정

- 남밗님의 자료 : http://egloos.zum.com/nambaxa/v/657469

 

 

 IBM PC AT 호환기종의 메모리 맵핑

- PCI 장치 혹은 PC에 장착하는 카드를 사용할 때, 각 장치가 메모리에 맵핑되는 상태를 설명합니다.
- 0x00000000 - 0x0009ffff : RAM
- 0x000a0000 - 0x000bffff : 비디오 카드 접근 영역
- 0x000c0000 - 0x000c7fff : 비디오 BIOS
- 0x000c8000 - 0x000dffff : 각종 카드의 ROM 영역
- 0x000d0000 - 0x000dffff 영역은 대부분 비어 있다
- 0x000e0000 - 0x000effff : 확장 BIOS
- 0x000f0000 - 0x000fffff : BIOS
- 0x00100000 - 0x00efffff : RAM
- 0x00f00000 - 0x00ffffff : RAM 혹은 ISA 홀(BIOS의 설정에 의해서 결정될 수 있다)
    286의 경우는, 0x00fffff0로부터의 16바이트에 리셋트 점프 명령이 있을 수도 있다
- 0x01000000 - 메모리의 끝 : RAM
- 메모리의 끝 - 0xffffffef : PCI 장치등의 메모리 맵핑 I/O에 이용 가능한 영역
- 0xfffffff0 - 0xffffffff : 386이후에서는 여기에 리셋트 점프 명령이 있다


소프트웨어에 따른 용도 구분

- 0x00000000 - 0x000003ff : 리얼모드용 인터럽트 벡터
- 물론 IDT를 변경하면 변경할 수 있지만 기본적으로는 이 주소가 사용된다
- 0x00000300 - 0x000003ff는 BIOS용 스택
- 0x00000400 - 0x000004ff : BIOS가 사용하는 영역
- 0x00007c00 - 0x00007dff : 부트섹터가 로딩되는 주소
- 0x0009fc00 - 0x0009ffff : ACPI 영역

 

 

 

ORG 0x7c00. 프로그램 시작점을 0x7c00으로 설정한 이유 2

- 0x00007c00 ~ 0x00007dff 가 부트 섹터의 어드레스이기 때문

- 부트 섹터가 아닌 다른 곳을 시작점으로 하면 오작동함

 

 

부트 섹터만 nask로 만들기 (helloos4)

- 앞으로는 nask로 512바이트의 부트섹터만 만듬

 1. helloos.nas에서 뒷부분 제거. 이름을 ipl.nas로 변경

   ->기존의 helloo.nas의 프로그램 영역이 ipl.nas에서 제거됨

 2. asm.bat을 수정하여 실행파일 ipl.bin과 리스트 ipl.lst가 출력되도록 수정

  * 리스트 파일 : 어떤 명령이 어느 기계어로 번역되었는지 확인 가능 

수정된 asm.bat 좌측. 기존의 파일 우측
ipl.lst

 

- 나머지는 디스크 이미지 툴로 만들기

 1. makeimg.bat 작성

 2. maikeimg.bat은 ipl.bin을 부트섹터로 하여 디스크 이미지  helloos.img 생성

 

 

 

 

 

 

300x250
728x90
; hello-os---------------------------------------------------------
; TAB=4

		ORG		0x7c00			; 메모리 안에서 로딩되는 곳

; 아래는 표준 FAT12 포맷 플로피 디스켓을 위한 내용들

		JMP		entry
		DB		0x90
		DB		"HELLOIPL"		; 부트섹터 이름. 마음대로해도 ok
		DW		512				; 1섹터 크기(바이트 단위, 512)
		DB		1				; 클러스터 크기(1로 해야됨)
		DW		1				; 예약된 섹터수 
		DB		2				; 디스크 FAT 테이블 수
		DW		224				; 루트 디렉토리 엔트리 수 (보통 224엔트리)
		DW		2880				; 디스크 총섹터수
		DW		0xf0				; 미디어 타입
		DW		9				; 하나의 FAT 테이블 섹터 수
		DW		18				; 1트랙에 몇 색터가있는지
		DW		2				; 헤드의 수
		DD		0				; 파티션 없으므로 0
		DD		2880				; 드라이브 크기 한번더씀
		DB		0, 0, 0x29			; 필요하다고함
		DD		0xffffffff			; 볼륨 시리얼 번호
		DB		"HELLO-OS  "		; 디스크 이름
		DB		"FAT12   "			; 포멧이름
		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		"good i e yo you good good good"
		DB		0x0a			; 줄바꿈
		DB		0

		RESB	0x7dfe-$		; 나머지칸 0채우기

		DB		0x55, 0xaa

; 부트섹터 이외 부분에 적을 내용들

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

 어셈블리 코드를 천천히 살펴보자

 

ORG 명령

- origin

- 시작점을 NASK 어셈블러에게 알려줌  -> 0x07c00번지서 시작

 

JMP 명령

- Jump 명령. c언어의 goto와 동일하게 레이블로 이동

- 레이블 예시

   entry:,    putloop:,    fin:

- JUMP putloop -> putloop 레이블로 이동해서 문자 출력

 

 

MOV 명령어

- 대입 연산

- 프로그래밍 언어에서 = 와 동일

- 예시

 1. MOV AX, 0 => 값 0을 AX 레지스터에 대입(저장)

 2. MOV SS, AX => AX레지스터의 값을 SS 레지스터에 데입하라

 

 

 

 

 

 

 

레지스터

- CPU내 기억 장치. 변수 공간

- 예시

 AX : accumulator 누산기

 CX : Counter 가산기

 DX : 데이터

 BX : 베이스

 SP : 스택 포인터 stack poitner

 BP : 베이스 포인터 Base Pointer

 SI : 소스(읽기) 인덱스 source index

 DI : 목적지(쓰기) 인덱스 destination index

 

 

8비트 레지스터

- 16비트 레지스터 X의 의미 : AX, CX에서 X는 확장 -> 8비트에서 16비트로 확장되었기 때문

- CPU 8비트 레지스터 예시

 AL : 누산기 로

 CL : 카운터 로

 DL : 데이터 로

 BL : 베이스 로

 AH : 누산기 하이

 CH : 카운터 하이

 DH : 데이터 하이

 BL : 베이스 하이

- 16비트 레지스터는 로 공간과 하이 공간으로 구성됨 

 => 예시 : AX = AH + AL

 

32비트 레지스터

- 16비트 레지스터앞에 E가 추가

- 예시 : EAX, ECX, EDX ...

 

 

세그먼트 레지스터

- 16비트

- 종류

 ES : 엑스트라 세그먼트

 CS : 코드 세그먼트

 SS : 스택 세그먼트

 DS : 데이터 세그먼트

 FS : 엑스트라 세그먼트 2

 GS : 엑스트라 세그먼트 3

 

 

어셈블리 코드 돌려보기

- 경로 : make_os\tolset\helloos3

- 위 어셈블리어를 nask로 컴파일 후 qemu상에서 돌려보면

- 굳이에요 굳굳굳 문자열이 잘 출력되는걸 볼수 있다.

 

300x250
728x90

텍스트 에디터

- Scite 사용

 

wscite444.zip
1.87MB

 

 

 

 

 

준비하기

- tolset 안에다가 hellos3 폴더를 복붙하고

- helloos.nas를 열자

 

 

 

한글깨짐

- 이건 일본어 원문 자료에서 그대로 가져오다보니 주석들이 다깨진듯 하다..

 

 

- utf-8로 고쳐주고

 

- 불편해서 안되겠다. vscode 쓰자

 

 

다고친 결과

- 파일 열때 깨진 주석들을 다 한글로 고침

 

 

 

- 고친 결과

; hello-os---------------------------------------------------------
; TAB=4

		ORG		0x7c00			; 메모리 안에서 로딩되는 곳

; 아래는 표준 FAT12 포맷 플로피 디스켓을 위한 내용들

		JMP		entry
		DB		0x90
		DB		"HELLOIPL"		; 부트섹터 이름. 마음대로해도 ok
		DW		512				; 1섹터 크기(바이트 단위, 512)
		DB		1				; 클러스터 크기(1로 해야됨)
		DW		1				; 예약된 섹터수 
		DB		2				; 디스크 FAT 테이블 수
		DW		224				; 루트 디렉토리 엔트리 수 (보통 224엔트리)
		DW		2880				; 디스크 총섹터수
		DW		0xf0				; 미디어 타입
		DW		9				; 하나의 FAT 테이블 섹터 수
		DW		18				; 1트랙에 몇 색터가있는지
		DW		2				; 헤드의 수
		DD		0				; 파티션 없으므로 0
		DD		2880				; 드라이브 크기 한번더씀
		DB		0, 0, 0x29			; 필요하다고함
		DD		0xffffffff			; 볼륨 시리얼 번호
		DB		"HELLO-OS  "		; 디스크 이름
		DB		"FAT12   "			; 포멧이름
		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			; 줄바꿈
		DB		0

		RESB	0x7dfe-$		; 나머지칸 0채우기

		DB		0x55, 0xaa

; 부트섹터 이외 부분에 적을 내용들

		DB		0xf0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00
		RESB	4600
		DB		0xf0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00
		RESB	1469432
300x250
728x90

* 주의사항

폴더 구조를 바꾸면서 파일 내용도 일부 수정

github 내용 참고 필요

https://github.com/JeongChanDo/make_os

 

 

nask 어셈블러 명령어

- DB Data byte : 파일 값을 1바이트씩 직접 쓰는 명령어

 * 소문자 db도 ㄱㅊ

- RESB REServe Byte : 10바이트 예약

 * ex. RESB 10 - 10바이트 공간을 공백으로 예약

- 0x : 16진수

- 일반 : 10진수

 

 

 

 

어셈블러 코드 개선하기

- helloos2폴더에서 작성

 

추가된 명령어

- j : 주석 처리

- DB : 문자열도 사용가능

- DW Data Word : 데이터 워드로 2바이트 -> 16비트

- DD Data Double-word : 데이터 더블 워드로 4바이트 -> 32비트

- RESB 0xfe-$ : 0xfe부터 앞에서 쓴 바이트를 뺀 크기를 공백으로 채움

 * RESB 378  하자니 앞에 가변일수 있으므로 $ 사용

 

 

개선된 어셈블러 코드 동작 결과

- 이전에 16진수로만 작성한 어셈블러 코드랑 동일하게 동작

- 소스코드 가독성이 더좋음

300x250
728x90

어셈블러 만들기

- 이전에 바이너리로 만든 helloos.img를 어셈블러 소스 코드로 만들자(내용은 바이너리와 비슷)

- 사용 어셈블러 nask 나스크, nasm보다 최적화 성능 좋음

- hellos.nas로 저장

 

 

hellos.nas

- RESB 명령으로 공백 넘어감

- nask 어셈블러 소스코드

	DB	0xeb, 0x4e, 0x90, 0x48, 0x45, 0x4c, 0x4c, 0x4f
	DB	0x49, 0x50, 0x4c, 0x00, 0x02, 0x01, 0x01, 0x00
	DB	0x02, 0xe0, 0x00, 0x40, 0x0b, 0xf0, 0x09, 0x00
	DB	0x12, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00
	DB	0x40, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x29, 0xff
	DB	0xff, 0xff, 0xff, 0x48, 0x45, 0x4c, 0x4c, 0x4f
	DB	0x2d, 0x4f, 0x53, 0x20, 0x20, 0x20, 0x46, 0x41
	DB	0x54, 0x31, 0x32, 0x20, 0x20, 0x20, 0x00, 0x00
	RESB	16
	DB	0xb8, 0x00, 0x00, 0x8e, 0xd0, 0xbc, 0x00, 0x7c
	DB	0x8e, 0xd8, 0x8e, 0xc0, 0xbe, 0x74, 0x7c, 0x8a
	DB	0x04, 0x83, 0xc6, 0x01, 0x3c, 0x00, 0x74, 0x09
	DB	0xb4, 0x0e, 0xbb, 0x0f, 0x00, 0xcd, 0x10, 0xeb
	DB	0xee, 0xf4, 0xeb, 0xfd, 0x0a, 0x0a, 0x68, 0x65
	DB	0x6c, 0x6c, 0x6f, 0x2c, 0x20, 0x77, 0x6f, 0x72
	DB	0x6c, 0x64, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00
	RESB	368
	DB	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0xaa
	DB	0xf0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00
	RESB	4600
	DB	0xf0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00
	RESB	1469432

 

 

 

 

* 구글링하다가 깃헙 소스 찾음

- https://github.com/slankdev/os

 

 

nask 어셈블러로 어셈블

- 어셈블 수행

 

 

어셈블리어로 작성한 이미지 실행 결과

- 지난번에 만든 run.bat으로 돌리면 결과가 정상적으로 나옴

 

300x250
728x90

os만들기 - 2에서 한 모든 일들은 다 쓸모없는 짓이었다.

 

 

 

나중에 다시보니

 

지금 하는 바이너리 파일 만드는건

 

모든 바이너리 코드들을 내 마음대로가 아니라 똑같이 만들어야 부팅가능한 이미지가 만들어지더라

 

왜 계속 아무리 돌려봐도 실행이 안되나 싶었더니

 

부팅 가능한 기계어 코드를 만드는 예제 인데

 

정해진 대로 안한 채 내가 마음대로 치고

 

부팅 가능한 이미지를 만들겠다고 이것 저것 툴만 만지고 있었다.

 

 

 

 

아무튼 정해진 주소에 코드를 올바르게 입력했더니

 

무슨 뜻인지 모를 이진 코드 이미지가 일단 부팅은 가능한 상태가 되었다.

 

 

 

 

 

 

여기서 바이너리에디터로 조금만 수정하면

 

hello world가 출력된다.

 

 

 

오늘 한 내용은

 

기계어 수준으로

 

부팅 가능한 플로피 이미지를 만들고 hello, world를 출력하는 프로그램을 작성하였다.

 

 

하지만 기계어로 제어하는 만큼 한자리라도 잘못되면 원하는 결과가 안나올수 있다.

 

오늘 처럼 원인을 잘못 생각해서 삽질하는일 없도록 조심하자 ㅠㅠ

 

아래의 파일은 위 바이너리 이미지 파일

 

helloos.img
1.41MB

 

 

 

 

 

bochs에서도 잘돌아간다!

300x250
728x90

자료에서보면

 

boshs에 방금 만든 이미지를 돌리더라

 

바로 돌릴수 있는줄 알고 해봤지만

 

- 부팅가능한 이미지가 아니라고 아무것도 뜨지 않는다.

 

 

 

 

다시 잘보니 toolset으로 부팅 가능 이미지로 만들어야 된다고 한다.

 

toolset이 원래 CD에 있다고는 하는데 나는 CD가없으므로

 

소스 찾다보니 깃헙에 올라온걸 찾았다.

 

https://github.com/HariboteOS/tolsrc

 

일단 윈도우 바이너리로 빌드하긴 해야되니

 

mingw부터 깔고, 환경변수 등록하고

 

 

 

toolset 빌드 중

 

하다가 에러발생

 

gmtime_r 이 인클루드 안된것 같다.

 

 

 

찾아보니 ctime.h는 g++에 있는듯 하다

 

 

g++도 설치

 

 

 

으악 보다보니

 

 

c++이 아니라

 

내가 사용한 gcc랑 c언어 표준 이랑 맞지 않았던것 같다.

 

 

C Standards. C표준. C11, C99, C90, 등. 그리고 gcc

https://junho85.pe.kr/1026

 

 

 

 

C2X는 C18 다음 표준안인듯 하다.

 

 

 

 

일단 메이크 파일에서

 

-std=gnu2x를 추가해주고 다시 빌드를 해봤다.

 

 

 

 

 

아까 처럼 워닝은 안뜨지만

 

gmtime_r이 없으니 링킹이 안되는건 여전하다.

 

gcc 버전을 바꿔야 될수도 있겠다...

 

 

 

 

 

 

다시 검색하다보니

 

gmtime_r은 gmtime의 안전한 버전으로 susv2에 있다고 한다.

 

gcc에 susv2만 추가할 수 있으면 될것같긴한데 ...

 

 

 

일단 sus는 단일 유닉스 규격 single unix specification

 

 

 

 

도저히 안되서 msys에서 작업하려는데

 

gcc도 못찾고 있더라

 

누가 pacman -S gcc를 치면 된다길래 했더니

 

gcc가 설치된다 ..

 

 

 

 

찾아보니 pacman이 msys에서 패키지 관리 프로그램이라고 한다.

 

 

https://myshare.tistory.com/14

 

 

pacman으로 gcc 설치후 make 해보니

 

빌드 성공 ..

 

지금까지 뭘한걸가 ㅠㅜㅜㅜ

 

 

make install로 바이너리 정리해주고

 

 

윈도우 실행파일로 빌드 완료 ㅎㅎ

 

 

 

 

추가적인 유용한 도구들 설치

- 아직은 gcc만 설치되어있으므로

 

http://blog.tcltk.co.kr/?p=4002

 

 

imgtol을 써야되는데

 

자꾸 cpp0가 없다고 빌드가 안된다.

 

 

 

 

pacman -S mingw-w64-x86_64-yaml-cpp0.3 설치

 

 

 

그래도 안된다..

 

 

 

 

 

 

 

 

 

 

계속 해매다가

 

어느 중국인이 tolset을 깃헙에 올린걸 찾았다..

 

https://github.com/fakefish/OSASK

 

 

결국에는 이짓을 할 필요가 없었어..

 

 

 

 

다시 해서

 

run.bat 파일이랑 아까 만든 이미지 파일을 놓고

 

 

 

 

run.bat을 돌리면

 

qemu가 돌아가는데 부팅불가능한 이미지라고 뜬다.

 

 

 

install.bat도 만들어서 돌려보면...

 

16비트라고 안돌아간다 OTL

 

 

 

 

아까 구한 imgtol 소스에서

 

빌드해야될것 같다..

 

그런데 아까 cpp0가 없다고 빌드가 안됬었는데 

 

 

 

 

 

z_tools에 있던 cpp0를 가져와 써보자..

 

 

 

여전히 cpp0를 못찾는다고 하니

 

일단 cpp0.exe로 고쳐주자

 

./cpp0.exe -v 로 찍어보니

 

엄청 오래된듯 하다

 

메이크 파일을 고치고

 

 

빌드했더니

 

cpp0는 잘 넘어갔는데 이번에는 aska가 문제다..

 

 

 

메이크 파일에서 필요하단건 다 복붙하자

 

그런데 bim2bin3이 안보인다..

 

 

 

일단 찾은것 대로만 메이크파일 고쳐주고 다시 실행해보면..

 

 

역시 잘되다가 bim2bin3이 문제다

 

아쉬운 대로 ztools에 bim2bin.exe로 바꿔서 한번 돌려보면

 

 

역시나 안된다.

 

 

 

실행 파일명만 바꾸고 옵션을 그대로 둔 상태에서 빌드해봤더니

 

성공

드디여 삽질해서

 

imgtol.com를 만들었다.

 

 

실행했더니 포맷 에러 발생

 

 

 

생각해보니 빌드 문제가 아니라 도스 명령을 64비트 운영체제에서 돌리려한게 문제였다.

 

 

검색해보니 기능 추가하면 돌릴수 있다고 하내

 

 

https://www.groovypost.com/howto/enable-16-bit-application-support-windows-10/

근데 난 없음

 

 

 

어쩔수 없이 도스박스에서 돌려보자

 

 

반가운 도스박스

 

 

 

 

 

일단 돌아가기는 하지만

 

없는 install.bat에 없는 a드라이브에다가 이미지를 쓴다고 했으니

 

드라이버 에러가 난다

 

 

 

아까 imtol 폴더에 readme를 봐야할것같은데

 

한글 윈도우라 다깨진다.

 

일단 볼수 있는 부분으로 이해해보면

 

imgtol.com w a: helloos.img는

 

a: 드라이브로 이미지를 올린다고 볼수 있을것같다

 

 

삽질한 결과 문제는 이게아니었다..

300x250
728x90

 

우선 C언어, 어셈블러가 아닌

바이너리 에디터로 시작

 

바이너리 에디터

- 2진수 편집기로 바이너리 실행파일을 수정할수 있음.

- 사용할 프로그램은 bz162

 

 

Bz162.zip
0.05MB

 

 

 

 

BZ162 바이너리 에디터 화면

- 좌측 000000은 메모리 주소

- 중간의 0 ~ F는 000000, 000001, 000002, ..., 00000F 번지에 각각 32비트 값저장

- 우측의 01234..EF는 ASCII코드상 표현

 

 

바이너리 에디터에 입력 예시

- 다음과 같이 문자열들을 입력할때 해당 문자의 아스키코드 16진수 값이 중앙의 번지에 저장되는 모습을 볼 수 있음.

* 문자 'h'는 10진수로 104 -> 16진수로 0x68로 바이너리 에디터의 000000번지에 올바르게 값이 저장됨.

 

 

- 아래는 아스키 코드 테이블 

아스키코드 테이블

 

 

 

hello.img로 저장

300x250

+ Recent posts