실제 코드로 구현 하면 아래와 같다.
더 자세히 ...
실제 코드로 구현 하면 아래와 같다.
- 작성자
- Sung-jae Park nices.nosp@m.j@ni.nosp@m.cesj..nosp@m.com
- 날짜
- 2011-7-18
x86 에서 지원되는 Memory 영역에 대한 Descriptor 관련 코드를 구현한다. MRD(Memory Range Descriptor)는 Stage 2 Loader 에서 Protected mode 로 전환하기 직전에 BIOS 가 제공하는 Service 를 이용해서 확보했다. E820 Method 로 Bios Service Routine 0x15 번에서 제공되고 있다.
아래 Table 은 ACPI Spec 문서에서 scrap 해 온 것이다.
| Input |
| Register | Contents | Description |
| EAX | Function Code | E820h |
| EBX | Continuation | Contains the continuation value to get the next range of physical memory. This is the value returned by a previous call to this routine. If this is the first call, EBX must contain ZERO. |
| ES:DI | Buffer Pointer | Pointer to an Address Range Descriptor structure that the BIOS fills in. |
| ECX | Buffer Size | The length in bytes of the structure passed to the BIOS. The BIOS fills in the number of bytes of the structure indicated in ECX register, maximum, or whatever amount of structure the BIOS implements. The minimum size that must be supported by both the BIOS and the caller is 20 bytes. Future implementations might extend this structure. |
| EDX | Signature | 'SMAP' Used by the BIOS to verify caller is requesting the system map information to returned in ES:DI |
|
| Output |
| Register | Contents | Description |
| CF | Carry Flag | Non-Carry - Indicates No Error |
| EAX | Signature | 'SMAP' Signature to verify correct BIOS revision |
| ES:DI | Buffer Pointer | Returned Address Range Descriptor pointer. Same value as on input |
| ECX | Buffer Size | Number of bytes returned by the BIOS in the address range descriptor. The minimum size structure returned by the BIOS is 20 bytes. |
| EBX | Continuation | Contains the continuation value to get the next address range descriptor. The actual significance of the continuation value is up to the discretion of the BIOS. The caller must pass the continuation value unchanged as input to the next iteration of the E820 call in order to get the next Address Range Descriptor. A return value of zero means that this is the last descriptor. Note: the BIOS can also indicate that the last descriptor has already been returned during previous iterations by returning the carry flag set. The caller will ignore any other information returned by the BIOS when the carry flag is set. |
|
이 Service Routine 은 다음 데이터를 return 한다.
| Offset in Bytes | Name | Description |
| 0 | BaseAddrLow | Low 32 Bits of Base Address |
| 4 | BaseAddrHigh | High 32 Bits of Base Address |
| 8 | LengthLow | Low 32 Bits of Length in Bytes |
| 12 | LengthHigh | High 32 Bits of Length in Bytes |
| 16 | Type | Address type of this range
| Value | Mnemonic | Description |
| 1 | AddressRangeMemory | This range is available RAM usable by the operating system. |
| 2 | AddressRangeReserved | This range of addresses is in use or reserved by the system and is not to be included in the allocatable memory pool of the operating system's memory manager. |
| 3 | AddressRangeACPI | ACPI Reclaim Memory. This range is available RAM usable by the OS after it reads the ACPI tables. |
| 4 | AddressRangeNVS | ACPI NVS Memory. This range of addresses is in use or reserve by the system and must not be used by the operating system. This range is required to be saved and restored across an NVS sleep. |
| 5 | AddressRangeUnusable | This range of addresses contains memory in which errors have been detected. This range must not be used by OSPM. |
| 6 | AddressRangeDisabled | This range of addresses contains memory that is not enabled. This range must not be used by OSPM. |
| Other | Undefined | Undefined. Reserved for future use. OSPM must treat any range of this type as if the type returned was AddressRangeReserved. |
- 주의
- The BIOS can use the AddressRangeReserved address range type to block out various addresses as not suitable for use by a programmable device. Some of the reasons a BIOS would do this are:
-
The address range contains system ROM.
-
The address range contains RAM in use by the ROM.
-
The address range is in use by a memory-mapped system device.
-
The address range is, for whatever reason, unsuitable for a standard device to use as a device memory space.
-
The address range is within an NVRAM device where reads and writes to memory locations are no longer successful, that is, the device was worn out.
|
| 20 | Extended Attributes |
| Bits | Mnemonic | Description |
| 0 | Reserved | Reserved. Must be set to 0 |
| 1 | AddressRangeNonVolatile | If set, the Address Range Descriptor represents non-volatile memory. Memory reported as non-volatile may require characterization to determine its suitability for use as conventional RAM |
| 2 | AddressRangeSlowAccess | If set, accesses to the described range may incur considerable latencies |
| 3 | AddressRangeErrorLog | If set, the address range descriptor represents memory used for logging hardware errors. |
| 4-31 | Reserved | Reserved for future use |
|
- 주의
-
The BIOS returns address ranges describing baseboard memory.
-
The BIOS does not return a range description for the memory mapping of PCI devices, ISA Option ROMs, and ISA Plug and Play cards because the OS has mechanisms available to detect them.
-
The BIOS returns chip set-defined address holes that are not being used by devices as reserved.
-
Address ranges defined for baseboard memory-mapped I/O devices, such as APICs, are returned as reserved.
-
All occurrences of the system BIOS are mapped as reserved, including the areas below 1 MB, at 16 MB (if present), and at end of the 4-GB address space.
-
Standard PC address ranges are not reported. For example, video memory at A0000 to BFFFF physical addresses are not described by this function. The range from E0000 to EFFFF is specific to the baseboard and is reported as it applies to that baseboard.
-
All of lower memory is reported as normal memory. The OS must handle standard RAM locations that are reserved for specific uses, such as the interrupt vector table (0:0) and the BIOS data area (40:0).
다만, 이 Service Routine 을 사용하기 위해서는 Real Mode (16 bits) 여야 하기 때문에, Protected Mode 로 전환하기 전에, MRD 들을 얻어 오고, 특정 메모리 영역에 저장한 다음에 Stage 2 로 이동하여 해당 정보를 사용하도록 한다.
; Get the memory from the ACPI (E820h) services
mov dword [KERNEL_ARGUMENT], 0
xor ebx, ebx ; Continuation
mov es, ebx ; ES
mov edi, KERNEL_ARGUMENT + 4 ; DI (ES:DI) location of storing data
mov ecx, 20 ; Buffer size, 20 bytes
mov edx, 0x534d4150 ; Signature
e820_get_desc:
mov eax, 0x0000E820 ; function ID
clc ; Clear carry flag
int 0x15 ; Invoke interrupt 0x15
jc e820_error ; Check the carry flag
cmp eax, 0x534d4150 ; Check the signature
jne e820_error
cmp ecx, 20 ; Check the minimum size of descriptor
jl no_e820
add edi, ecx ; Move pointer to next
cmp edi, E820_BOUND ; Compare the boundary of memory for descriptors
jge e820_overflow
inc dword [KERNEL_ARGUMENT]
cmp ebx, 0 ; Check the continuation value
jne e820_get_desc
Type of Memory Range Descriptor.
| 열거형 멤버 |
|---|
| MRD_UNKNOWN |
Unknown
|
| MRD_MEMORY |
AddressRangeMemory
|
| MRD_RESERVED |
AddressRangeReserved
|
| MRD_ACPI |
AddressRangeACPI
|
| MRD_NVS |
AddressRangeNVS
|
| struct mrd* mrd_base |
( |
void |
) | |
|
MRD 가 저장된 Base 주소를 반환한다.
- 반환값
- MRD 가 저장된 Base 주고
Descriptor 의 총 개수를 반환한다.
- 반환값
- Descriptor 의 전체 개수
| void* mrd_get_base |
( |
int |
idx) | |
|
지정된 인덱스에 해당하는 Descriptor 의 시작 주소를 반환한다.
- 매개변수
-
- 반환값
- Index 에 해당하는 Descriptor 의 시작주소
| unsigned long mrd_get_size |
( |
int |
idx) | |
|
지정된 Index에 해당하는 Descriptor 가 가리키는 영역의 크기를 반환
- 매개변수
-
- 반환값
- Index에 해당하는 Descriptor 가 가리키는 영역의 크기
| int mrd_get_type |
( |
int |
idx) | |
|
지정된 인덱스에 해당하는 Descriptor 의 종류를 반환한다.
- 매개변수
-
- 반환값
- Index 에 해당하는 Descriptor 의 종류
| void mrd_init |
( |
void * |
addr) | |
|
MRD 관리자를 초기화한다.
- 반환값
- void 없음