- 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의 저장기술 측면에서의 클러스터는 하드디스크 위에 파일을 저장하는 논리적 단위이며, 컴퓨터의 운영체계에 의해 관리된다. |
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 |
9~15비트 | 년도 (1980 + 비트값) |
5~8비트 | 월(1~12) |
0~4비트 | 일(1~31) |
클러스터 위치: 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 |