RAM size? BIOS or other? [Working]

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
User avatar
Dex
Member
Member
Posts: 1444
Joined: Fri Jan 27, 2006 12:00 am
Contact:

Post by Dex »

LordMage wrote:

Code: Select all


bits 32

Stage3:

	;-------------------------------;
	;   Set registers		;
	;-------------------------------;
	  
	mov	ax, 0x10		; set data segments to data selector (0x10)
	mov	ds, ax
	mov	ss, ax
	mov	es, ax
	mov fs, ax
	mov gs, ax
	mov	esp, 90000h		; stack begins from 90000h
	;HERE IN YOU CODE DO THIS
   call TestRam
	push [ExtMemorySize]
	push [TotalMemoryMB]
	
Add these function to you code

Code: Select all

 ;----------------------------------------------------;
 ; TestRam                                            ;
 ;----------------------------------------------------;
TestRam:
        pushad
        mov   eax,dword[TotalMemoryMB]
        rol   eax,8
        push  eax
        push  eax
        shr   al,4
        call  hexget
        mov   byte [fs:0xB8090], al
        pop   eax
        call  hexget
        mov   byte [fs:0xB8092], al
        pop   eax
        rol   eax,8
        push  eax
        push  eax
        shr   al,4
        call  hexget
        mov   byte [fs:0xB8094], al
        pop   eax
        call  hexget
        mov   byte [fs:0xB8096], al
        pop   eax
        rol   eax,8
        push  eax
        push  eax
        shr   al,4
        call  hexget
        mov   byte [fs:0xB8098], al
        pop   eax
        call  hexget
        mov   byte [fs:0xB809A], al
        pop   eax
        rol   eax,8
        push  eax
        push  eax
        shr   al,4
        call  hexget                                      
        mov   byte [fs:0xB809C], al
        pop   eax
        call  hexget
        mov   byte [fs:0xB809E], al
        pop   eax
        popad
        ret

 ;----------------------------------------------------;
 ; hexget                                             ;
 ;----------------------------------------------------;
hexget:
        and   eax,0x0000000f
        or    eax,0x00000030
        cmp   eax,0x39
        ja    add7
        ret
add7:   add   eax,7             
        ret
This should print a hex number in the top right hand corner, report back what it prints.
If you have 32mb of ram, it should print 20 .
User avatar
bewing
Member
Member
Posts: 1401
Joined: Wed Feb 07, 2007 1:45 pm
Location: Eugene, OR, US

Post by bewing »

LordMage wrote:okay, I tried to push the contents like he suggested but I got the same answer, I must be doing something wrong but I really don't know what. is there anything else wrong with my code? Can I actually make something in my stage2 bootloader globally available so that my kernel can see it also?
Of course you can. I would very much suggest it, in fact. It's much harder to move a stack properly, than it is to use a table at an absolute address.
One thing that is absolutely guaranteed on all PCs is that "low" memory, from 0x500 to 0x9ffdf is completely available. There cannot be any holes, any hardware remappings, or anything at all except pure plain vanilla RAM. All of that memory (almost 639K) is available for passing data in absolute (known) memory locations. All you need to do is have your bootloader create a table there, and have your kernel pick it back up. Of course, this is PHYSICAL memory, so if you wait until virtual page mapping is turned on, you may need to unmap it.

Code: Select all

TotMem	equ	0x1000

... middle of bootloader code ...
	call get_RAMsize	; returns total amt of ram in EAX
	mov [TotMem], EAX	; Intel (not at&t) syntax

... bootloader boots kernel written in C

... in kernel code somewhere
#define		TotMem	0x1000
unsigned long ram_from_bios;

	ram_from_bios= *((unsigned long *) TotMem);
But, of course, as Brendan is saying -- in the end you won't just be passing one 32bit value, you will have an entire table stored at some KNOWN absolute physical address in low mem.
LordMage
Member
Member
Posts: 115
Joined: Sat Sep 22, 2007 7:26 am
Contact:

Post by LordMage »

I went the shorter route and took Bewings advice, it worked!!!! :) I do appreciate the hex routine though Dex. I was wanting one of those and will use it. The good news though is that I am seeing 32 now which is the correct amount of ram so now I can modify and calculate to give me what I need for my plans. Thanks again :)
Getting back in the game.
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Post by Brendan »

Hi,
bewing wrote:One thing that is absolutely guaranteed on all PCs is that "low" memory, from 0x500 to 0x9ffdf is completely available.
That is not guaranteed. Do a web search for "EBDA too big" and see how many hits you get because some LILO programmer made the same assumption...

