mmap_addr and mmap_length constant?

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
ThisMayWork
Member
Member
Posts: 65
Joined: Sat Mar 22, 2014 1:14 pm
Location: /bin

Re: mmap_addr and mmap_length constant?

Post 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?
"Programming is an art form that fights back."
-Kudzu
Octocontrabass
Member
Member
Posts: 5588
Joined: Mon Mar 25, 2013 7:01 pm

Re: mmap_addr and mmap_length constant?

Post 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.
User avatar
ThisMayWork
Member
Member
Posts: 65
Joined: Sat Mar 22, 2014 1:14 pm
Location: /bin

Re: mmap_addr and mmap_length constant?

Post 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.
"Programming is an art form that fights back."
-Kudzu
User avatar
ThisMayWork
Member
Member
Posts: 65
Joined: Sat Mar 22, 2014 1:14 pm
Location: /bin

Re: mmap_addr and mmap_length constant?

Post 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. 
"Programming is an art form that fights back."
-Kudzu
User avatar
Combuster
Member
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?

Post 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... :shock:
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
User avatar
ThisMayWork
Member
Member
Posts: 65
Joined: Sat Mar 22, 2014 1:14 pm
Location: /bin

Re: mmap_addr and mmap_length constant?

Post 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?
"Programming is an art form that fights back."
-Kudzu
User avatar
Combuster
Member
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?

Post by Combuster »

Have you ever tried running your kernel against a real multiboot loader and even try to isolate the problem?
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
User avatar
ThisMayWork
Member
Member
Posts: 65
Joined: Sat Mar 22, 2014 1:14 pm
Location: /bin

Re: mmap_addr and mmap_length constant?

Post by ThisMayWork »

Never thought of that. I'll try it out, thanks Combuster :)
"Programming is an art form that fights back."
-Kudzu
Post Reply