Page 3 of 3
Re: mmap_addr and mmap_length constant?
Posted: Wed Jun 17, 2015 8:47 am
by ThisMayWork
After the MB Info is pushed. Should it be the opposite way?
Sidenote: I just realised that I could simply specify an address and have the kernel read from it to get the MB info. Is this in any way worse that passing it in the function?
Re: mmap_addr and mmap_length constant?
Posted: Wed Jun 17, 2015 8:49 am
by Octocontrabass
ThisMayWork wrote:After the MB Info is pushed.
I don't see it anywhere in the code you posted earlier, and you haven't posted any updated code.
Re: mmap_addr and mmap_length constant?
Posted: Wed Jun 17, 2015 9:06 am
by ThisMayWork
I just realised I changed that to try and track down the error. From stage 2 to stage 3 it is a normal jump so it should not modify the stack. That means that MB Info is still at the correct place. Then, on stage 3 I call kernel_entry. The new values are 0x0 for length and addr of mmap and 0x985 for the multiboot address.
Re: mmap_addr and mmap_length constant?
Posted: Wed Aug 05, 2015 2:16 pm
by ThisMayWork
Update: Instead of pushing the pointer for multiboot info on the stack and receiving it as a parameter in my main function, I decided to just copy it to a constant memory address and retrieve it as a double pointer in C code but it still isn't giving me correct values. Any ideas? Code:
Code: Select all
call BiosGetMemorySize64MB ;Here I fill my boot_info struct
mov word [boot_info+multiboot_info.memoryHi], bx
mov word [boot_info+multiboot_info.memoryLo], ax
mov eax, 0x0
mov ds, ax
mov di, 0x1000
call BiosGetMemoryMap
Code: Select all
mov eax, 10000h ;Here I copy it in 0x10000
mov dword [eax], boot_info
Code: Select all
struct multiboot_info* mboot = *(struct multiboot_info**)0x10000;
//Here I retrieve it in C kernel code and print it out. (putun is my kernels way of outputting unsigned numbers, the third parameter is the radix)
putun("MB Address:", mboot, 16);
putun("Flags:", mboot->m_flags, 16);
putun("Mem Lo:", mboot->m_memoryLo, 16);
putun("Mem Hi:", mboot->m_memoryHi, 16);
putun("Memory Map Address:", mboot->m_mmap_addr, 16);
Code: Select all
BiosGetMemoryMap:
pushad
xor ebx, ebx
xor bp, bp ; number of entries stored here
mov edx, 'PAMS' ; 'SMAP'
mov eax, 0xe820
mov ecx, 24 ; memory map entry struct is 24 bytes
int 0x15 ; get first entry
jc .error
cmp eax, 'PAMS' ; bios returns SMAP in eax
jne .error
test ebx, ebx ; if ebx=0 then list is one entry long; bail out
je .error
jmp .start
.next_entry:
mov edx, 'PAMS' ; some bios's trash this register
mov ecx, 24 ; entry is 24 bytes
mov eax, 0xe820
int 0x15 ; get next entry
.start:
jcxz .skip_entry ; if actual returned bytes is 0, skip entry
.notext:
mov ecx, [es:di + MemoryMapEntry.length] ; get length (low dword)
test ecx, ecx ; if length is 0 skip it
jne short .good_entry
mov ecx, [es:di + MemoryMapEntry.length + 4]; get length (upper dword)
jecxz .skip_entry ; if length is 0 skip it
.good_entry:
inc bp ; increment entry count
add di, 24 ; point di to next entry in buffer
.skip_entry:
cmp ebx, 0 ; if ebx return is 0, list is done
jne .next_entry ; get next entry
jmp .done
.error:
stc
.done:
popad
ret
;---------------------------------------------
; Get memory size for >64M configuations (32 bit)
; ret\ ax=KB between 1MB and 16MB
; ret\ bx=number of 64K blocks above 16MB
; ret\ bx=0 and ax= -1 on error
;---------------------------------------------
BiosGetMemorySize64MB_32Bit:
push ecx
push edx
xor ecx, ecx
xor edx, edx
mov ax, 0xe881
int 0x15
jc .error
cmp ah, 0x86 ;unsupported function
je .error
cmp ah, 0x80 ;invalid command
je .error
jcxz .use_ax ;bios may have stored it in ax,bx or cx,dx. test if cx is 0
mov ax, cx ;its not, so it should contain mem size; store it
mov bx, dx
.use_ax:
pop edx ;mem size is in ax and bx already, return it
pop ecx
ret
.error:
mov ax, -1
mov bx, 0
pop edx
pop ecx
ret
;---------------------------------------------
; Get memory size for >64M configuations
; ret\ ax=KB between 1MB and 16MB
; ret\ bx=number of 64K blocks above 16MB
; ret\ bx=0 and ax= -1 on error
;---------------------------------------------
BiosGetMemorySize64MB:
push ecx
push edx
xor ecx, ecx
xor edx, edx
mov ax, 0xe801
int 0x15
jc .error
cmp ah, 0x86 ;unsupported function
je .error
cmp ah, 0x80 ;invalid command
je .error
jcxz .use_ax ;bios may have stored it in ax,bx or cx,dx. test if cx is 0
mov ax, cx ;its not, so it should contain mem size; store it
mov bx, dx
.use_ax:
pop edx ;mem size is in ax and bx already, return it
pop ecx
ret
.error:
mov ax, -1
mov bx, 0
pop edx
pop ecx
ret
;Here are my memory functions. I tried both variants for GetMemorySize with no result.
Re: mmap_addr and mmap_length constant?
Posted: Thu Aug 06, 2015 1:26 am
by Combuster
I see "multiboot" and "int 0x15" in the same code.
I think you forgot the point about using multiboot in the first place...
Re: mmap_addr and mmap_length constant?
Posted: Thu Aug 06, 2015 1:32 am
by ThisMayWork
I am sorry, but I didn't quite understand what you said. My goal here is to provide the kernel with the exact same multiboot info GRUB and other bootloaders give. Since I do not do any module loading, I do not need to worry about that part, so all I am doing is gathering memory size and map data and pass it to the kernel. Am I thinking wrong here?
Re: mmap_addr and mmap_length constant?
Posted: Thu Aug 06, 2015 9:03 am
by Combuster
Have you ever tried running your kernel against a real multiboot loader and even try to isolate the problem?
Re: mmap_addr and mmap_length constant?
Posted: Thu Aug 06, 2015 12:14 pm
by ThisMayWork
Never thought of that. I'll try it out, thanks Combuster