The 512 KB area from 0x00000000 to 0x00080000 is guaranteed to be nice, contiguous, usable RAM though. ;)
bewing wrote:There cannot be any holes, any hardware remappings, or anything at all except pure plain vanilla RAM.
Strange you should say "holes". Take a look at the datasheets for Intel 945 chipsets - it actually does support a hole from 0x00080000 to 0x000A0000. I doubt any motherboards actually use this hole, but the chipset supports it.

Also, the PXE specification (for booting from network) says the BIOS/ROM/etherboot networking code can freely use the area from 0x00080000 to the start of the EBDA, so it's good to leave this area untouched while your booting.


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.
User avatar
bewing
Member
Member
Posts: 1401
Joined: Wed Feb 07, 2007 1:45 pm
Location: Eugene, OR, US

Post by bewing »

Brendan wrote: Do a web search for "EBDA too big" and see how many hits you get
OK, I'll do that -- OK, the answer is only 4000 on google; I knew that there might be a little space at the end of page 9 used by BIOS; multiple K for the EBDA is completely excessive (low memory is precious during bootup, and people would have to be idiots to f*ck it up with a damned table like this); and it would be really nice if someone would write a wiki entry about this stupid "feature" somewhere -- since there are no obvious search results, and the OSDev wiki has unfulfilled references to the EBDA.
Brendan wrote: The 512 KB area from 0x00000000 to 0x00080000 is guaranteed to be nice, contiguous, usable RAM though. ;)
Except that the real mode IDT takes up the first K, and you don't really want to lose that -- and the BIOS trashes bytes in the next 0x100 bytes every 18th of a second.
Brendan wrote: Also, the PXE specification (for booting from network) says the BIOS/ROM/etherboot networking code can freely use the area from 0x00080000 to the start of the EBDA, so it's good to leave this area untouched while your booting.
But then you're booting off an entirely different bootloader anyway.
If a disk-based bootloader knows that it is booting itself, it already knows you are not booting off a network.
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Post by Brendan »

Hi,
bewing wrote:
Brendan wrote:Do a web search for "EBDA too big" and see how many hits you get
OK, I'll do that -- OK, the answer is only 4000 on google; I knew that there might be a little space at the end of page 9 used by BIOS; multiple K for the EBDA is completely excessive (low memory is precious during bootup, and people would have to be idiots to f*ck it up with a damned table like this); and it would be really nice if someone would write a wiki entry about this stupid "feature" somewhere -- since there are no obvious search results, and the OSDev wiki has unfulfilled references to the EBDA.
Try to imagine writing code that handles as much as a modern BIOS does with less than 5 KB of ".bss", where most of that space must match code written over 20 years ago (before there were things like PCI BIOS, Multiprocessor specification, ACPI, SMM, Plug & Play, DMTF/SMBIOS, boot from CD/USB and floppy/had disk emulation, etc).

There is no complete reference for the EBDA that every BIOS complies with, just like there's no complete reference for kernel data that all OS's comply with.
bewing wrote:
Brendan wrote:The 512 KB area from 0x00000000 to 0x00080000 is guaranteed to be nice, contiguous, usable RAM though. ;)
Except that the real mode IDT takes up the first K, and you don't really want to lose that -- and the BIOS trashes bytes in the next 0x100 bytes every 18th of a second.
It's still usable RAM, even if it is temporarily unusable before the switch to protected mode.
bewing wrote:
Brendan wrote:Also, the PXE specification (for booting from network) says the BIOS/ROM/etherboot networking code can freely use the area from 0x00080000 to the start of the EBDA, so it's good to leave this area untouched while your booting.
But then you're booting off an entirely different bootloader anyway.
If a disk-based bootloader knows that it is booting itself, it already knows you are not booting off a network.
Not necessarily. From this web site:
MEMDISK simulates a disk by claiming a chunk of high memory for the
disk and a (very small - 2K typical) chunk of low (DOS) memory for the
driver itself, then hooking the INT 13h (disk driver) and INT 15h
(memory query) BIOS interrupts.
Just because your OS booted from a floppy, doesn't mean it didn't boot from an emulated floppy (where the floppy emulation code runs on top of etherboot/netboot to access a floppy image on a remote machine).


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.
User avatar
bewing
Member
Member
Posts: 1401
Joined: Wed Feb 07, 2007 1:45 pm
Location: Eugene, OR, US

Post by bewing »

