[OS]miniOS-7(3)

👉️ 데이터 영역: GDT(Global Descriptor Table) 구조 정의 부분 코드 설명입니다.
Data Area: This is an explanation of the code defining the GDT (Global Descriptor Table) structure.

✔️ 데이터 영역으로 GDT(Global Descriptor Table) 구조를 정의 합니다.
Define the GDT (Global Descriptor Table) structure in the data area.

— 4바이트 정렬 / 4-byte alignment

1)현재 위치의 코드 데이터의 바이트 수를 4로 나누었을경우 나머지가 0이 아니면 0~3바이트를 0을 추가해서 4로 나눈 나머지가0이 되도록 맞춥니다.
If the byte count of the code data at the current position is not divisible by 4 (i.e., the remainder is not 0), 0 to 3 bytes are added to make the remainder 0 when divided by 4.

2)필수 사항은 아니며 GDT의 깔끔한 정렬 때문에 사용합니다.
It is not mandatory; I use it because of GDT’s clean alignment.

align 4

— 널 디스크립터 입니다.
It is a null descriptor.

dd 0, 0 

1)GDT의 첫 번째 엔트리는 Null Descriptor여야 합니다.
The first entry of the GDT must be a null descriptor.

2)디스크립터는 세그먼트를 설명하는 8바이트짜리 정보입니다.
A descriptor is an 8-byte piece of information that describes a segment.

3) GDT는 테이블이고 디스크립터는 테이블의 원소입니다.
The GDT is a table, and descriptors are the elements of that table.

4) dd 0, 0은 32비트(double word) 데이터 두 개를 0으로 저장하라는 의미입니다.
“dd 0, 0” means to store two 32-bit (double-word) data items as 0.

5) 지시어의 크기 / Size of the directive

db (Define Byte) : 1Byte
dw (Define Word) : 2Byte
dd (Define Double Word) : 4Byte

6)실제 메모리에는 다음과 같이 저장 됩니다.(4바이트 + 4바이트 = 8바이트)
It is stored in actual memory as follows (4 bytes + 4 bytes = 8 bytes).

6-1) 널디스크립터의 크기는 8바이트이며 메모리에는 실제로 아래와 같이 저장됩니다.
The null descriptor is 8 bytes in size and is actually stored in memory as shown below

00 00 00 00
00 00 00 00

— 코드 세그먼트 디스크립터 (오프셋 0x08 = 널 디스크립터 8바이트)
Code segment descriptor (offset 0x08 = 8-byte null descriptor)

    dw 0xFFFF, 0x0000
    db 0x00, 0x9A, 0xCF, 0x00

1) 코드 세그먼트 디스크립터는 코드 세그먼트의 위치에 대한 정보가 저장됩니다.
A code segment descriptor stores information about the location of a code segment.

2)dw는 2바이트를 생성합니다.
dw generates 2 bytes.

3) 0xFFFF는 FF FF 2바이트가 되고 0x0000는 00 00로 2바이트가 됩니다.
0xFFFF becomes the two bytes FF FF, and 0x0000 becomes the two bytes 00 00.

4) 그러면 총 4바이트가 됩니다.
That makes a total of 4 bytes.

5) db는 1바이트를 만듭니다.
db creates a 1-byte value.

6) 그러면 아래처럼 각1바이트의 합계는 총4바이트가 됩니다.
Then, as shown below, the sum of the 1-byte values ​​results in a total of 4 bytes.

1)dw는 2바이트를 생성합니다.
dw generates 2 bytes.

2) 0xFFFF는 FF FF 2바이트가 되고 0x0000는 00 00로 2바이트가 됩니다.
0xFFFF becomes the two bytes FF FF, and 0x0000 becomes the two bytes 00 00.

3) 그러면 총 4바이트가 됩니다.
That makes a total of 4 bytes.

4) db는 1바이트를 만들고 총 4바이트가 됩니다.
db creates 1 byte, resulting in a total of 4 bytes.

db 0x00 → 1 byte
db 0x9A → 1 byte
db 0xCF → 1 byte
db 0x00 → 1 byte
--------------------
합계/total 4  byte

