Page 1 of 1

Can't make rsp/rbp more then 0xF0010

Posted: Tue Jul 26, 2022 4:15 am
by Cyao
I just got to 64 bit mode, and want to make the stack higher, but i found out the stack can't be set to values above 0xF0010. Is this some kind of paging fault or did I not setup my 64 bit mode correctly? Can someone correct me?

My 64 bit switch:

Code: Select all

[bits 32]
switch_lm:
    ; check A20 Line
    pushad
    mov edi,0x112345
    mov esi,0x012345
    mov [esi],esi
    mov [edi],edi
    cmpsd
    popad

    jne enable_paging
    ; If there isn't any, set it up
    in al, 0x92
    or al, 2
    out 0x92, al

    jmp switch_lm

enable_paging:
    mov edi, PAGING_OFFSET
    mov cr3, edi
    xor eax, eax
    mov ecx, 4096
    rep stosd
    mov edi, cr3

    ; Make PML4T, PDPT, PDT and PT
    mov DWORD [edi], 0x00002003
    add edi, 0x1000
    mov DWORD [edi], 0x00003003
    add edi, 0x1000
    mov DWORD [edi], 0x00004003
    add edi, 0x1000

    ; Setup loop
    mov ebx, 0x00000003
    mov ecx, 512

.SetEntry:
    mov DWORD [edi], ebx
    add ebx, 0x1000
    add edi, 8
    loop .SetEntry
    ; PAE-paging enable
    mov eax, cr4
    or eax, 1 << 5
    mov cr4, eax
    ; LM-bit
    mov ecx, 0xC0000080
    rdmsr
    or eax, 1 << 8
    wrmsr
    ; Enable paging
    mov eax, cr0
    or eax, 1 << 31
    mov cr0, eax

    mov byte [gdt_code.code_limit], 10101111b
    lgdt [gdt_descriptor]

    jmp CODE_SEG:init_lm ; Looooooooooooong jump

[bits 64]
init_lm:    ; Well the long jump wasn't very long
    mov ax, DATA_SEG    ; Make everything point to the data seg
    mov ds, ax
    mov ss, ax
    mov es, ax
    mov fs, ax
    mov gs, ax

    mov rbp, 0xF0010  ; Can't make it more then 0xF0010 or crash
    mov rsp, rbp

    call BEGIN_LM
If you need to see some more code i got it on my git http://www.github.com/cheyao/OS

Re: Can't make rsp/rbp more then 0xF0010

Posted: Tue Jul 26, 2022 5:12 am
by iansjack
You're trying to set the stack in ROM.

That's not going to work, is it?

Re: Can't make rsp/rbp more then 0xF0010

Posted: Tue Jul 26, 2022 5:46 am
by Cyao
iansjack wrote:You're trying to set the stack in ROM.
Oh yes my bad, thanks for correcting me! I am now using 0x0009FFFF as my stack pointer, and im making my idt 64 bit, but it keeps breaking when i call a int, could you help me have a look?

Thanks again!

Re: Can't make rsp/rbp more then 0xF0010

Posted: Tue Jul 26, 2022 5:58 am
by davmac314
The 0xF0000 - 0x100000 range is typically BIOS ROM. See https://wiki.osdev.org/Memory_Map_(x86)

Typically there will be some memory available just beyond 0x100000, but it's even best not to rely on this if you can avoid it (i.e. query the memory map via BIOS functions instead).

Re: Can't make rsp/rbp more then 0xF0010

Posted: Tue Jul 26, 2022 6:35 am
by iansjack
Your stack pointer should not be an odd number. Try making it 0xa0000.

Re: Can't make rsp/rbp more then 0xF0010

Posted: Tue Jul 26, 2022 7:19 am
by Cyao
Now my stack pointer is at 0x0009FFFE, I didn't put it at 0x000A0000 because according tohttps://wiki.osdev.org/Memory_Map_(x86) 0x000A0000 should already be in the Video display memory

Re: Can't make rsp/rbp more then 0xF0010

Posted: Tue Jul 26, 2022 8:03 am
by iansjack
You are overlooking the fact that the stack pointer is decremented before the value is stored to it. 0xA0000 is a perfectly safe address to use for the initial stack pointer. It could be argued that it is a good address to choose as should you attempt to pop a value off an empty stack the program will crash rather than continuing with corrupt data.

Re: Can't make rsp/rbp more then 0xF0010

Posted: Tue Jul 26, 2022 8:06 am
by Cyao
iansjack wrote:You are overlooking the fact that the stack pointer is decremented before the value is stored to it. 0xA0000 is a perfectly safe address to use for the initial stack pointer. It could be argued that it is a good address to choose as should you attempt to pop a value off an empty stack the program will crash rather than continuing with corrupt data.
Oh thanks :) ! I thought that the stack will first put the value, then decrease after!

Re: Can't make rsp/rbp more then 0xF0010

Posted: Tue Jul 26, 2022 8:24 am
by Octocontrabass
If you place your stack at 0xA0000, it will overlap the EBDA, and that might cause stack corruption. You should choose a different address.

Re: Can't make rsp/rbp more then 0xF0010

Posted: Tue Jul 26, 2022 8:41 am
by nullplan
You really ought to allocate your stack. While in real mode, query the system memory map from BIOS using E820 (that is function AX=E820 of int 15h), then from that figure out where you have enough free memory for your stack. On a legacy BIOS system, you should probably reserve the very first page of memory (addresses 0 - 0x1fff) irrespective of what BIOS says, because that is the IVT and BDA, which may or may not be important. Other considerations are that memory below 1MB is valuable and ought not to be used unless you cannot help it (indeed, it may be best to allocate the stack as high as possible. It may be best to allocate everything as high as possible).

That also means you really ought to allocate your page tables rather than putting them at pre-defined addresses. That way you avoid all the pitfalls of clobbering the EBDA or any other page of memory that may be in use by the firmware.

Re: Can't make rsp/rbp more then 0xF0010

Posted: Tue Jul 26, 2022 9:24 am
by Cyao
Thanks everyone for the support :) !

I am now putting my stack at 0x8000000 so it doesn't overlap anything :D .

Re: Can't make rsp/rbp more then 0xF0010

Posted: Tue Jul 26, 2022 10:08 am
by Octocontrabass
You need to check the memory map to ensure the memory at that address is usable. (Or use paging to place some usable memory at that virtual address.)