mmap_addr and mmap_length constant?
- ThisMayWork
- Member
- Posts: 65
- Joined: Sat Mar 22, 2014 1:14 pm
- Location: /bin
Re: mmap_addr and mmap_length constant?
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?
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?
"Programming is an art form that fights back."
-Kudzu
-Kudzu
-
- Member
- Posts: 5588
- Joined: Mon Mar 25, 2013 7:01 pm
Re: mmap_addr and mmap_length constant?
I don't see it anywhere in the code you posted earlier, and you haven't posted any updated code.ThisMayWork wrote:After the MB Info is pushed.
- ThisMayWork
- Member
- Posts: 65
- Joined: Sat Mar 22, 2014 1:14 pm
- Location: /bin
Re: mmap_addr and mmap_length constant?
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.
"Programming is an art form that fights back."
-Kudzu
-Kudzu
- ThisMayWork
- Member
- Posts: 65
- Joined: Sat Mar 22, 2014 1:14 pm
- Location: /bin
Re: mmap_addr and mmap_length constant?
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.
"Programming is an art form that fights back."
-Kudzu
-Kudzu
- Combuster
- Member
- Posts: 9301
- Joined: Wed Oct 18, 2006 3:45 am
- Libera.chat IRC: [com]buster
- Location: On the balcony, where I can actually keep 1½m distance
- Contact:
Re: mmap_addr and mmap_length constant?
I see "multiboot" and "int 0x15" in the same code.
I think you forgot the point about using multiboot in the first place...
I think you forgot the point about using multiboot in the first place...
- ThisMayWork
- Member
- Posts: 65
- Joined: Sat Mar 22, 2014 1:14 pm
- Location: /bin
Re: mmap_addr and mmap_length constant?
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?
"Programming is an art form that fights back."
-Kudzu
-Kudzu
- Combuster
- Member
- Posts: 9301
- Joined: Wed Oct 18, 2006 3:45 am
- Libera.chat IRC: [com]buster
- Location: On the balcony, where I can actually keep 1½m distance
- Contact:
Re: mmap_addr and mmap_length constant?
Have you ever tried running your kernel against a real multiboot loader and even try to isolate the problem?
- ThisMayWork
- Member
- Posts: 65
- Joined: Sat Mar 22, 2014 1:14 pm
- Location: /bin
Re: mmap_addr and mmap_length constant?
Never thought of that. I'll try it out, thanks Combuster
"Programming is an art form that fights back."
-Kudzu
-Kudzu