5) 코드 세그먼트 디스크립터는 dw(2byte×2) 4바이트와 db(1byte×4) 4바이트를 합해서 총 8바이트가 됩니다.
A code segment descriptor totals 8 bytes, combining 4 bytes from dw (2 bytes × 2) and 4 bytes from db (1 byte × 4).

6) 메모리에는 다음처럼 8바이트가 생성됩니다.
8 bytes are created in memory as follows.

FF FF 00 00 00 9A CF 00

7) 코드 디스크립터의 구조는 다음과 같습니다.
The structure of the code descriptor is as follows.

+----------------+----------------+
| Limit(2B)      |
+----------------+----------------+
| Base(2B)       |
+----------------+----------------+
| Base(1B)       |
+----------------+----------------+
| Access(1B)     |
+----------------+----------------+
| Flags+Limit(1B)|
+----------------+----------------+
| Base(1B)       |
+----------------+----------------+

8) 다음은 코드 디스크립터의 기능입니다.
The following are the functions of the code descriptor.

Code Descriptor

Base
-- 코드 세그먼트가 시작될 위치
The starting location of the code segment

Limit
-- 사용할 메모리 용량
Memory capacity to use

Access
 -- 코드인지 데이터인지 설정
Configure whether it is code or data.
 -- 실행 가능한지 설정
Set whether it is executable
 -- 권한설정
Permission Settings

Flags
-- 16비트인지 32비트인지 설정
Set to 16-bit or 32-bit
-- Limit를 바이트 단위로 볼지 4KB 단위로 볼지 설정
Configure whether to view the limit in bytes or 4KB units.

7-2) 코드디스크립터의 각 코드와 기능 설명입니다.
Here are the descriptions of the codes and functions for the code descriptor.

dw 0xFFFF
-- Limit의 하위 16비트
The lower 16 bits of the Limit
-- 0xCF 안에도 Limit의 상위 4비트가 들어갑니다.
The upper 4 bits of the Limit are also included in 0xCF.
✅ Limit = 상위 4비트(0xF) + 하위16비트(0xFFFF) = 4GB
Limit = Upper 4 bits (0xF) + Lower 16 bits (0xFFFF) = 4GB

dw 0x0000 
-- Base Address 하위 16비트
Lower 16 bits of the base address
-- 세그먼트의 시작 주소입니다.
This is the starting address of the segment.
-- Base = 0x0000

db 0x00 
-- Base Address 16~23bit
-- Base = 0x000000

db 0x9A
-- Access Byte(권한 및 세그먼트 종류)📓
Access Byte (Permissions and Segment Type)

db 0xCF
-- 11001111에서 1100은 플래그📓, 1111은 Limit의 상위 4비트입니다.
In 11001111, 1100 represents the flags 📓, and 1111 represents the upper 4 bits of the Limit.

db 0x00
-- Base = 0x00000000
✅ Base Address는 dw 0x0000 , db 0x00 ,db 0x00를 조합해서 32비트를 만듭니다.
The Base Address is formed as a 32-bit value by combining `dw 0x0000`, `db 0x00`, and `db 0x00`.

📓 접근권한바이트 / Access Byte

— 0x9A = 10011010

비트/Bit이름/Name값/Vale설명/Description
7P(Present)1메모리에 존재
Resides in memory
6~5DPL00Ring0
4S1Code/Data 세그먼트
Code/Data segment
3E1실행 가능Feasible(Code)
2C0Conforming 안 함
Non-conforming
1R1읽기 가능
Readable
0A0CPU가 접근하면 1로 변경
Changes to 1 when accessed by the CPU.
비트/Bit이름/Name값/Vale설명/Description
7P(Present)1메모리에 존재
Resides in memory
6~5DPL00Ring0
4S1Code/Data 세그먼트
Code/Data segment
3E1실행 가능Feasible(Code)
2C0Conforming 안 함
Non-conforming
1R1읽기 가능
Readable
0A0CPU가 접근하면 1로 변경
Changes to 1 when accessed by the CPU.

