- FAT32

MBR에 기록된 0x10000 위치를 헥사뷰어로 보니 뭔가 Windows 7에서 포맷하면서 써 놨다. 부트레코드 인가 보다. 음. 내가 알 수 없는 부분이라 불안하다. Windows 7 에서 만든 MBR 과 이 코드를 검색해 봐야 겠다. 있을진 모른겠다.


http://thestarman.pcministry.com/asm/mbr/W7MBR.htm

http://thestarman.pcministry.com/asm/mbr/W7VBR.htm


이 사이트에 MBR과 VBR(Volume Boot Record), BPB(Bios Parameter Block) 이라고 하는 0x10000 부트레코드 코드가 다 있다. 오! 역시 인터넷은 정보의 바다다!! 만쉐!!


에고.. 영어라 모르겠다. VBR 같은 경우 NTFS로 쏼라 쏼라 한다. 난 FAT32인데?? 음…이 사이트 기웃 거리다가 FAT32 찾았다!!

http://thestarman.pcministry.com/asm/mbr/ntFAT32BR.htm


내 부트레코드랑 틀리다. 참고만 해야 겠다. 대충 통빡으로 보면 앞 3자리는 jump 코드란다. 그 다음은 BPB 영역(http://thestarman.pcministry.com/asm/mbr/MSWIN41.htm#BPB)이라고 해서 클릭해 보니… 와우 이건 모냐???


FAT32 정보네~~ 아고 FAT32 정보가 어디 있나 했더니 부트로더랑 FAT32 정보가 포함되어 있네? 흠…공부해야겠다.

우선 복습하는 차원에서 MBR의 파티션 정보는 다음과 같다.



저번에 포스팅 했던 내용과 같다. 그리고 FAT32 구조는.



위와 같다. 위 그림에서 Volume ID 이 부분이 0x10000 위치의 부트코드가 있는 위치이고 그 다음이 Reserved Sector, FAT#1, FAT#2, Files & 디렉토리가 일련의 순서대로 구성되어 있다. 부트로더와 FAT#1 사이에는 Reserved Sector가 존재한다. 왜 들어가 있는지 모르겠다. 그리고 FAT#1 과 FAT#2가 있는데 파일이 하드디스크의 어느 부분에 저장되어 있는지 위치를 기록하는 공간(Data영역에서 어느 위치)이다. 두 개나? 있는데 하나는 백업용이란다. FAT#1이 지워졌을 때 복구 하기 위해 있다고 한다.  Data 영역(파일과 디렉토리) 영역에는 파일 목록과 실제 파일 데이터가 기록된다.

파일이 FAT32에서 어떻게 읽고 쓰는지는 요거 BPB 라는 놈 분석해 보고 알아보자. (아 ..하기 싫어..)



잊어 버릴 것 같아서 직접 표로 작성했다.

부트로더 0x03부터 0x59 까지 FAT 정보가 들어갔다. FAT12/16/32가 서로 유사하다고 한다. 뭐 난 FAT32 만 할꺼니 딴 건 신경 안 쓰기로 했다.


모르는 용어가 나온다. 나머지야 다 유추해 볼만 한데 클러스트 라는 용어는 생소한다.


PC의 저장기술 측면에서의 클러스터는 하드디스크 위에 파일을 저장하는 논리적 단위이며, 컴퓨터의 운영체계에 의해 관리된다.
파일이 하드디스크에 저장되면 적어도 하나 이상의 클러스터를 차지하게 되며, 아주 커다란 파일인 경우 여러 개의 클러스터에 걸쳐 저장되는 수도 있다. 그러나, 비록 하나의 파일이 여러 개의 클러스터에 나뉘어 있다고 해도, 이 클러스터들이 항상 연속되어 있어야만 하는 것은 아니며, 하드디스크의 이곳 저곳에 흩어져 있는 것도 가능하다. 이런 경우 하나의 파일에 연관된 여러 개의 클러스터들의 위치는 하드디스크의 파일 배치표(FAT)에 관리되므로, 사용자의 입장에서는 파일이 어떤 클러스터에 저장되어 있는지, 혹은 나뉘어 저장되어 있는지 아닌지 등에 대해 전혀 알 필요가 없으며, 그저 원하는 파일을 읽고자 하면 파일 내용 전체가 읽혀진다.


http://www.terms.co.kr/cluster.htm 에 이렇게 쓰여져 있다. 내용이 어렵고 부족하다. 좀더 검색 질 좀 해야겠다.

음.. 대충 검색해서 이해한 바로는..


파일을 디스크에 쓸 때 클러스터 단위로 파일을 쪼개고, 그걸 클러스터 단위로 저장하나 보다. 각 클러스터는 연속적으로 저장 될 수 있고 여기 저기 흩어질 수 있다고 한다. 클러스터는 섹터들이 모여서 구성된다고 한다. . 그럼 왜 저장 단위를 클러스터 단위로 묶는 것일 까??? 흐… 메모리 생성, 삭제를 생각해 보면 되겠다… 단.편.화! 아니면 용량이 큰 디스크 일 경우 섹터로 할 경우, 4바이트를 벗어날 경우가 있어서 그런가?? 흠. 뭐 다른 이유가 있을 지도 모르겠지만, 아무튼 클러스터가 이런 거란다.

BPB구조를 표로 다시 작성해봤다.


위치

구분

설명

0x00

Jump Boot Code 0x03부터 0x59까지 FAT32 정보가 들어가기 때문에 그 위치를 건너 코드를 호출한다.

0x03

OEM Name OEM Name이라는데 그냥 8바이트 문자열.

0x0B

섹터 당 바이트 1 섹터에 몇 바이트를 저장 하는지에 대한 정보. 보통 512 바이트이지만 뭐 다를 수도 있나 보다.

0x0D

섹터 당 클러스터 클러스터 하나에 섹터 몇 개가 묶이는지에 대한 정보.

0x0E

예약 영역 섹터 파티션 시작 위치부터 FAT#1 까지 위치까지의 섹터 수.

0x10

FAT 수 FAT 테이블 수.

0x11

최대 루트 엔트리 수 루트 엔트리 수. 그냥 0 이란다.

0x13

FAT16 총 섹터 FAT16 파일 시스템 일 경우, FAT16의 총 섹터 수.

0x15

장치 타입 플로피 디스크 인지, 하드디스크인지 정보 기록.
0xF0 : 기본 플로피 디스크
0xF8 : 하드 디스크

0x16

FAT16의 크기 FAT16 파일 시스템일 경우, FAT#1 테이블의 크기

0x18

트랙 당 섹터 수 한 트랙에 존재하는 섹터 총 수.

0x1A

헤드 수 헤드 수

0x1C

숨은 섹터 수 디스크의 0 부터 파티션 시작 위치까지의 섹터 수

0x20

FAT32 총 섹터 FAT32 파일 시스템 일 경우, 총 섹터 수. (총 크기)

0x24

FAT32 크기 FAT32 파일 시스템일 경우, FAT#1 테이블 크기

0x28

확장 FLAGS - 플래그

0x2A

File System Version 파일 시스템 버전

0x2C

루트 디렉토리 클러스터 루트 디렉토리 시작 클러스터 번호

0x30

File System Info -

0x32

백업 부트 섹터 백업 부트 섹터 위치

0x34

예약  

0x40

드라이브 번호 BIOS 콜 (INT 13h)드라이브 정보
0x00 : 플로피 디스크 A
0x01 : 플로피 디스크 B
0x80 : 드라이브 C
0x81 : 드라이브 D

0x41

예약  

0x42

부트 시그널 0x29 시그널

0x43

볼륨 ID 디스크 볼륨 ID

0x47

볼륨 레이블 디스크 볼륨 레이블

0x52

File System Type -


위치 별 각 항목을 적어봤다.

이 구조에 값을 대입해 보면서 파일을 찾고 파일 데이터 읽는 부분을 순차적으로 분석해 봐야 겠다.

우선 파일을 찾기 위해선 파일 목록 정보를 가지고 있는 루트 디렉토리 엔트리로 가야한단다. 무조건 시작은 루트 디렉토리 엔트리 영역에서 파일을 찾든 데이터를 읽든 시작한단다. 파일 목록이 너무 길면, 다음 파일 목록이 어디에 있는지 루트 디렉토리 영역에 기록되어 있단다. 그래?? 한번 찾아가봐야 겠네! 


(ㅋㅋㅋㅋ 실제로는 FAT 테이블에 다음 영역이 기록된다고 한다. ㅋ)

실제 디스크에서 루트 디렉토리는 위치는 위 표에서 나온대로

루트 디렉토리 = 숨은 영역 섹터 + 예약 영역 섹터 + (FAT#1 크기 * FAT 수)


위치에 있다. 이 영역에서 파일을 검색한다. 함 찾아 볼까??

내 BaramOS 이미지 BPB 영역에서 각 항목은



숨은 영역 섹터(0x1C) = 0x00000080
예약 영역 섹터(0x0E) = 0x186E
FAT32 크기(0x24) = 0x000003C9
FAT 수(0x10) = 0x02

루트 디렉토리 = 0x00000080 + 0x186E + (0x000003C9 * 0x02)


0x2080 섹터에 루트 디렉토리가 존재 한다. 그럼 이미지 파일에서 0x2080 섹터 위치를 찾아 볼까나? 아! 섹터 위치다 여기서 섹터당 바이트(0x0B) 위치에 보면 0x200 이므로 0x200을 곱한다. 그럼 0x410000위치에 루트 디렉토리가 존재한다. 가보잣!!



뭔가 적어져 있다. 포맷 하고 아무것도 파일 저장 안 했는데 뭔가 있다. 아! 루트 디렉토리(C:\) 정보란다. 그냥 기본으로 들어간다고 한다. 그래서 파일 하나를 저장해봤다.


오!! 파일이 기록되어 있다. KERNEL.SYS 파일명이 있고 쏼라 쏼라.. KERNEL.SYS 에서 “.” 이 빠진 게 특이하다. 그럼 이 파일목록 구조를 살펴봐야 겠다. (할게 겁나 많네..)


한 파일당 32바이트(0x20) 구성으로 이루어져 있다고 한다. 이미지 파일이 0x410000에서 시작하니 KERNEL.SYS 파일은 0x410020 에서 시작되는 것이다. 위 항목에 실제 이미지 파일 데이터를 대입해 보면


파일이름 : KERNEL
확장자 : SYS
속성 : 0x20 (Archive)

0000 0001 읽기 전용
0000 0010 숨은 파일
0000 0100 시스템 파일
0000 1000 볼륨 레이블
0000 1111 긴 파일
0001 0000 디렉토리
0010 0000 Archive

예약 : 0xAB18
파일 생성시간 : 0x7CA2

11~15비트 시간 0~23
5~10비트 분 0~59
0~4비트 초 0~59
파일 생성날짜 : 0x42EF
9~15비트 년도 (1980 + 비트값)
5~8비트 월(1~12)
0~4비트 일(1~31)
액세스 날짜 : 0x42EF
클러스터 위치: 0x0000 (high)
파일 Write 시간 : 0x0577
파일 Write 날짜 : 0x42EC (
클러스터 위치: 0x0003 (low) (3)
파일크기: 0x0000048F (1167 byte)


KERNEL.SYS 파일은 클러스터 HIGH + LOW 하면 0x00000003 위치에 있다. 그러면 데이터 영역 3번 클러스터 위치로 가보자! 1 클러스터는 2 섹터가 묶여 있다고 하니, 2 * 0x200(512) * 3.

현재 위치 0x410000 + (0x00000003 * 0x200 * 2) = 0x410C00 .. 으로 가보자!!!


없다…아무런 데이터도 없다.. 이게 웬일이냐??

흠…


그러니까 데이터 영역 시작과 현재 내가 보고 있는 루트 디렉토리 영역은 동일한 위치가 아니란다. 뭔말?? 즉, 데이터 영역에서 2 클러스터 이동한 위치가 루트 디렉토리 영역이다. 난, 데이터 영역 시작 위치가 루트 디렉토리 영역인지 알았다. 하지만 그게 아니고 데이터 영역 위치에서 2 클러스터 위치를 이동한 위치가 0x410000인것이다. 이 정보가 어디에 있냐면, BPB 의 루트 디렉토리 클러스터 (0x2C) 위치에 0x2 라고 적어 놨다… 아놔!!!~~~흠


현재 위치가 데이터 영역에서 2클러스터 위치 0x410000 이니까 3 클러스터 위치는 0x410000 영역에서 0x200(512) * 2 = 0x400 를 더한 0x410400 위치에 있다. 함 볼까?



데이터가 있다. 얼마나 있을까? 생각해 보니 1 클러스터 크기 만큼 있을테니 1 클러스터(2섹터)는 1024byte 만큼 있을 것이다. 그렇겠지!~~~? 그러면 내 KERNEL.SYS 파일 크기는 1167 byte 이므로 하나의 클러스터(1024byte)에 다 기록하기에는 힘들다. 그럼 다음 클러스터에 있겠지….라고 생각해서 이동해 봤더니 다음 데이터가 다음 클러스터 위치(0x410800)에 있다. 그런데 검색 질 해보니 이건 방금 포맷하고 파일 저장 한 거라 이렇게 되지만, 파일을 삭제,추가를 반복하게 되면 이렇게 순차적으로 저장되지 않는다고 한다. 어째 다음 데이터가 있길래 잘 풀린다 했다. 검색 내용으로는 파일 데이터가 있는 클러스터를 읽고 난 후 FAT 테이블로 이동해서 다음 데이터가 어디에 있는 지 클러스터 번호를 얻어야 한다고 한다.

그래 FAT 테이블이 어떤지를 또 알아야 된다는 거네!!!! 아놔~FAT 테이블로 이동해 보자.

FAT 테이블 = 숨은 영역 섹터 + 예약 영역 섹터
0x18EE = 0x00000080 + 0x186E
FAT 위치 = 0x18EE * 0x200 (512byte)

0x31DC00 위치에 FAT가 있다. 가보자!!


이상한 FF FF FF 만 있다. 이게 뭔지를 알아야 한다 ㅠㅠ 아이고!!!


FAT는 위 구조와 같이 구성되어 있다고 한다. 각 클러스터는 4바이트로 구성되고 다음 클러스터 위치를 가르킨 다고 한다. 0x0FFFFFFF 일 경우에는 다음 클러스터가 없다는 의미란다.


클러스터 0, 1 위치는 FAT32 에서는 쓰이지 않는다고 하니, 클러스터 2 는 루트 디렉토리 엔트리를 뜻한다. 현재 파일이 하나밖에 없고 디렉토리도 없으니까(클러스터 한 개에 파일 목록을 담을 수 있는 갯수는 32개이다. 왜??? 파일목록 데이터는 32바이트로 구성되고 한 개의 클러스터(1024) / 32 = 32이니까!~~즉 32개의 파일 목록 이상 가지고 있지 않으니 파일 목록 정보를 담은 클러스터는 클래스터2 로 충분하다는 말이다) 클러스터 2는 다음 클러스터를 0x0FFFFFFF 라고 기록되어 있다. 하지만 클러스터 3 은 KERNEL.SYS 데이터를 기록되어 있는 클러스터로 파일 크기가 1167 이니 클러스터 2개가 필요하다. 그래서 클러스터3 위치에 보면 다음 위치 0x00000004 위치를 가르킨다. 그리고 클러스터4 는 다음 클러스터를 0x0FFFFFFF 으로 더 이상 다음 클러스터가 없다고 기록되어 있다. 즉 KERNEL.SYS파일은 클러스터 3번과 4번을 이용해서 파일 데이터를 기록해 놓고 있다.


자 정리해 보면!


1. 루트 디렉토리 엔트리에서 원하는 파일을 찾는다.(KERNEL.SYS)
2. 파일 데이터가 기록되어 있는 클러스터3으로 이동해서 데이터를 읽는다.
3. FAT 테이블로 이동해 클러스터3번의 다음 클러스터가 있는지 체크한다. (클러스터 4가 있다)
4. 데이터 영역에서 다음 클러스터4 위치로 이동해서 데이터를 읽는다.
5. FAT 테이블로 이동해 클러스터4번의 다음 클러스터가 있는지 체크한다. (0x0FFFFFFF 이므로 더 이상 없다.)
6. 종료.


위와 같은 방법이 FAT32 동작 시나리오라 할 수 있겠다. 휴~~ 긴 FAT32 를 공부했다.

검색질을 몇번을 했는지 모른다. 글 쓰고 수정하고 수정하고… 글이 완전 산으로 간다.

'프로그래밍 > OS 만들기' 카테고리의 다른 글

OS 만들기 #9 - 부트로더  (0) 2013.08.14
OS 만들기 #8 - 부트로더  (0) 2013.08.14
OS 만들기 #6 - MBR  (0) 2013.08.14
OS 만들기 #5 - 부트로더  (0) 2013.08.14
OS 만들기 #4 - 부트로더  (0) 2013.08.14

부트로더 #4

BaramOS이미지의 첫번째 섹터의 데이터에 내가 입력하지 않는 데이터가 기록되어 있다. 이건 도대체 무엇일까?

또 검색질을 해본다. 아 MBR …


MBR이란?

마스터 부트 레코드 또는 파티션된 기억 장치의 첫 섹터 인 512 바이트 시동 섹터이다. MBR은 다음의 것들 가운데 하나 이상을 위해 사용된다.
디스크 프라이머리 파티션 테이블을 소유한다. 부트스트래핑 운영 체제 32비트 디스크 서명이 있는 각 디스크 매체의 구별 IBM PC 호환 컴퓨터의 대중화 때문에, 지원을 넓히고 다른 컴퓨터 통합하기 위해 이러한 종류의 MBR이 널리 사용된다.  - 위키백과


새로만든 BaramOS 이미지의 파일의 첫번째 섹터의 데이터는 윈도우즈가 디스크 초기화 메뉴에서 MBR 항목에서 선택했을 때 알아서 기록했던 데이터 인것이다. MBR은 파티션 정보를 담을 수 도 있고 , 없을 수도 있단다. 파티션 없는 저장 매체 일 경우 없겠지!~~ 음. http://www.terms.co.kr/MBR.htm 에서는 다음과 같이 설명한다.


MBR[엠비알]은 운영체계가 어디에, 어떻게 위치해 있는지를 식별하여 컴퓨터의 주기억장치에 적재될 수 있도록 하기 위한 정보로서 하드디스크디스켓의 첫 번째 섹터에 저장되어 있다. MBR은 또한 "파티션 섹터" 또는 "마스터 파티션 테이블"이라고도 불리는데, 그 이유는 하드디스크가 포맷될 때 나뉘어지는 각 파티션의 위치에 관한 정보를 가지고 있기 때문이다. 그외에도, MBR은 메모리에 적재될 운영체계가 저장되어 있는 파티션의 부트 섹터 레코드를 읽을 수 있는 프로그램을 포함하고 있는데, 부트 섹터 레코드에는 다시 운영체계의 나머지 부분들을 메모리에 적재시키는 프로그램을 담고 있다.


디스크 파티션을 나눴을 때, 그 정보를 디스크 첫번째 섹터에 담고 있나 보다.

자, 그러면 난 뭐해야 하냐??? 이 1섹터를 내 부트로더로 덮어써야 하는건가?? 검색질(^^)


아~


윈도우 기본 MBR은 활성화된 파티션을 찾아서 그 해당 파티션의 부트레코드를 0x7C00 메모리에 올리는 실행권을 넘긴다고 한다.


그냥 둬도 되겠네… 파티션 부트 레코드를 내 부트로더로 덮어 씌우면 되겠다. 그 전에

파티션.. 좀더 MBR 파티션 정보에 대해서 알아 봐야 겠다.


MBR은 446바이트의 부트코드 랑 16바이트 씩 4개의 파티션 정보를 지니고 있다고 한다. 뭐 내 관심은 446 부트코드는 아니니 넘어가고, 4개의 파티션 정보좀 살펴 봐야 겠다.


파티션 구조

오프셋

길이

내용

0x00

1

파티션 상태 (0x80 : 시동가능 ….)

0x01

3

파티션 첫번째 섹터의 트랙/헤더/섹터 주소

0x04

1

파티션 종류

0x05

3

파티션 마지막 트랙/헤더/섹터 주소

0x08

4

파티션 첫번째 섹터의 LBA

0x0C

4

파티션의 크기


4개의 파티션이 위와 같은 구조로 되어 있다고 한다. MBR은 이 4개의 파티션을 읽어서 파티션 상태 0x80 인 파티션을 찾아서 파티션 첫번째 섹터의 읽고 실행시킨다는 거지. 여튼 여긴 손댈곳이 없는 것 같다. 파티션의 첫번째 섹터만 찾아서 내 부트로더만 넣으면 되겠지.



MBR 의 부트코드가 446라니깐 그 뒤는 파티션 정보는 0x1BE 에 있다.



BaramOS 이미지 파일은 파티션이 하나이므로 뭐 볼 필요는 없겠지만, 첫번째 파티션 정보는 위 그림의 영역 까지다. 한번 나눠보자.

파티션 상태(1) : 0x80(0x80 = 시동 가능, 0x00 = 부팅불가, 기타 = 비정상)
파티션 첫번째 섹터 (3) : 0x000302
파티션 종류(1) : 0x0B(
http://www.win.tue.nl/~aeb/partitions/partition_types-1.html)
파티션 끝 셋터(3) : 0x0F21F0
파티션 첫번째 섹터 LBA : 0x00000080
파티션 크기(섹터갯수) : 0x0003E800

* 리틀 인디안


음. 부팅이 가능 0x80 상태고 FAT32 시스템이라고 파티션 정보에 나와 있다. LBA 는 뭐지???

오!!! int 13 으로 파일 읽을 때 트랙/헤드/섹터 요렇게 구분해 가지고 파일 읽었는데 LBA는 그냥 0부터 ~~쭉 섹터 번호를 읽는게 LBA 라는거네!~ 어쩐지 트랙/헤드/섹터 요거 읽는 거 불편했는데 직관적인 LBA 가 있었네.. 이제 LBA 방식으로 파일을 읽도록 해야 겠다. 트랙/헤드/섹터 요건 영~~~직관적이지 않아!!!!


자 그럼 내 부트로더를 덮어 씌울 파티션 부트섹터 영역으로 넘어가봐야 겠다. 파티션 정보에 LBA에 0x00000080 이라니깐 0x80 섹터 뒤에 있다는 거네!! 0x80 X 512 = 0x10000 이니깐 헥사뷰어 0x10000로 이동!!!



윈도우즈 7 에서 포맷 했더니 요놈은 포맷 하면서 윈도우 기본 부트로더 까지 넣었나 보다. 뭔가 쭉 채워져 있다.



'프로그래밍 > OS 만들기' 카테고리의 다른 글

OS 만들기 #8 - 부트로더  (0) 2013.08.14
OS 만들기 #7 - FAT32  (1) 2013.08.14
OS 만들기 #5 - 부트로더  (0) 2013.08.14
OS 만들기 #4 - 부트로더  (0) 2013.08.14
OS 만들기 #3 - 부트로더  (1) 2013.08.14

부트로더 #3

파일시스템 전혀 생각 안하고 그냥 되는데로 부트로더만 만들다 보니 이런… 처음부터 다시 해야 한다. 아무래도 기본 구조 및 설계는 해 놓고 시작해 놔야 겠다. 그래! 파일시스템. 파일 시스템을 선정 하려고 여기 저기 검색질 해 봤다. 자체 파일 시스템 쓰는곳도 있고 EXT2 , FAT12/16 도 있다. 윈도우에서 개발하니 FAT 시스템으로 가자!! 흠..

FAT 파일 시스템으로 결정하고, 이젠 뭘 해야 하나??

검색질 하니 FAT16 부트로더가 있다. 좋아~ 이걸 참조해서 만들어 보자!! 음.. 이것 역시 플로피 디스크 이미지를 이용한다. 아놔!~ 난 하드디스크 라고!!!!!! ㅠㅠ 참조해서 테스트 하기 어렵겠다..또 검색질 해서 만들어야겠다. 그래 이왕 만드는 김에 FAT16말고 FAT32 파일 시스템으로 가자~~!!! 난 FAT16 같은 오래된 건 싫다고~~~또, 부트로더에 커널 크기 집어 넣는 따위는 하지 말고, 루트 디렉토리에서 파일을 찾아서 로드, 실행 하게끔 깔끔하게 가자~


부트로더 목표


1. FAT32 파일 시스템을 사용한다.
2. 커널은 루트 디렉토리에서 파일 찾아서 로드한다. (C:\OSLDR.SYS)


갑자기 하기 싫어진다…뭘 이제 뭘 어떻게 해야 할지 모르겠다…ㅠㅠ


맹붕!!~~~~~~~~


우선, 기존 이미지 파일은 첫 부트로더 기념으로 그냥 묵혀 둬야 겠다. Virtual PC로 새 장치 추가 해서 다른 이미지 하나를 만들었다. 이번엔 test가 아니고 정식으로 만들 생각이니깐 BaramOS 라고 이름을 지었다. 의미 없다. 그냥 지금 하고 있는 이 삽질이 그냥 부질없다고 생각이 들고 이리저리 흔들리는 것 같아 아무 생각 없이 바람 이라고 지었다. 흠.. 생성한 이 BaramOS 이미지 파일을 FAT32 파일 시스템 이용할 생각이니 포맷이나 해 두자. 음.. 어떻게 포맷하지??? 어떻게 포맷하냐고!~~ 검색..검색..

흘… MS-DOS 플로피 디스크 이미지 파일 하나 구해서 그걸로 부팅하고 하드디스크 포맷하란다!!~ 아놔 고대적 유물 같은 그 이미지를 어떻게 구하냐고!!!! 다시 검색..검색..휴~~ 윈도우즈 7 에 VHD 파일을 가상 드라이브로 연결해 주는 기능이 있다고 한다. 다행이다! 


Virtual PC 로 이미지 만들어서….

제어판 –> 관리도구 –> 컴퓨터 관리


디스크 관리 에서 오른쪽 마우스 클릭 하면 VHD 연결 메뉴가 나온다. 선택.



흠. 디스크에 이미지 파일이 들어갔다. 디스크 1 에 파일이 들어간 그림이다.



초기화 안됨 이라고 나오네..이건 모냐.. 흠. 디스크 1에 마우스 올리고 오른쪽 마우스를 클릭해 봤다. 디스크 초기화 라는 메뉴가 있다. 선택해 봤다.



MBR(마스터 부트 레코드) ? 우선 이건 모르겠다. 그냥 확인 눌러 버렸다. 초기화 안됨이 온라인 으로 바뀌었네..흠


또 디스크 포맷 해야 하니 오른쪽 마우스 클릭해본다. 음. 근데 새 단순 볼륨 ???이건 모냐!! 선택해 본다. 아 파티션 잡는 거구나.. 아~ 플로피 디스크에서는 없는 파티션이다… ㅠㅠ 하드 디스크 이미지 이기 때문에 파티션을 잡아줘야 하나 보다. 아 귀찮다..새 단순 볼륨 생성 다음 다음 누르다 보니 파티션 포맷이 나온다.



FAT32 로 포맷 해야 하니, 선택하고 할당 단위?? 그냥 기본값으로 볼륨 레이블은 모르겠다. 그냥 다음.



파티션 생성 되었고 포맷도 다 되었다. 다시 마우스 오른쪽 클릭을 해보니 [파티션을 활성 파티션으로 표시] 메뉴가 있다. 아! 파티션 생성했으니, 활성 파티션으로 만드는 거구나.. 선택했다.


디스크1 에서 오른쪽 클릭 하면 VHD 분리가 있다. 분리시켰다.


뭔일이 생겼나~~ 한번 헥사 뷰어로 볼까??.



음.. 첫번째 섹터에 이상한 데이터가 들어 있다. 문자열들을 보면 파티션 이라는 단어가 보이네?? 이건 모지??? 조금전 생성했던 파티션에 대한 정보인가?? 왜 이게 여기 있지?? 아놔 이거 관련해서 공부좀 해놔야 겠다



'프로그래밍 > OS 만들기' 카테고리의 다른 글

OS 만들기 #7 - FAT32  (1) 2013.08.14
OS 만들기 #6 - MBR  (0) 2013.08.14
OS 만들기 #4 - 부트로더  (0) 2013.08.14
OS 만들기 #3 - 부트로더  (1) 2013.08.14
OS 만들기 #2  (0) 2013.08.14

부트로더 #2

이제 커널을 로드 해서 커널 실행코드로 넘겨주면 될 것 같다. ㅋ 이 두려운 어셈블리어에서 빨리 벗어나고픈 생각 뿐이다.

이제 파일을 로드 하는 방법에 대해서 검색질 해봐야 겠다. 파일을 읽는 방법은 int 13h 인터럽트를 사용하면 된다고 한다. 근데 사용 방법이 거의 이해하기 어려운 수준이다. 섹터, 트렉, 헤드.. 많이 들어본 용어긴 하지만 그냥 언어적 이해만 할 뿐이지, 실제 데이터 읽고, 쓰는 방법에 대해선 전혀 모른다. 이것 먼저 공부해야 한다. 휴~ 겁나 귀찮고 어렵고 지루하다.

INT 13h 를 사용하여 데이터를 읽는 방법은 다음과 같다.


파라미터

AH 0x02 읽기 ( 0x03 : 쓰기)
AL 읽을 섹터 수.
CH 트랙 번호
CL 읽을 섹터 번호
DH 헤드번호
DL 드라이브 번호
ES:BX 읽은 데이터를 저장할 위치

결과

CF 에러시 플래그가 설정됨.
AH 리턴 코드
AL 읽은 섹터 갯수

그러면 트랙, 섹터, 헤드 가 뭔지를 알아보자.

인터넷에서 검색하다가 찾은 그림이다. 그림을 보니 이해가 된다.

트랙 디스크판에서 원형으로 줄 그어 놓은 영역
섹터 트랙을 부채꼴 모양으로 줄 그어 나눈 구간
헤드 디스크 윗면과 밑면을 읽는 구분.


각각 트랙과 헤드는 0 부터 시작하고 섹터는 1부터 시작한다고 한다. 컴퓨터가 부트로드 영역을 찾을 수 있었던 건 0 트랙, 1섹터에 접근해서 그냥 1섹터를 읽기 때문이기 때문이군..뭐 대충 이해는 간다. 근데 왜이리 복잡한 방법으로 구현해 놓은거냐!~~흠..

나의 커널 데이터는 0트랙 2섹터에 저장해 놓고 이걸 읽으면 되겠군. 아싸 드뎌 진도가 조금 나갔다!!!

헉 프로그래밍 하다 보니까 int 13h 에서 쓰는 DL 레지스터 값 드라이브 번호는 어떻게 적어줘야 하냐 ㅡㅡ;;; 문제에 봉착했다. 검색질 해보니 0x00 은 플로피 디스크 , 0x80 부터는 하드디스크 번호라고 하는데… 나의 이미지 파일은 하드 디스크 이므로 0x80 이라고 주어줘도 된다. 근데 만약 플로피 인지 하드디스크 인지 알고 싶으면??? 검색해보자!! 검색 할 단어 조차도 모르겠다 ㅠㅠ 여튼 부트로더 로 검색 해봐야지~~~ 영어에 일본어에 모르는 글자 들 ㅠㅠ 어렵다…어려워

에휴! 컴퓨터가 부트로더 올리고 DX의 DL 의 부팅한 번호를 기록해서 부트로더로 점프한다고 한다. dl 레지스터가 변경되지 않은 한 dl에 부팅 드라이브 번호가 기록된단다.. 검색하느라 겁나 오래 걸렸다. 아무튼 변수 하나 만들어서 이것도 기록해 놔야 겠다.

ORG 0x7C00
BITS 16

	cli				; 인터럽트 발생안되게 설정
	xor ax,ax		; ax 0으로 초기화 한다. ax xor ax 어차피 0이다.
	mov ds, ax		; ds 세그먼트 레지스터를 0 으로 초기화 한다.
	mov es, ax		; es 세그먼트 레지스터를 0 으로 초기화 한다.
	sti				; 인터럽트 발생 설정

	mov [DRIVE_NUM], dl	; 부팅한 드라이브 번호를 DRIVE_NUM 변수에 저장.

	lea si, [HELLO_MSG]	; HELLO_MSG 위치 주소
	call PRINT			; PRINT 함수 호출

	call READ_SECTOR	; 커널 이미지를 읽어라

	jmp 0x9000			; 메모리 0x9000으로 이동해라.

READ_SECTOR:
	pusha				; 모든 레지스터를 스택에 넣는다.
	mov ah, 0x02		; 디스크 읽기 모드
	mov al, 1			; 1 섹터만 읽는다.
	mov ch, 0			; 트랙은 0번 트랙
	mov cl, 2			; 읽을 섹터는 2번째 섹터
	mov dh, 0			; 헤드는 0번 헤드
	mov dl, [DRIVE_NUM] ; 읽을 드라이브 번호
	mov bx, 0x9000		; 0x9000 메모리에 커널 이미지 올린다.
	int 0x13			; 읽어라!

	popa
	ret	
PRINT:
	pusha				; 모든 레지스터를 스택에 넣는다.
PRINT_LOOP:
	mov al, [si]		; al에 글자 하나 저장한다.
	inc si				; si 주소를 증가한다.
	or al, al			; or 연산. 
	jz PRINT_END		; 문자열 끝이 or 연산이 0 이라면. 종료
	mov ah,0x0E			; ah = 0xE
	int 0x10			; 인터럽트 0x10h
	jmp PRINT_LOOP		; 다음 문자 출력 루프	

PRINT_END:
	popa				;모든 레지스터 스택에서 뺀다.
	ret					;호출 한곳으로 리턴.

HELLO_MSG:
	db "HELLO MY BOOTLOADER", 0x0D,0x0A,0x00

DRIVE_NUM db 0x00
	
	times 510-($-$$) db 0x00
	dw	0xAA55

자, 부트로더는 이렇게 작성해 놓고…커널 이미지를 만들면 된다. 음.. 동작 되는지 확인 할겸 화면에 문자열을 출력하는 기능만 갖도록 하자.  완전 흥분된다!

ORG 0x9000			; 0x9000 메모리에서 실행되므로 0x9000 으로 주소정렬
BITS 16

	cli				; 인터럽트 발생안되게 설정
	xor ax,ax		; ax 0으로 초기화 한다. ax xor ax 어차피 0이다.
	mov ds, ax		; ds 세그먼트 레지스터를 0 으로 초기화 한다.
	mov es, ax		; es 세그먼트 레지스터를 0 으로 초기화 한다.
	sti				; 인터럽트 발생 설정

	lea si, [LOAD_MSG]	; LOAD_MSG 위치 주소
	call PRINT			; PRINT 함수 호출

	jmp $

PRINT:
	pusha				; 모든 레지스터를 스택에 넣는다.
PRINT_LOOP:
	mov al, [si]		; al에 글자 하나 저장한다.
	inc si				; si 주소를 증가한다.
	or al, al			; or 연산. 
	jz PRINT_END		; 문자열 끝이 or 연산이 0 이라면. 종료
	mov ah,0x0E			; ah = 0xE
	int 0x10			; 인터럽트 0x10h
	jmp PRINT_LOOP		; 다음 문자 출력 루프	

PRINT_END:
	popa				;모든 레지스터 스택에서 뺀다.
	ret					;호출 한곳으로 리턴.

LOAD_MSG:
	db "LOAD MY KERNEL", 0x00

	times 510-($-$$) db 0x00
	dw	0xAA55

자 컴파일..

nasm –fbin –o bootloader bootloader.asm
nasm –fbin –o kernel kernel.asm

깔끔하게 컴파일 된다 ^^ 자~ bootloader 하고 kernel 을 Visual studio에서 헥사뷰어로 로드 하고 … 가상 이미지 파일도 로드 하고 512 바이트씩 복사해서 붙여보자…

자~~ 가상 컴퓨터 ~~~

HELLO MY BOOTLOADER
LOAD MY KERNEL

우하하하!! 된다!!! ㅋㅋㅋ

이거 은근히 가슴이 벅차다.. 이제 커널까지 로드 했으니, 본격적으로 커널 만들어서 띄우면 되겠다 ! ^^ 우선, 부트로더 랑 커널을 이미지 파일에 넣는 거 불편하니, 프로그램 하나 만들어 주고!!~ 가만 커널이 커지면 부트로더 에서 섹터 읽어 오는 부분을 변경해줘야 하네!! 흠…지금은 512바이트만 읽어오는 구조니 커널 먼저 만들고 크기 계산해서 부트로더 섹터 읽어 오는 갯수를 늘려줘야 하는 구조네…음…

그냥 파일 크기 알아서 오는 방법은 없나?? 흠.. 커널 만들어서 그냥 복사 해주는 방식으로.. 흠.. 아~~악, 내가 만든 부트로더랑 커널은 파일 시스템이 전혀 고려 안된 구조다!!!

그냥 부트로더 만든다고 나머지 설렁설렁 봤더니 , ㅠㅠ 파일시스템을 고려 했어야 했는데!!! 다시 파일시스템을 고려한 부트로드를 만들어야 한다. (아놔! 어셈블리어 또 …ㅠㅠ) 아, 지친다.. 하기 싫다.. 파일 시스템은 만들어야 하나, 있던거 써야 하나 .. 리눅스 ext2?? 윈도우 FAT??? 이거 뭘 써야 하나~

'프로그래밍 > OS 만들기' 카테고리의 다른 글

OS 만들기 #6 - MBR  (0) 2013.08.14
OS 만들기 #5 - 부트로더  (0) 2013.08.14
OS 만들기 #3 - 부트로더  (1) 2013.08.14
OS 만들기 #2  (0) 2013.08.14
OS 만들기 #1  (0) 2013.08.14

부트로더 #1

부트로더를 만들어야 하는데, 어셈블리어 잘 모르는데 난감하다. 몇 번 훑어 본 걸로 만들 수 있을 지 모르겠다. 다른 부트로더를 참조해서 만들어야 겠다. 그래 (ㅠㅠ 나의 영혼이여~~ ) 근데, 부트로더는 어떻게 실행 할까? 라는 궁금증이 생겼다. 자 검색..검색..

음… 대충 컴퓨터가 전원이 켜질 경우 , 저장 매체의 첫 번째 섹터에서 512 바이트를 정해진 메모리에 로딩하고 해당 메모리를 프로그램으로 인식하고 실행한다. 라고 이해했다. 그러니까 첫 번째 섹터 512바이트를 읽어서 그걸 실행한다는 거군. 쉽네. 근데 왜 512바이트지?? 검색..검색.. 흠 못 찾겠다.

자 , 그러면 프로그래밍 한번 해보자!!! 아직, 부트로더 설계도 제대로 잡지 않았는데…음… 흠.

그냥 HELLO 한번 찍어 보자.

   1: mov ax, 0    ; ax 레지스터를 0 으로 초기화 한다.
   2: mov ds, ax   ; ds 세그먼트 레지스터를 0으로 초기화 한다.
   3: mov es, ax   ; es 세그먼트 레지스터를 0으로 초기화 한다.

아직 여기밖에 모르겠다. 화면에 출력하려면 어떻게 하지?? 히유!! 답답하다…또 검색질 하자.

어셈블리어를 이용해서 화면에 글자를 출력하려면 BIOS 인터럽트 를 이용해야 한다고 하네.. 그래 인터럽트 한번 더 뒤져보자.

http://ko.wikipedia.org/wiki/%EB%B0%94%EC%9D%B4%EC%98%A4%EC%8A%A4_%EC%9D%B8%ED%84%B0%EB%9F%BD%ED%8A%B8_%ED%98%B8%EC%B6%9C 여기에 인터럽트 테이블 모아놓은 게 있네. INT 10h 이용하면 되겠다.

mov al, ‘a’
mov ah, 0x0E
int 10h

이걸 이용해서 다시 프로그래밍 한다.

	cli				; 인터럽트 발생안되게 설정
	xor ax,ax		; ax 0으로 초기화 한다. ax xor ax 어차피 0이다.
	mov ds, ax		; ds 세그먼트 레지스터를 0 으로 초기화 한다.
	mov es, ax		; es 세그먼트 레지스터를 0 으로 초기화 한다.
	sti				; 인터럽트 발생 설정

	lea si, [HELLO_MSG]	; HELLO_MSG 위치 주소
	call PRINT			; PRINT 함수 호출

	
PRINT:
	pusha				; 모든 레지스터를 스택에 넣는다.
PRINT_LOOP:
	mov al, [si]		; al에 글자 하나 저장한다.
	inc si				; si 주소를 증가한다.
	or al, al			; or 연산. 
	jz PRINT_END		; 문자열 끝이 or 연산이 0 이라면. 종료
	mov ah,0x0E			; ah = 0xE
	int 0x10			; 인터럽트 0x10h
	jmp PRINT_LOOP		; 다음 문자 출력 루프	

PRINT_END:
	popa				;모든 레지스터 스택에서 뺀다.
	ret					;호출 한곳으로 리턴.

HELLO_MSG:
	db "HELLO MY BOOTLOADER", 0x00

자 코드 입력은 했고 , 컴파일 해야지~~~^^

nasm –fbin –o BOOTLOADER BOOTLOADER.ASM

캬~~ 에러도 없다. BOOTLOADER 라는 파일이 생성 되었다.

자 이제 이걸 첫 번째 섹터에 복사해 주면 된다.  아~ 난 가상이미지 파일인데?? 어떻게 이걸 복사하지?? 아놔!!! ..흠…이미지 파일이니까 그냥 이미지 파일 찾아서 해당 첫 번째에다가 복사하면 되나?? 생각 난 김에 해보자!! 근데 이거 원… 가상 이미지 파일 있는 위치를 모르겠네 ㅡㅡ;;;

1. Windows Virtual PC 를 실행한다.
2. 생성한 가상 컴퓨터를 선택한다.
3. 설정 을 클릭한다.
4. 하드 디스크 1을 선택한다.
5. 가상 이미지 파일 위치를 찾았다!

 자 , vhd 확장자의 이미지 파일을 찾았다. ㅎㅎ 이제 에디터로 불러야지~~. 음… 울트라 에디터로 로딩할 까, Visual Studio 로 로딩 할까?? 아무래도 복사해야 하니 Visual Studio 에서 로딩 해야 할것 같다. 아악!! 128MB 다. 왜 이렇게 크게 만들었을까 ..ㅠㅠ 다시 만들까?? 귀찮다!!! 그냥 읽어 버렷!

깔끔하게 헥사뷰어 로 나온다. 울트라 에디트 보단 이게 좋지~^^ 아 부트로더 도 읽어야지~~Visual Studio에 부트로더 도 읽어 준다. 탭으로 왔다 갔다 하면 편하겠네..부트로더 헥사뷰어에서 코드를 이제 복사한다. 컴퓨터가 512바이트를 읽는다고 했으니, 512바이트를 복사하면 되겠다. 라인이 1f0까지 쭉 내려서 복사한다. 그리고 이미지 파일 헥사뷰어에서 똑같이 1f0 라인까지 선택 후, 붙이기 한다. 그리고 저장.!!!!

긴장된다. Windows Virtual PC 실행해서 가상 컴퓨터 작동해봐야지~~

한참을 기다려도 실행 안된다. 검은 화면…..이미지 파일 첫 부분에 파일 붙이기 하는게 안되는 건가?? 흠.. 인터넷에서 돌아다니는 부트로더로 컴파일 해서 복사, 붙이기 하니 화면이 뜬다. 이미지 파일 첫 부분에 붙이기 하는건 되는건가 보다. 내가 만든 코드는 아니지만 가상 컴퓨터 화면에 뭔가 출력은 되니, 쪼금 나도 희망이 생긴다. 음.. 뭐가 문제지?? 되는 부트로더 랑 비교해 보자!!

크게 다른 부분은 첫 부분하고 끝 부분이다.

times 510-($-$$) db 0x00
dw 0xAA55

이건 또 무슨 문법이야 ? 하고 검색해 보니, times 는 뭘 반복할 때 쓴다고 한다. $는 현재 위치를 나타내는 거고, $$줄 처음 위치를 나타내는 거란다. 그러면 저 명령어 들의 하는 짓은??? 그냥 510까지 0으로 채우는 짓이란다. 즉 내가 만든 코드는 50 바이트 밖에 안된다. 510-50 = 460 바이트를 0으로 다 채운다는 것이다. 어차피 0으로 다 채워져 있는데 뭘!! 흠.. 그리고 dw 0xAA55는 510 이후에 AA55라고 쓰기 위해서란다. 왜???? 컴퓨터가 512 바이트를 읽고 0xAA55 저놈이 있나 없나 체크 한단다!! 없으면 실행 안 해 준다네…

흠.. 그러니까 512 바이트 중 끝에 0xAA55가 있어야지 우선 실행해 준다는 거네. 그러면 코드에 times랑 0xAA55 넣고 컴파일….다시 가상 PC 작동…..오~~~~~~~~~~~~~~~~~ 뭔가 나온다!!!

아드래날린이 왕성하게 분비 되는지 흥분된다. 하하하 . 흠 근데 왜 글자가 안나오고 쓰레기값이 나오냐?? 코드 문제인가? 흠.. 동작하는 부트로더랑 비교해 봐야겠네…

첫부분에

org 0x7C00
bits 16

이 있다. 뭐 뒤에 쓰잘데기 없이 점프 명령어 있긴 한데 뭐 필요 없는 작업인것 같고… 요 두넘이 틀리다. 또 뭐하는 놈들이냐?? 검색..검색…(검색질도 지겹다 …)

ORG 0x7C00 : 컴퓨터가 내가 만든 부트로더를 0x7C00 메모리 위치에다가 로딩하는데, 내 부트로더는 데이터 변수 쓸때 그 데이터 변수 위치가 0으로 시작된 위치에 있으므로 찾지 못한다. 고로 첫줄에 똭!!!! 0x7C00 부터 시작 되게 하면 그 데이터를 쓸 수 있게 해준단다!

BITS 16 : 내가 작성하는게 16비트에서 작동하는 코드를 사용한다는 명령어란다. 흠!

뭐 이리 어렵나~~ 여튼 추가…

ORG 0x7C00 
BITS 16

    cli                ; 인터럽트 발생안되게 설정 
    xor ax,ax        ; ax 0으로 초기화 한다. ax xor ax 어차피 0이다. 
    mov ds, ax        ; ds 세그먼트 레지스터를 0 으로 초기화 한다. 
    mov es, ax        ; es 세그먼트 레지스터를 0 으로 초기화 한다. 
    sti                ; 인터럽트 발생 설정

    lea si, [HELLO_MSG]    ; HELLO_MSG 위치 주소 
    call PRINT            ; PRINT 함수 호출

    jmp $

    
PRINT: 
    pusha                ; 모든 레지스터를 스택에 넣는다. 
PRINT_LOOP: 
    mov al, [si]        ; al에 글자 하나 저장한다. 
    inc si                ; si 주소를 증가한다. 
    or al, al            ; or 연산. 
    jz PRINT_END        ; 문자열 끝이 or 연산이 0 이라면. 종료 
    mov ah,0x0E            ; ah = 0xE 
    int 0x10            ; 인터럽트 0x10h 
    jmp PRINT_LOOP        ; 다음 문자 출력 루프   

PRINT_END: 
    popa                ;모든 레지스터 스택에서 뺀다. 
    ret                    ;호출 한곳으로 리턴.

HELLO_MSG: 
    db "HELLO MY BOOTLOADER", 0x00

    times 510-($-$$) db 0x00 
    dw    0xAA55

나 울뻔 했다…된다..

HELLO MY BOOTLOADER

화면에 출력된다. 검색 질 하느라 시간 보냈는데 출력이 되니 기쁘다. 이제 커널 파일 만들어서 부트로더에서 로딩시키고 커널 실행시키면 되겠다. 하하 이제 C 로 넘어간다. 알지도 못하는 어셈블리어로 벗어 난다니 더 기쁘다.

'프로그래밍 > OS 만들기' 카테고리의 다른 글

OS 만들기 #6 - MBR  (0) 2013.08.14
OS 만들기 #5 - 부트로더  (0) 2013.08.14
OS 만들기 #4 - 부트로더  (0) 2013.08.14
OS 만들기 #2  (0) 2013.08.14
OS 만들기 #1  (0) 2013.08.14

가상 이미지 생성

Windows Virtual PC 를 실행했다. 음… 탐색기 처럼 생겼네…아니 탐색기네. 음 자~ 새 장치를 추가 해야 하는데 음.. 없네…

아~ 가상 컴퓨터 만들기 메뉴 버튼에 있구나.. 거참 자세히 봐야 하네…이름?? 음…우선 test로 지정하고 나중에 다시 지정해야 겠다.

이름 : test

음  … 위치??? 그냥 두자.. 귀찮다. 다음..

메모리 ? 음… 기본 512로 하자.. 뭐 윈도우즈 만드는것도 아니고~^^ 네트워킹 너도 아직 네트워크는 무리다..다음..

RAM : 512
네트워크 : 언체크

가상 하드 디스크 추가.. 동적 확장?? 디스크 용량이 늘어나면 동적으로 늘어난다는 말이군… 난 고정 디스크로 할꺼다. 커질일 없을테니 … 고정은 없네? 고급 옵션쪽에 있나 보다.. 다음.

고급 옵션을 사용하여 가상 하드 디스크 만들기 : 체크

아…ㅎ 여기에 고정 크기 있네.. 고정크기 …

고정크기 : 클릭

창이 바로 바뀌네…이름 그대로 두고 다시 다음. 크기 지정 …그냥 64?? 32?? 음…모르겠다.. 128M

크기 : 128M

다 만들었다. test.vmcx 파일이 생겼네…우선 만들었으니 부팅한번 해 볼까??? 이거 실행은?? 어떻게 하지?? 그냥 더블 클릭??? 어디…오 된다!!!

검은 창에

Reboot and Select proper Boot device
or Insert Boot Media in selected Boot device

메시지 출력 된다. 뭐 아직 부트로더 라는게 없으니..


이제 부트로더 한번 만들어 보자!!!



 

'프로그래밍 > OS 만들기' 카테고리의 다른 글

OS 만들기 #6 - MBR  (0) 2013.08.14
OS 만들기 #5 - 부트로더  (0) 2013.08.14
OS 만들기 #4 - 부트로더  (0) 2013.08.14
OS 만들기 #3 - 부트로더  (1) 2013.08.14
OS 만들기 #1  (0) 2013.08.14

  OS를 만들기 위해 부랴부랴 인터넷 검색을 해봤다. 우와! 책도 많고 관련 정보들이 상당하다. 수준급인 OS 부터 기초 정보 또한 대단히 많다. ‘그냥 이거 가져다 수정하면서 공부해 보면 되겠네…’ 라고 생각했다가 접었다.. 왜? 내 코드가 아니고 내 구조가 아니고… 내 영혼(?)이 아니다. 그냥 하나 하나 내가 부딪치며 만들어야 내것 같다는 생각이 들어서다. 또 뭔가 고비가 있어야 내 지식이지, 단순히 복사 & 붙이기는 그냥 영혼없는 결과물 만들기일 뿐이라고 생각해서 이다.

 

그래서 처음에 무얼 만들어야 하는지, 검색해 봤다. 부트로더 란다.. 컴퓨터가 전원 들어와서 처음으로 찾는 프로그램이란다. 근데, 어셈블리어로 작성해야 한단다. 난 어셈블리어 모르는데?? 공부해야 한다. ㅠㅠ 귀찮다. 인터넷에서 대충 훑어 봤다. 훑어 보는 내내 영혼의 울림이 있다. 내 취향과 어울리나 보다… ㅋㅋㅋ 하지만 어렵다.. 더 세세하게 파기에는 나의 귀차느즘이 거부한다. 부트로더 프로그래밍은 아직 무리다.. 다시 뭘 준비해야 하는지 검색해 봤다. 부트로더를 올리고 테스트 해 볼 가상 이미지 파일이나 플로피 디스크를 준비해야 한단다. 난 플로피 디스크 드라이버 없으므로, 이미지 파일로 준비하면 되겠다. 음… 이미지 파일을 만들려면 또 이것저것 프로그램이 필요하단다. 아~ 점점 귀찮아 진다. 다 다운로드 받았다. 그런데 검색하다 보니 대부분 플로피 디스크 이미지로 만든다. “왜?” 라고 생각이 들었다. 용량이 작아서 그러나? … 난 하드 디스크 이미지로 할꺼다… 플로피 디스크 언제적 고대 유물이냐 말이다! ^^

 

귀찮은 툴들이 다 필요 없어 진다. ㅎㅎㅎ 좋다. 근데 하드 디스크 이미지는 뭐로 만들지??? 검색한다. 아~~ vmware가 있었지!! ㅋㅋㅋ virtual box 도 있고… 생각을 못했네 !!. vmware 는 상용이고 무거우니까(?) virtual box를 설치해야지~~ ^^ virtual box 다운 받으려고 검색하니 virtual pc 라는 윈도우 프로그램도 있다고 하네? ^^ ㅋ 음.. 그럼 Windows Virtual pc 로 하자~ 

 

 

 

준비물


- Windows 7
- Windows Virtual PC
- NASM 2.10 이상



 

'프로그래밍 > OS 만들기' 카테고리의 다른 글

OS 만들기 #6 - MBR  (0) 2013.08.14
OS 만들기 #5 - 부트로더  (0) 2013.08.14
OS 만들기 #4 - 부트로더  (0) 2013.08.14
OS 만들기 #3 - 부트로더  (1) 2013.08.14
OS 만들기 #2  (0) 2013.08.14

C로 작성된 서버에서 네트워크로 문자열 패킷을 수신했다. 이를 String 으로 변환하려


string msg = new string(msg_data);

위와 같이 했을 경우, msg_data에 패킷 문자열을 고정시키기 위해 실 문자는 5개 문자열만 있지만 실제 데이터 크기가 60개라면 \0로 문자열 끝을 가리키는 문자로 채워진다. string msg에 \0도 문자열로 판단하여 공백이 발생한다. 이는 Trim함수로 공백을 제거하려 해도 되지 않는다. \0 문자로 삭제해야 한다.

msg.TrimEnd(‘\0’);

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

PNG 16bit grayscale 데이터 읽기  (0) 2022.03.15
Window class name is not valid  (0) 2014.08.06
쓰레드 종료 지연 문제  (0) 2013.08.14
변수 타입  (0) 2013.08.14

FtpRequest를 이용한 FTP 클라이언트를 만드는 도중, 폼이 종료 할때 종료가 지연되는 문제가 발생했다.

원인을 파악해 보니 접속되지 않는 주소에 연결을 하게 될 경우나 파일 전송중에 종료를 하게 되니 발생하는 문제였다.

Thread의 Abort 기능이나 interrupt 로 처리해 보았지만, 여전히 문제는 해결되지 않았다. 그러던중 IsBackground라는 속성을 알게 되었는데 이 IsBackground에 대한 설명은 msdn에 다음과 같이 설명되어 있다.

http://msdn.microsoft.com/ko-kr/library/system.threading.thread.isbackground.aspx

스레드가 배경 스레드인지 여부를 나타내는 값을 가져오거나 설정합니다.

네임스페이스: System.Threading
어셈블리: mscorlib(mscorlib.dll)

public bool IsBackground { get; set; }
속성 값
형식: System.Boolean

이 스레드가 백그라운드 스레드이거나 백그라운드 스레드가 될 예정이면 true이고, 그렇지 않으면 false입니다.

배경 스레드는 프로세스의 종료를 막지 않는다는 점을 제외하고 전경 스레드와 동일합니다. 프로세스에 속해 있는 모든 전경 스레드가 중단되면 공용 언어 런타임에서 프로세스를 끝냅니다. 나머지 배경 스레드는 모두 중지되며 완료되지 않습니다.

Thread WorkThread = new Thread(new ThreadStart(WorkProc));
WorkThread.IsBackgound = true;

위와 같이 처리하면 종료 시 지연 되는 문제는 없어진다. Foreground 쓰레드는 생성된 후 자신의 작업이 끝날때 까지 종료되지 않는다. 그래서 메인 쓰레드가 종료되더라도 쓰레드가 종료 될 때까지 대기 상태로 머무르게 된다. Background는 주 쓰레드를 대신하여 작업을 대신 하는 것이므로 진입 메소드가 종료되면 쓰레드가 끝나는 것으로 자연스럽게 표현된다고 한다.

Thread의 abort는 기존 TherminateThread 와 같은 기능은 아닌것 같고 ThreadAbortException을 발생 시킨다고 한다. 또한 intterupt는 ThreadInterruptedException을 발생시킨다.

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

PNG 16bit grayscale 데이터 읽기  (0) 2022.03.15
Window class name is not valid  (0) 2014.08.06
C# array char to String 변환  (0) 2013.08.14
변수 타입  (0) 2013.08.14
변수
 - 변수란, 데이터를 담을수 있는 메모리 이며, 메모리를 가르키는 이름이다.

- 데이터형
byte       1바이트
char       2바이트
int          4바이트
long       8바이트
float       4바이트
double   8바이트
decimal  16바이트
bool       1바이트

* built-in
각 데이터형은 기본적으로 위에서 표기된 정해진 메모리를 할당한다.


사용법 예제

int a;

a = 5;
a = 20;

a라는 변수는 int 데이터형을 나타낸다.
a 라는 변수에 5를 저장한다.
(a가 가르키는 메모리에 숫자 5를 저장한다.)
a 라는 변수에 10을 저장한다.


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

PNG 16bit grayscale 데이터 읽기  (0) 2022.03.15
Window class name is not valid  (0) 2014.08.06
C# array char to String 변환  (0) 2013.08.14
쓰레드 종료 지연 문제  (0) 2013.08.14

+ Recent posts