32bit protected mode init problem

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.
czlowieczek
Posts: 21
Joined: Wed Jul 10, 2013 3:00 am

32bit protected mode init problem

Post by czlowieczek »

I have a problem, when I run my os with bosch it crashes, when i remove segment reloading it crashes also at jumping to 32 bit code (jmp 0x08:start32)
Below is my all code. Bootloader loads my kernel at 80000:0000. Please help


Code: Select all

[org 0h]
[bits 16]
jmp start

gdt:
  ; NULL Descriptor
  dd 0
  dd 0
 
  ;code 4gb start 00000000h
  dw 0xFFFF   
  dw 0         
  db 0         
  db 10011010b 
  db 11001111b 
  db 0         
 
  ;data 4gb start 00000000h
  dw 0xFFFF
  dw 0        
  db 0         
  db 10010010b 
  db 11001111b 
  db 0         
gdt_end:    
 

gdt_descr:
  dw gdt_end - gdt - 1    
  dd gdt   
  
start:

lgdt [gdt_descr]
 
mov eax, cr0
or eax, 1
mov cr0, eax

mov ax, 0x10 ;data 0x10 8x2
mov ss, ax
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax

jmp 0x08:start32 ;code 0x08 8x1
 
[BITS 32]

mov esp, koniec_stoss
start32:

mov al, 'x'        ;test char to check is it working
mov edi, 0B800h
stosb

petla:

jmp petla

stoss:
RESB 4096
koniec_stoss:
Attachments
Screenshot of my bosch console after trying to reload segments.
Screenshot of my bosch console after trying to reload segments.
User avatar
AJ
Member
Member
Posts: 2646
Joined: Sun Oct 22, 2006 7:01 am
Location: Devon, UK
Contact:

Re: 32bit protected mode init problem

Post by AJ »

Hi,

Your offsets are all based on the ORG 0 directive, but in real mode, you are at 0x8000:0x0000. This means that your JMP 0x8:[x] code is jumping to the linear address 0x132 (which is somewhere in the real mode IVT) rather than your intended linear address of 0x80132.

Also, I've never seen the data segment registers set before the jump to PMode - this may well be valid, but just commenting!

Cheers,
Adam
czlowieczek
Posts: 21
Joined: Wed Jul 10, 2013 3:00 am

Re: 32bit protected mode init problem

Post by czlowieczek »

Adam, I read a book, which says, that when I load new gdt and want to jump the 0x08 and 0x10 means place in gdt 0x08 means in my gdt code starting at 00000000h with size 4gb and 0x10 means data segment in gdt starting also at 00000000h with size 4gb. If this book is right jumping at 0x08:[x] means with mygdt means jumping in code segment 00000000h with offset x. I triet just to copy another gdt(s) and codes but I had the same errors, on the page http://wiki.osdev.org/Protected_Mode there is the same jump instruction. I have errors with jumping too :(
User avatar
AJ
Member
Member
Posts: 2646
Joined: Sun Oct 22, 2006 7:01 am
Location: Devon, UK
Contact:

Re: 32bit protected mode init problem

Post by AJ »

Hi,

Most of your the jumps in your code will be relative. That is, they move EIP by a certain number of bytes forwards / backwards.

jmp 0x08:x is an absolute jump. The position of x is hard coded by the assembler. The only way that your assembler knows where the code is located in memory is by your ORG directive. In your case, ORG 0 tells the assembler that all addresses in your code are relative to 0x0000 (which *is* valid for your real mode code, as your code is loaded at 0x0000 in segment 0x8000).

Once your switch to protected mode addressing, your code is now loaded at 0x08:0x80000. This means that if you wish to address a location 2 bytes from the start of your code in real mode, you would be able to use mov ax, [0x0002]. In PMode, to achieve the same thing, you need to use mov ax, [0x80002] - simply because of where you have chosen to place your real mode code.

The problem is, you could change the directive to ORG 0x80000 which would generate the correct code for your JMP instruction, but will not correctly load the GDT. Alternatively, you will have to manually add 0x80000 to your JMP instruction (JMP 0x08:(0x80000 + x)) and all PMode offsets thereafter.

Cheers,
Adam
User avatar
AJ
Member
Member
Posts: 2646
Joined: Sun Oct 22, 2006 7:01 am
Location: Devon, UK
Contact:

Re: 32bit protected mode init problem

Post by AJ »

Hi,

Addendum: If your second stage is small enough, a simpler way to deal with this would be to load your mode switching code somewhere in real mode segment 0x0000. This will provide you with the same addressing for real mode and PMode. By using the ELF file format, you may even be able to load bootstrap and other code in two separate physical locations - but thats getting a bit mode complex.