📓 플래그 / Flags

— 1100(G D L AVL)

비트
Bit
이름
Name
현재 값
Current Value
의미
Description
7G (Granularity)1Limit를 4KB 단위로 해석합니다.
The limit is interpreted in 4KB units.
6D (Default Operation Size)132비트 코드/데이터
32-bit code/data
5L (Long Mode)064비트 아님
Not 64-bit
4AVL (Available)0운영체제가 자유롭게 사용하는 비트
bits freely used by the operating system

1)G (Granularity)

1-1) G=0이면 Limit를 1바이트 단위로 해석합니다.Limit = 100이면 100Byte까지만 사용 할 수 있습니다.
If G=0, the limit is interpreted in 1-byte units. If Limit = 100, only up to 100 bytes can be used.

1-2)G=1이면 Limit를 4KB 단위로 해석합니다.100 × 4096 Byte를 사용 할 수 있습니다.
If G=1, the Limit is interpreted in 4 KB units; 100 × 4,096 bytes can be used.

1-3)현재 코드에서 0xFFFFF(1,048,575) × 4096 + 4095 = 4GB이 됩니다.
In the current code, 0xFFFFF (1,048,575) × 4096 + 4095 equals 4 GB.

1-4)0~4GB이기 때문에 0xFFFFF(1,048,575) × 4096 이 부분에서 4096은 0~4095까지의 값입니다.
Since the range is 0 to 4 GB, in the expression 0xFFFFF (1,048,575) × 4096, the value 4096 represents the range from 0 to 4095.

1-5)그래서 메모리 전체 용량은 1~4GB가 아니라 0~4GB를 사용 할 수 있습니다.
Therefore, the total usable memory capacity is 0 to 4 GB, rather than 1 to 4 GB.

1-6)1~4GB에 대한 계산은 0xFFFFF(1,048,575) × 4096 입니다.
The calculation for 1–4 GB is 0xFFFFF (1,048,575) × 4096.

1-7)위의 값에 0에서 부터 1사이의 값인 4095를 더합니다.(4096개에서 0을 빼면 4095)
Add 4095—a value ranging from 0 to 4095—to the value above. (Subtracting 0 from 4,096 yields 4,095.)

1-8)그러면 전체 메모리 용량은 0xFFFFF(1,048,575) × 4096 + 4095 = 4GB 이렇게 됩니다.
Then, the total memory capacity becomes 0xFFFFF (1,048,575) × 4096 + 4095 = 4 GB.

2)D (Default Operation Size)

2-1)CPU가 이 세그먼트를 16비트로 사용할지 32비트로 사용할지를 결정합니다.
It determines whether the CPU uses this segment as 16-bit or 32-bit.

3)L (Long Mode)

3-1)64비트 모드 여부입니다.
Indicates whether 64-bit mode is enabled.

4)AVL (Available)

4-1)운영체제가 자유롭게 사용하는 비트로 cpu는 별로 신경쓰지 않으며 보통 0으로 둡니다.
This is a bit that the operating system is free to use; the CPU generally pays no attention to it and usually leaves it set to 0.


— 데이터 세그먼트 디스크립터
Data segment descriptor

1)코드 세그먼트 디스크립터와 데이터 세그먼트 디스크립터의 Base, Limit, Flags는 동일합니다.
The Base, Limit, and Flags of the code segment descriptor and the data segment descriptor are identical.

2) access byte에서 는 bit3의 설정값이 달라 코드/데이터를 구분합니다.
In the access byte, the setting of bit 3 distinguishes between code and data.

3)그리고 CPU는 그 결과에 따라 bit2와 bit1을 서로 다른 의미(코드에서는 Conforming/Readable, 데이터에서는 Expand Down/Writable)로 해석합니다.
Based on that result, the CPU interprets bits 2 and 1 differently (as Conforming/Readable for code, and as Expand-Down/Writable for data).

2)0x92 = 10010010

비트
Bit
이름
Name

