Getting The Amount Of RAM
Getting The Amount Of RAM
Hi again
I seem to run into a new problem daily... Anyhow I'm trying to get the amount of RAM available.
...EDIT (see later posts)...
Sorry for asking sooo many questions recently .
Lster
I seem to run into a new problem daily... Anyhow I'm trying to get the amount of RAM available.
...EDIT (see later posts)...
Sorry for asking sooo many questions recently .
Lster
Last edited by Lprogster on Sun May 13, 2007 4:05 am, edited 1 time in total.
- Brynet-Inc
- Member
- Posts: 2426
- Joined: Tue Oct 17, 2006 9:29 pm
- Libera.chat IRC: brynet
- Location: Canada
- Contact:
Since he states he isn't using GRUB (and he didn't mention any other ready-made bootloader), presumably he's writing his own and can use the BIOS from there, before entering PM (assuming he enters it at all).Brynet-Inc wrote:Are you in protected mode? If you are you can't use BIOS interrupts..
Of course, that's still a requirement he must take care to follow: only use the BIOS interrupts if in real mode (or VM86).
Parts of BIOS memory that can be used without calling interrupts (video memory at 0xb8000 in text mode, the VBE3 protected mode interface, etc.) are fine even in protected mode, of course...
- mathematician
- Member
- Posts: 437
- Joined: Fri Dec 15, 2006 5:26 pm
- Location: Church Stretton Uk
Hi,
You should be able to use 32-bit registers for 80386 and later CPUs, and I don't think Qemu can emulate 80286 or older CPUs.
I'd be tempted to think there's other problems, like something corrupting/overwriting your code, something corrupting/overwriting data used by the BIOS (IVT, BDA, EBDA), using a bad location for your stack, forgetting to use "bits 16", not loading the entire thing from disk, bugs in (your version of) Qemu, accidentally booting an old version of your code and wondering why it behaves the same, etc.
Single stepping through the code to see exactly what is happening would help too - I'm not sure if Qemu supports this or not. Trying your code on Bochs might be a good idea anyway (if it has the same problem on Bochs, then you could be reasonably sure it's not caused by bugs in your version of Qemu).
Cheers,
Brendan
Are you sure about this?Lprogster wrote:I can't seem to use EAX, EDX, EBX and ECX in 16 bit mode.
You should be able to use 32-bit registers for 80386 and later CPUs, and I don't think Qemu can emulate 80286 or older CPUs.
I'd be tempted to think there's other problems, like something corrupting/overwriting your code, something corrupting/overwriting data used by the BIOS (IVT, BDA, EBDA), using a bad location for your stack, forgetting to use "bits 16", not loading the entire thing from disk, bugs in (your version of) Qemu, accidentally booting an old version of your code and wondering why it behaves the same, etc.
Single stepping through the code to see exactly what is happening would help too - I'm not sure if Qemu supports this or not. Trying your code on Bochs might be a good idea anyway (if it has the same problem on Bochs, then you could be reasonably sure it's not caused by bugs in your version of Qemu).
Cheers,
Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
Do you have "bits 16" at the top of your code?
Maybe an example will help.
The following works for me: (bs.asm)
Assemble with (or nasmw if you're on Windows) and run with
It should print the memory map to the screen (in hexadecimal). On my QEMU, the result is (modulo typos)
I'm using QEMU 0.8.2. It also works in my Bochs (2.3).
Maybe an example will help.
The following works for me: (bs.asm)
Code: Select all
org 0x7c00
bits 16
main:
; clear screen
mov ax, 0xb800
mov es, ax
mov fs, ax ; needed later
xor di, di
mov ax, 0x0720
mov cx, 25*80
rep stosw
xor bp, bp ; needed later as well
; set up stack and ds, es
mov ss, bp
mov ds, bp
mov es, bp
mov sp, 0x7c00
; Initial value for interrupt
xor ebx, ebx
.iter:
; Preserved:
; ebx -- continuation
; fs:ebp -- screen position
; ss:esp -- stack
; Clobbered:
; eax
; es
; ds
; edx
; ecx
; esi
; edi
mov di, 0x500
mov eax, 0x0000E820
mov edx, 0x534D4150
mov ecx, 20
int 0x15
jc .halt
mov si, di
lodsd
mov [low], eax
lodsd
mov [high], eax
call printhex
mov eax, [low]
call printhex
mov ax, '-'
call printchar
lodsd
add [low], eax
lodsd
adc [high], eax
mov eax, [high]
call printhex
mov eax, [low]
call printhex
mov ax, ':'
call printchar
lodsd
call printhex
call newline
cmp ebx, 0
je .ebxzero
jmp .iter
.ebxzero:
mov word [fs:24*80*2+1], 'Z'
.halt:
mov word [fs:24*80*2], 'D' | 0x0700
cli
hlt
jmp .halt
; Requires:
; eax -- number to print
; fs:ebp -- preserved
; Clobbers:
; ecx
; edx
; eax
printhex:
mov edx, eax
mov cx, 8
.loop:
push cx
; prepare shift
dec cx
shl cx, 2
; apply shift
mov eax, edx
shr eax, cl
pop cx
; mask one digit
and eax, 0xf
; print digit
mov ax, [hexdigs+eax] ;; reads one byte too much
mov ah, 0 ;; clear extra byte
call printchar
loop .loop
ret
; Requires:
; fs:ebp -- Next character on screen
; al -- character to print
; Clobbers:
; ah
printchar:
mov ah, 0x07
mov word [fs:bp], ax
add bp, 2
ret
newline:
mov bp, [line]
add bp, 80 * 2
mov [line], bp
cmp bp, 24*80*2
jae main.halt
ret
low: dd 0 ; The low 32 bits of a 64-bit address
high: dd 0 ; The high 32 bits of a 64-bit address
hexdigs:db "0123456789abcdef" ; Obvious :)
line: dw 0 ; The location of the next line
times 510-($ - $$) db 0
db 0x55, 0xAA
Code: Select all
nasm -f bin -o bs.bin bs.asm
Code: Select all
qemu -fda bs.bin
Code: Select all
0000000000000000-000000000009fc00:00000001
0000000000100000-0000000008000000:00000001
I'm using QEMU 0.8.2. It also works in my Bochs (2.3).
The reason the code is failing is because int 13h ah=0 (Reset drive) expects the drive number in DL (also int 0x13 ah=2 expects the drive number in dl and head in dh) You are getting stuck in an infinite loop constantly resetting the drive.
You are thrashing EDX with the E820 magic number. The BIOS sets dl to the ID of the boot drive before when loading your boots sector. If you want to get the memory map before reading from disk, you should save the value of DL before thrashing it.
Tip: when debugging these sort of things it helps to poke chars to the screen in various places so that you can see the exact flow of the code.
HTH
Shecks
You are thrashing EDX with the E820 magic number. The BIOS sets dl to the ID of the boot drive before when loading your boots sector. If you want to get the memory map before reading from disk, you should save the value of DL before thrashing it.
Tip: when debugging these sort of things it helps to poke chars to the screen in various places so that you can see the exact flow of the code.
HTH
Shecks
- Brynet-Inc
- Member
- Posts: 2426
- Joined: Tue Oct 17, 2006 9:29 pm
- Libera.chat IRC: brynet
- Location: Canada
- Contact:
The attached code prints the '!' in the top corner...
Hope this helps..
Hope this helps..
- Attachments
-
- boot.asm
- Fixed code..
- (1.72 KiB) Downloaded 118 times
- Brynet-Inc
- Member
- Posts: 2426
- Joined: Tue Oct 17, 2006 9:29 pm
- Libera.chat IRC: brynet
- Location: Canada
- Contact:
That's a tough one.. I'm guessing the best way would be to do it before switching into protected mode, storing the value some how?neon wrote:Rather then starting a new thread on the same subject...
How would one find out the amount of RAM available in pmode?
Just curious...
If you use grub, You can find out the amount of ram using multiboot_info structure..