flat assembler
Message board for the users of flat assembler.

Index > OS Construction > A question about Fn E801 INT 15

Author
Thread Post new topic Reply to topic
zhak



Joined: 12 Apr 2005
Posts: 501
Location: Belarus
zhak 20 Feb 2010, 16:26
Hi guys.
I'm just a bit confused about the output of Fn E801 INT 15. What does 'configured' memory (returned in CX-DX) mean?

I've read at wiki.osdev.org that a typical output is AX = CX, and BX = DX. I've also read that grub checks only AX-BX pair, and linux kernel checks CX-DX pair unless it's zero.

I believe i should implement a full check (both pairs) but what value can be considered a more appropriate? AX-BX or CX-DX? I mean which should be checked first and if they differ, which pair should be considered to hold the correct value?

Thanks a lot
Post 20 Feb 2010, 16:26
View user's profile Send private message Reply with quote
smiddy



Joined: 31 Oct 2004
Posts: 557
smiddy 20 Feb 2010, 16:53
Here's a routine I wrote a while back, but as you can see, for the most part E801h is not reliable for checking all your memory:

Code:
BIOSE801Message                 DB 'E801: ',0
BIOSE801ErrorMessage            DB 'ERROR: Function unsupported.',13,10,0
BIOSE801ErrorUnreliableMessage  db 'ERROR: Function unreliable, gives greater than 15 MB.',13,10,0
E801TotalMemory                 DD 0                            ; Saving the Extended Memory

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; BIOSE801Memory
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

BIOSE801Memory:

    mov si,BIOSE801Message
    call PrintString
    
    xor eax,eax
    xor ebx,ebx
    xor ecx,ecx
    xor edx,edx

    mov eax,0E801h              ; Load function
    int 0x15                    ; Call BIOS

    jc .BIOSE801Error           ; If function not support, Try 88xx

    mov [TheEBX],ebx            ; Save EBX
    cmp eax,dword 3c00h         ; Check maximum value, greater it is unreliable
    ja .BIOSE801Error           ; Unreliable if greater than the 15 MB 
    je .DoNextRegister          ; If equal, then move on to next register

    mov ebx,400h                ; Multiply by 1024
    mul ebx
    add eax,100000h             ; Add bottom 1MB of RAM
    
;    mov eax,100000h            ; Testing Probing and over all memory
    
    mov [E801TotalMemory],eax   ; Save bytes installed (intialized)
    call ToDecimal
    call AddCommas
    
    mov si,CommaBuffer
    call PrintString
    mov si,TheBytes
    call PrintString

    mov si,TheEndOfLine
    call PrintString
    jmp .Done
    
.DoNextRegister:

    mov eax,[TheEBX]
    mov ebx,10000h
    mul ebx                     ; Multiply by 64 KB
    add eax,1000000h            ; Add 16 MB
    mov [E801TotalMemory],eax
    call ToDecimal
    call AddCommas
    
    mov si,CommaBuffer
    call PrintString
    mov si,TheBytes
    call PrintString

    mov si,TheEndOfLine
    call PrintString
    jmp .Done
    
.BIOSE801Error:

    mov si,BIOSE801ErrorMessage
    call PrintString
    jmp .Done
    
.BIOSE801ErrorUnreliable:

    mov si,BIOSE801ErrorUnreliableMessage
    call PrintString
    
.Done:
    
    ret
    
Post 20 Feb 2010, 16:53
View user's profile Send private message Reply with quote
Fanael



Joined: 03 Jul 2009
Posts: 168
Fanael 20 Feb 2010, 17:36
Check whether ECX is zero or it's left intact (if ECX is 0 before calling BIOS, then only first check should be performed, as second would do exactly the same thing). If it is, then AX-BX pair contain valid result, otherwise CX-DX does.

Code from my bootloader:
Code:
xor ebx, ebx
xor ecx, ecx
xor edx, edx
mov eax, 0E801h
int 15h ;get it from BIOS
jc .memSizeError ;error?
cmp ah, 80h
je .memSizeError ;invalid command?
cmp ah, 86h
je .memSizeError ;unsupported function?
jcxz .use_ax ;if result is in CX and DX, then...
mov ax, cx ; ...move CX to AX...
mov bx, dx ;...and DX to BX...
; ... and use AX-BX pair
.use_ax:
movzx ebx, bx
movzx eax, ax
shl ebx, 6 ;multiply EBX by 64
lea eax, [eax + ebx + 1024] ;put memory size in KB to EAX    

Use E820 instead of this!


Last edited by Fanael on 20 Feb 2010, 17:44; edited 1 time in total
Post 20 Feb 2010, 17:36
View user's profile Send private message Reply with quote
zhak



Joined: 12 Apr 2005
Posts: 501
Location: Belarus
zhak 20 Feb 2010, 17:43
hmm have you ever faced such systems that returned > 3c00 in ax?
Post 20 Feb 2010, 17:43
View user's profile Send private message Reply with quote
smiddy



Joined: 31 Oct 2004
Posts: 557
smiddy 20 Feb 2010, 20:43
Yes. I don't recall where...however. It has been quite a while since I ran tests on this code.
Post 20 Feb 2010, 20:43
View user's profile Send private message Reply with quote
zhak



Joined: 12 Apr 2005
Posts: 501
Location: Belarus
zhak 20 Feb 2010, 21:39
thanks guys. i implemented it in similar way as Fanael - test cx-dx pair first, and added "> 3c00" check as smiddy advised.

by the way, are that "cmp ah, 80h/cmp ah, 86h" checks necessary? i always thought that CF set should be enough to determine whether a function succeeded or not
Post 20 Feb 2010, 21:39
View user's profile Send private message Reply with quote
Fanael



Joined: 03 Jul 2009
Posts: 168
Fanael 20 Feb 2010, 23:11
zhak wrote:
by the way, are that "cmp ah, 80h/cmp ah, 86h" checks necessary?
Yes. If function is not supported, then BIOSes may set AH to one of these values, without setting carry flag. Perhaps that's the reason of AX > $3C00 Wink
Post 20 Feb 2010, 23:11
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.