Value
설명
Description
7P (Present)1세그먼트가 메모리에 존재
Segment exists in memory
6~5DPL00Ring 0
4S1시스템 세그먼트가 아니라 Code/Data 세그먼트
Code/Data segment, not a system segment.
3E (Executable)0실행 불가 → 데이터 세그먼트
Non-executable → Data segment
2ED (Expand Down)0일반 데이터 세그먼트
General data segment
1W (Writable)1쓰기 가능
Writable
0A (Accessed)0아직 접근 안 함
Not yet approached.

1)P,DPL,S부분은 코드 세그먼트 디스크립터와 동일합니다.
The P, DPL, and S fields are identical to those of the code segment descriptor.

2)E (Executable)

2-1)이값이 0이면 데이터 세그먼트라고 판단합니다.
If this value is 0, it is determined to be a data segment.

3)ED – Expand Down (데이터 세그먼트 전용으로 사용/Used exclusively for data segments)

3-1)ED = 1이면 스택처럼 높은 주소에서 낮은 주소 방향으로 사용하는 특수한 데이터 세그먼트 입니다.
If ED = 1, it is a special data segment that is used in the direction from high addresses to low addresses, similar to a stack.

3-2)ED = 0이면 일반적인 데이터 세그먼트입니다.
If ED = 0, it is a standard data segment.

4)W

4-1)이 값이 1이면 쓰기가 가능합니다.
If this value is 1, writing is possible.

5)A

5-1)A 비트는 프로그래머가 직접 사용하는 것이 아니라 CPU가 “이 세그먼트를 사용했다”는 표시로 사용하는 비트입니다.
The A-bit is not used directly by the programmer; instead, it is a bit used by the CPU to indicate that “this segment has been used.”


— CPU에게 “GDT가 어디 있는지” 알려주는 구조체입니다.(dw 2byte,dd 4byte)
It is a structure that tells the CPU “where the GDT is.”

gdt_pointer:
    dw gdt_end - gdt_start - 1  ; GDT의 크기 (Size of GDT)
    dd gdt_start                ; GDT의 시작 주소 (Starting address of GDT)

1)lgdt [gdt_pointer] 이 코드에서 사용하기 위한 부분입니다.
This part is intended for use with the lgdt [gdt_pointer] instruction.

2) gdt_end와 gdt_start는 라벨의 위치입니다.
gdt_end and gdt_start are the locations of the labels.

3)gdt_end – gdt_start = 24(8[Null Descriptor]+8[Code Descriptor]+8[Data Descriptor])

4)그래서 dw gdt_end – gdt_start – 1 이 값은 dw 23이 저장 됩니다.
Therefore, the value dw 23 is stored for the expression dw gdt_end - gdt_start - 1.

5)gdt_start는 gdt시작 주소가 저장됩니다.
The starting address of the GDT is stored in gdt_start.

— (sector2.asm) 512바이트에서 데이터로 사용되고 난 나머지 코드는 0으로 맞추는 부분입니다.
(sector2.asm) This section pads the remaining space within the 512 bytes with zeros after the code.

times 512 - ($ - $$) db 0

1) boot.asm에서 다음과 같이 섹터를 1개만 읽어오면 512바이트가 됩니다.
If you read only one sector in boot.asm as shown below, it amounts to 512 bytes.

boot.asm
mov al, 1 → 1섹터 읽음 / 1 Sector Read

secotr2.asm
times 512 - ($ - $$) db 0

2) boot.asm에서 다음과 같이 섹터를 2개를 읽어오면 1024바이트가 됩니다.
If you read two sectors in boot.asm as shown below, it amounts to 1024 bytes.

boot.asm
mov al, 2 → 2섹터 읽음 / 2 Sector Read

sector2.asm
times 1024 - ($ - $$) db 0

3) boot.asm에서 다음과 같이 섹터를 3개를 읽어오면 1536바이트가 됩니다.
If you read three sectors in boot.asm as shown below, it amounts to 1,536 bytes.

boot.asm
mov al, 3 → 3섹터 읽음 / 3 Sector Read

sector2.asm
times 1536 - ($ - $$) db 0

Leave a Reply