Нахождение объема памяти в Boot без DOS, Windows, Linux

Я пишу простую программу на ассемблере (NASM). Когда загрузочный сектор загружается, он должен отображать всю память (RAM), установленную на компьютере, в мегабайтах. При загрузке загрузочного сектора операционной системы (DOS, Windows, Linux) не будет, так как узнать общий объем ОЗУ? У меня 2 ГБ оперативной памяти на моем компьютере. Я много искал в Интернете, но не смог найти решение.

Есть ли прерывание BIOS, которое показывает объем памяти 2 ГБ? Существует прерывание, которое использовалось на старых компьютерах для отображения памяти, но не все 2 ГБ. Я проверил, и нет никакого решения для этого в списке Ральфа Брауна. Может быть, кто-то знает больше о BIOS. Если BIOS не предоставляет эту возможность, могу ли я использовать C / C ++ для определения общего объема оперативной памяти? И вызывать C / C ++ код из сборки? Какая функция C / C ++ будет использоваться для определения общего объема оперативной памяти?

Помните, что мой ассемблерный код будет выполнять холодную загрузку, и не будет никакой операционной системы, которая бы обеспечивала мой код каким-либо средством.

Редакция:

Я читаю сайт http://wiki.osdev.org/Detecting_Memory_%28×86%29. И решил проверить, работает ли int 15. Поэтому я получил код с этого сайта и отредактировал его, чтобы проверить, работает ли int 15 EAX = E820. Но он не работает, и вывод «F» в .failed1. «F» — это тестовый пример, который я сделал для проверки «неподдерживаемой функции». Тестовые случаи: «F», «G» и «H». Вот код

; use the INT 0x15, eax= 0xE820 BIOS function to get a memory map
; inputs: es:di -> destination buffer for 24 byte entries
; outputs: bp = entry count, trashes all registers except esi
do_e820:

xor ebx, ebx     ; ebx must be 0 to start
xor bp, bp       ; keep an entry count in bp
mov edx, 0x0534D4150 ; Place "SMAP" into edx
mov eax, 0xe820
mov [es:di + 20], dword 1    ; force a valid ACPI 3.X entry
mov ecx, 24      ; ask for 24 bytes
int 0x15
jc short .failed1    ; carry set on first call means "unsupported function"mov edx, 0x0534D4150 ; Some BIOSes apparently trash this register?
cmp eax, edx     ; on success, eax must have been reset to "SMAP"jne short .failed2
test ebx, ebx        ; ebx = 0 implies list is only 1 entry long (worthless)
je short .failed3
jmp short .jmpin

.e820lp:
mov eax, 0xe820      ; eax, ecx get trashed on every int 0x15 call
mov [es:di + 20], dword 1    ; force a valid ACPI 3.X entry
mov ecx, 24      ; ask for 24 bytes again
int 0x15
jc short .e820f      ; carry set means "end of list already reached"mov edx, 0x0534D4150 ; repair potentially trashed register

.jmpin:
jcxz .skipent        ; skip any 0 length entries
cmp cl, 20       ; got a 24 byte ACPI 3.X response?
jbe short .notext
test byte [es:di + 20], 1    ; if so: is the "ignore this data" bit clear?
je short .skipent

.notext:
mov ecx, [es:di + 8] ; get lower dword of memory region length
or ecx, [es:di + 12] ; "or" it with upper dword to test for zero
jz .skipent      ; if length qword is 0, skip entry
inc bp           ; got a good entry: ++count, move to next storage spot
add di, 24

.skipent:
test ebx, ebx        ; if ebx resets to 0, list is complete
jne short .e820lp

.e820f:
mov [mmap_ent], bp   ; store the entry count
clc          ; there is "jc" on end of list to this point, so the carry must be cleared

mov ah, 0x0E       ; Teletype command
mov bh, 0x00       ; Page number
mov bl, 0x07       ; Attributes (7 == white foreground, black background)
mov al, mmap_ent   ; Character to print
int 0x10

ret

.failed1:
push eax
push ebx
mov ah, 0x0E       ; Teletype command
mov bh, 0x00       ; Page number
mov bl, 0x07       ; Attributes (7 == white foreground, black background)
mov al, 70 ; Character 'F' to print
int 0x10
pop ebx
pop eax

stc          ; "function unsupported" error exit
ret

.failed2:
push eax
push ebx
mov ah, 0x0E       ; Teletype command
mov bh, 0x00       ; Page number
mov bl, 0x07       ; Attributes (7 == white foreground, black background)
mov al, 71 ; Character 'G' to print
int 0x10
pop ebx
pop eax

stc          ; "function unsupported" error exit
ret

.failed3:
push eax
push ebx
mov ah, 0x0E       ; Teletype command
mov bh, 0x00       ; Page number
mov bl, 0x07       ; Attributes (7 == white foreground, black background)
mov al, 72 ; Character 'H' to print
int 0x10
pop ebx
pop eax

stc          ; "function unsupported" error exit
retmmap_ent db 0
failmsg db 0
failmem db 'Failed', 0
;times 512-($-$$) db 0
;dw 0xAA55

Редакция:

Я использовал nasm memext.asm -o memext.com -l memext.lst. Использовал MagicISO для создания загрузочного образа файла memext.iso, а для записи на DVD / RW — на устройство записи дисков Windows. Загрузил Oracle VM и создал новую виртуальную машину с 256 МБ ОЗУ, CD / DVD, жестким диском объемом 2 ГБ. Загрузился с DVD для теста холодной загрузки, ничего не печатает.

Кроме того, я открываю командную консоль и просто набираю memext, и в качестве результата она выдает «F».

1

Решение

Вам нужно будет прочитать таблицы ACPI на ПК (или на других компьютерах, поддерживающих ACPI).

Обратите внимание, что это не даст вам общий размер в виде одного числа, но даст вам объем памяти каждой области памяти — на простой машине, которая может быть просто двумя или тремя областями (в «дыре» нет места 0xA0000-0xFFFFF и везде, где BIOS решает поставить «PCI-дыру»).

Я подозреваю, что не совсем просто встроить считыватель ACPI в один сектор, учитывая, что у некоторого загрузочного сектора есть только около 400 байт доступного пространства (хотя, если вы полностью пропустите таблицу разделов, я предполагаю, что вы можете использовать почти все из 512 байт).

Что касается «как вызывать C / C ++», вы не сможете разместить какую-либо значимую программу на C или C ++ менее чем в нескольких секторах. Вам нужно будет взглянуть на загрузчик ОС и посмотреть, как они выполняют настройку компилятора (и во многих случаях вам также понадобятся специальные инструменты для создания кода, который находится в определенном месте, подходящем для загрузки в память). и прямо исполнено). Эта страница может быть полезна для этого (я не прочитал все это, она может даже сказать, сколько у вас памяти): http://www.codeproject.com/Articles/36907/How-to-develop-your-own-Boot-Loader

4

Другие решения

РЕДАКТИРОВАТЬ: моя ошибка, вики правильно, просто оставив это здесь, потому что …

Похоже, в вики есть опечатка — строка:

mov edx,0x0534D4150

должен выглядеть так:

mov edx,0x050414D53

Обратите внимание, что байты расположены в обратном порядке (поскольку x86 имеет младший порядок байтов).

1