Brendan wrote: Try to imagine writing code that handles as much as a modern BIOS does with less than 5 KB of ".bss"
Well, the BIOS tests (and therefore can access) upper memory -- so it's stupid for it to put stuff in low mem. Also, if the BIOS didn't lock the 128k below 1M, it would have plenty of ram to play with there.
Brendan wrote: There is no complete reference for the EBDA
Ugh. I'd think they'd have learned their lesson over the years about the concept of "standards". Guess not.
Brendan wrote: It's still usable RAM, even if it is temporarily unusable before the switch to protected mode.
Yes, but precisely the same comment could be applied to the EBDA itself, too. :wink:
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Post by Brendan »

Hi,
bewing wrote:
Brendan wrote:There is no complete reference for the EBDA
Ugh. I'd think they'd have learned their lesson over the years about the concept of "standards". Guess not.
Can you find any standard that says the OS can use more than 512 KB of memory below 1 MB (or a standard that says the BIOS can't have a large EBDA from 0x00080000 to 0x0009FFFF)? I'd think OS developers would have learned their lesson over the years about the concept of "standards" (e.g. the standard BIOS "Int 0x12" function). I'd guess they haven't (although LILO did fix their bug when they realised they were relying on assumptions, and I doubt they'll be making the same mistake again soon).
bewing wrote:
Brendan wrote:It's still usable RAM, even if it is temporarily unusable before the switch to protected mode.
Yes, but precisely the same comment could be applied to the EBDA itself, too. :wink:
No it can't - data in the EBDA may be used by SMM code regardless of what mode the CPU/OS was using (and can also be used by the BIOS to co-ordinate SMM code, real mode APM code and ACPI code).


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.
User avatar
bewing
Member
Member
Posts: 1401
Joined: Wed Feb 07, 2007 1:45 pm
Location: Eugene, OR, US

Post by bewing »

Brendan wrote: Can you find any standard that says the OS can use more than 512 KB of memory below 1 MB (or a standard that says the BIOS can't have a large EBDA from 0x00080000 to 0x0009FFFF)?
In fact, I think the standard that said just that is called MSDOS ver 3 through 5 and/or Windows 1.0 through 3.11.

And doesn't an OS have complete control over preventing the system from entering SMM?
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Post by Brendan »

Hi,
bewing wrote:
Brendan wrote:Can you find any standard that says the OS can use more than 512 KB of memory below 1 MB (or a standard that says the BIOS can't have a large EBDA from 0x00080000 to 0x0009FFFF)?
In fact, I think the standard that said just that is called MSDOS ver 3 through 5 and/or Windows 1.0 through 3.11.
The word "standard" is probably a bit inaccurate - the original 8086 XT machine had "BIOS Int 0x12", and all other 80x86 computers still have it for backward compatability.
bewing wrote:And doesn't an OS have complete control over preventing the system from entering SMM?
SMM is (and AFAIK was always intended to be) completely hidden from the OS and normal software.

If the OS enables "ACPI mode" then some things will cause an SCI (which is handled by the OS's AML interpretter) instead of causing an SMI (which is handled by the BIOS's SMM code).

If the OS supports USB properly, then some things that were emulated by the BIOS's SMM code aren't (e.g. BIOSs make a USB keyboard look like a PS/2 keyboard using SMM until the OS disables it in the USB device).

However, even with full ACPI and USB support there can be other things the BIOS uses SMM for. One of the things that's mentioned in the documentation for some Intel chipsets is "RAM scrubbing" (which I assume is something that attempts to correct or recover from temporary RAM errors).

For some chipsets you might be able to avoid and/or disable all of the causes of SMI, but without studying each motherboard (chipset and BIOS) you won't know how much SMM does or how much SMM you can avoid. There isn't really any limit to the number of things the BIOS could use SMM for, and there definately isn't a generic way to disable all SMM.


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.
User avatar
Dandee Yuyo
Member
Member
Posts: 47
Joined: Fri Nov 09, 2007 6:46 pm
Location: Argentina

Post by Dandee Yuyo »

Me I just plainly forget about what's below 1MB. I just use it to load the second stage loader and to map some tables at boot time while I can still use the BIOS to get some valuable system information, and plan to use it only for DMA buffers in the future; and maybe, MAYBE, some kernel tables.

To determine the amount of RAM I do int 15 with eax e820h, e801h and 8800h in that order. If e820h fails, I fill an e820h-like memory map with the results of e801h or 8800h that the kernel uses to initialize the page frame allocator.

I asume that if e820h didn't work there won't be any ACPI present mapping its I/O in upper RAM. Is this bad?

If 8800h fails, then I just show a message and jmp $.. Hey update your hardware! :lol:

Probing memory is bad, probing is evil. DON'T.
NaN - Not a Nerd
Working on: Physical Memory Management with a 5-lod mipmap XD
Post Reply