Page 1 of 1

Getting The Amount Of RAM

Posted: Sat May 12, 2007 5:12 am
by Lprogster
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

Posted: Sat May 12, 2007 7:01 am
by Brynet-Inc
Could you perhaps tell a little more about your OS?

Are you in protected mode? If you are you can't use BIOS interrupts..

Posted: Sat May 12, 2007 7:19 am
by Lprogster
...

Thanks,
Lster

Posted: Sat May 12, 2007 7:21 am
by urxae
Brynet-Inc wrote:Are you in protected mode? If you are you can't use BIOS interrupts..
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).
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...

Posted: Sat May 12, 2007 8:10 am
by mathematician
Shouldn't int 15 be int 0x15?

Posted: Sat May 12, 2007 8:32 am
by urxae
mathematician wrote:Shouldn't int 15 be int 0x15?
Yes. Yes it should. Good catch :). (Just tested his code with that modification)

Posted: Sat May 12, 2007 9:10 am
by Lprogster
Even changing that doesn't help. Any ideas?

Thanks,
Lster

Posted: Sat May 12, 2007 10:32 am
by Brendan
Hi,
Lprogster wrote:I can't seem to use EAX, EDX, EBX and ECX in 16 bit mode.
Are you sure about this?

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

Posted: Sat May 12, 2007 10:33 am
by urxae
Do you have "bits 16" at the top of your code?

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
Assemble with

Code: Select all

nasm -f bin -o bs.bin bs.asm
(or nasmw if you're on Windows) and run with

Code: Select all

qemu -fda bs.bin
It should print the memory map to the screen (in hexadecimal). On my QEMU, the result is

Code: Select all

0000000000000000-000000000009fc00:00000001
0000000000100000-0000000008000000:00000001
(modulo typos)

I'm using QEMU 0.8.2. It also works in my Bochs (2.3).

Posted: Sat May 12, 2007 1:33 pm
by Lprogster
...

Thanks guys...
Lster

Posted: Sat May 12, 2007 2:14 pm
by Shecks
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

Posted: Sat May 12, 2007 4:14 pm
by Brynet-Inc
The attached code prints the '!' in the top corner...

Hope this helps.. :)

Posted: Sun May 13, 2007 4:10 am
by Lprogster
Life is good... again :D!

Thanks everyone soooooo much,
Lster

Posted: Sun May 13, 2007 7:55 pm
by neon
Rather then starting a new thread on the same subject...

How would one find out the amount of RAM available in pmode?
Just curious...

Posted: Sun May 13, 2007 8:27 pm
by Brynet-Inc
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...
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? :?

If you use grub, You can find out the amount of ram using multiboot_info structure..