MOV DS, AX causes fault [solved]

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.
Post Reply
quadrant
Member
Member
Posts: 74
Joined: Tue Apr 24, 2018 9:46 pm

MOV DS, AX causes fault [solved]

Post by quadrant »

Hi there!

I am following James Molloy's Kernel tutorial, which is in turn based on Brandon Friesen's Kernel tutorial. Looking at old posts in this forum, it seems these are popular tutorials.

Unlike James, I opted to use QEMU (with GDB) instead of Bochs. Apart from the makefile (where I redirected the kernel elf to QEMU instead of Bochs) my code is essentially identical to his.

However, I cannot get the GDT part of the code/tutorial to work. Specifically, the gdt_flush assembly:

Code: Select all

global gdt_flush

gdt_flush:

	mov  eax, [esp+4]
	lgdt [eax]

	mov  ax, 0x10
	mov  ds, ax   ; Causes a triple fault
	mov  es, ax
	mov  fs, ax
	mov  gs, ax
	mov  ss, ax

	jmp  0x08:.flush

.flush:

	ret
When I stepi in GDB, I can see that all is going as expected until it reaches the

Code: Select all

move ds, ax
instruction. At which point a triple fault is raised.

I've googled around and some of the answers I have seen mention something about this instruction not being allowed in protected mode. What does that mean? Is it the cause of the fault? If it is, what can I do to address it? I suspect it is due to my use of QEMU (and GDB) rather than Bochs as otherwise the tutorial would have mentioned (and addressed) it.

Edit:
Link to my code
Last edited by quadrant on Wed Apr 25, 2018 4:11 pm, edited 3 times in total.
alexfru
Member
Member
Posts: 1112
Joined: Tue Mar 04, 2014 5:27 am

Re: MOV DS, AX causes fault - QEMU

Post by alexfru »

It means the segment register cannot be loaded with a segment selector.
There are multiple specific reasons, but the most likely ones in your case are:
  • the selector falls outside the table (selector too large or table too small)
  • the descriptor that the selector points to is somehow wrong (e.g. wrong segment type)
So you need to make sure your GDTR and GDT are correct and the selector that you're loading into the segment register makes sense.
quadrant
Member
Member
Posts: 74
Joined: Tue Apr 24, 2018 9:46 pm

Re: MOV DS, AX causes fault - QEMU

Post by quadrant »

If my code is exactly the same as the tutorial's (apart from the makefile), why does it fail for my case but work in the tutorial? I haven't modified any of the values.
User avatar
iansjack
Member
Member
Posts: 4706
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: MOV DS, AX causes fault - QEMU

Post by iansjack »

It might help if you gave a link to the repository of your code. Otherwise it's just guesswork.
quadrant
Member
Member
Posts: 74
Joined: Tue Apr 24, 2018 9:46 pm

Re: MOV DS, AX causes fault - QEMU

Post by quadrant »

I added a link to my code.
User avatar
iansjack
Member
Member
Posts: 4706
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: MOV DS, AX causes fault - QEMU

Post by iansjack »

The only thing that strikes me immediately is that you are using a 16-bit pointer for the base address in gdt_entry_struct, when it should be a 32-bit pointer. That's certainly going to cause problems.

If it's not that, you should set a breakpoint just before you load the segment registers. Then you can inspect the GDT in memory to see that it is correct. Also, you can use the qemu monitor to obtain information about the GDT.

Edit: I'm not sure why I said "if it's not that"; your code is loaded above the 64K mark so any pointers must be 32-bit. Using a 16-bit pointer is an absolute show-stopper.
simeonz
Member
Member
Posts: 360
Joined: Fri Aug 19, 2016 10:28 pm

Re: MOV DS, AX causes fault - QEMU

Post by simeonz »

The order of the fields in the gdt entry is incorrect as well. It doesn't match the one in the osdev wiki, and the osdev wiki matches the intel manual, so the source must be wrong.
quadrant
Member
Member
Posts: 74
Joined: Tue Apr 24, 2018 9:46 pm

Re: MOV DS, AX causes fault - QEMU

Post by quadrant »

iansjack wrote:The only thing that strikes me immediately is that you are using a 16-bit pointer for the base address in gdt_entry_struct, when it should be a 32-bit pointer. That's certainly going to cause problems.
Facepalm! #-o Thank you! :)
I guess my code isn't an exact copy (I'll have to comb over it again).
quadrant
Member
Member
Posts: 74
Joined: Tue Apr 24, 2018 9:46 pm

Re: MOV DS, AX causes fault - QEMU

Post by quadrant »

simeonz wrote:The order of the fields in the gdt entry is incorrect as well. It doesn't match the one in the osdev wiki, and the osdev wiki matches the intel manual, so the source must be wrong.
The order matters? 0.0! The tutorial's order follows that in the link you shared. I just changed it for legibility, I didn't think it mattered.
quadrant
Member
Member
Posts: 74
Joined: Tue Apr 24, 2018 9:46 pm

Re: MOV DS, AX causes fault - QEMU

Post by quadrant »

Thank you, both things pointed out were the issue. The code now works!
Post Reply