Cheers,
Adam
czlowieczek
Posts: 21
Joined: Wed Jul 10, 2013 3:00 am

Re: 32bit protected mode init problem

Post by czlowieczek »

So, u think that should be easier to load another (bin/executable) file to real mode segment 0x9000h:0000h but with org 90000h and jump to it like this: jmp 0x08:90000h ??
User avatar
AJ
Member
Member
Posts: 2646
Joined: Sun Oct 22, 2006 7:01 am
Location: Devon, UK
Contact:

Re: 32bit protected mode init problem

Post by AJ »

Hi,

That's one possible solution. Not necessarily the easiest, but certainly doable. If you decide to do it that way, you will end up with a small inter-stage loader specifically for mode switching, which may be a bit of a waste.

The solution that you go for depends on your design, really. As long as you bear in mind exactly where you are addressing in the current CPU mode.

If I had to pick an "easiest" solution, it would probably be using a Multiboot / Multiboot2 loader. I see the following basic choices (not necessarily in order of preference):
  • Use a pre-written boot loader.
  • Manually fix up addresses as needed.
  • Use a separate stage for mode switching.
  • Load a GDT in your stage 1 loader before you even call this code - making the entry point of stage 2 32 bit.
  • Use ELF and load your mode switching code in a separate location.
  • Load this stage somewhere below 0x0000:0xFFFF
  • Probably others...
Cheers,
Adam
czlowieczek
Posts: 21
Joined: Wed Jul 10, 2013 3:00 am

Re: 32bit protected mode init problem

Post by czlowieczek »

Thank you Adam, helping me with jump to 32 bit code, but there is still issue with setting the data segment to 0x10, u have any idea how to deal with this ??
User avatar
AJ
Member
Member
Posts: 2646
Joined: Sun Oct 22, 2006 7:01 am
Location: Devon, UK
Contact:

Re: 32bit protected mode init problem

Post by AJ »

Hi,

Successfully jump to an infinite loop in protected mode. Once you can do that, start worrying about your data segments :)

Cheers,
Adam
czlowieczek
Posts: 21
Joined: Wed Jul 10, 2013 3:00 am

Re: 32bit protected mode init problem

Post by czlowieczek »

I copied almost all my bootloader to my protected mode enabling stage, I enable protected mode and jumped to loaded kernel2.bin (0x08:90000)
which code is

Code: Select all

[bits 32]
[org 90000h]
petla:
jmp petla
And in bosh it look like in attachment

I think i'm in the infinite loop
Attachments
loop.png
User avatar
AJ
Member
Member
Posts: 2646
Joined: Sun Oct 22, 2006 7:01 am
Location: Devon, UK
Contact:

Re: 32bit protected mode init problem

Post by AJ »

Hi,

Great! When you power off Bochs, you'll get the register dump and EIP will tell you exactly where you are.

Cheers,
Adam
czlowieczek
Posts: 21
Joined: Wed Jul 10, 2013 3:00 am

Re: 32bit protected mode init problem

Post by czlowieczek »

Ok, it didn't worked, while shutting off i saw that cpu is in real mode with wrong cs :(
czlowieczek
Posts: 21
Joined: Wed Jul 10, 2013 3:00 am

Re: 32bit protected mode init problem

Post by czlowieczek »

I have error while I try to jump anywhere i tried 0x08:0FFFFFh (this should restart my pc, but it restart because it's error while jumping), 0x08:90000h and 0x08:70000h
User avatar
AJ
Member
Member
Posts: 2646
Joined: Sun Oct 22, 2006 7:01 am
Location: Devon, UK
Contact:

Re: 32bit protected mode init problem

Post by AJ »

Hi,

It seems like you are stabbing about in the dark a bit rather than using methodical debugging.

You are using Bochs and therefore have an integrated debugger. Your need to check a few things, beginning with the machine state when you launch your stage 2 loader. Firstly, is all your code and data where you would expect it to be? You also seem to have written a stage 1 loader yourself (assume this because you mention where your bootloader loads the kernel) - is Stage 1 working as expected.

I have not checked your GDT bit-by-bit, but you should probably do that too. Time to sit back and have a good look at the code in general, validating any assumptions as you go.

Cheers,
Adam
czlowieczek
Posts: 21
Joined: Wed Jul 10, 2013 3:00 am

Re: 32bit protected mode init problem

Post by czlowieczek »

I don't think that this is my bootloader fault, because I was using it to load any 16 bit real mode kernels and they were working correctly , but do you know any other ready to use boot loaders I can download ?? If yes, could you give me its page or tutorial how to install them on floppy ?
Post Reply