flat assembler
Message board for the users of flat assembler.
Index
> OS Construction > OS triple faults |
Author |
|
Artlav 07 Aug 2006, 05:28
OK, run it through a debugger.
Fifth line: mov ax, 0 mov ds, ax You load your OS at segment 60h offset 0h. By putting 0 in the ds you make it load GDT not from the 60h:gdt_descriptor but from 0:gdt_descriptor. (lgdt [gdt_descriptor] = lgdt ds:[gdt_descriptor]) That's first one. Second, lgdt must use linear address of gdt, not segment-relative, so add sixth line add dword [gdt_descriptor+2],600h That's the second one. Third one is in the idea - in GDT segment base is 0. Code is compiled to be at base 0. But when you switch to PM, your code appears at base 600h, since it loaded at 60h:0h So, add org 600h+$ before use32. And you don't want GDT to be after second org, so put it between jmp to pm and org #2. Code: org 0000h use16 cli mov ax, 0060h mov ds, ax add dword [gdt_descriptor+2],600h lgdt [gdt_descriptor] mov eax, cr0 or eax, 1 mov cr0, eax jmp 08h:clear_pipe gdt: dd 0, 0 gdt_code: db 0FFh, 0FFh, 0, 0, 0, 10011010b, 11001111b, 0 gdt_data: db 0FFh, 0FFh, 0, 0, 0, 10010010b, 11001111b, 0 gdt_end: gdt_descriptor: dw gdt_end - gdt - 1 dd gdt org 0600h+$ use32 clear_pipe: mov ax, 10h mov ds, ax mov ss, ax mov esp, 090000h mov byte [ds:0B8000h], 'P' mov byte [ds:0B8001h], 1Bh infinite_loop: jmp infinite_loop times 512-($-$$) db 0 |
|||
07 Aug 2006, 05:28 |
|
rhyno_dagreat 08 Aug 2006, 07:40
Thanks Artlav! I'll work with it tomorrow... It's 3:39 AM now, so it's kinda late for me.
- I actually just tried it, and it works, so thank you! Only thing is I didn't fully understand the second and third points you made, and as far as the last thing you said, about where the GDT would lie, I'm wondering why does that matter? If you could explain that to me, I'd be very grateful. Thanks! |
|||
08 Aug 2006, 07:40 |
|
rhyno_dagreat 08 Aug 2006, 18:22
Also, since I've got that working (thanks again, Artlav!) I tried adding VGA coding to my os, and I'm wondering why it's not working? Could someone please explain drawing graphics in P-mode to me?
Also, if you wish to take a look at this, here's the OS code: Code: org 0000h use16 mov ax, 0013h int 10h cli mov ax, 0060h mov ds, ax add dword [gdt_descriptor+2], 600h lgdt [gdt_descriptor] mov eax, cr0 or eax, 1 mov cr0, eax jmp 08h:clear_pipe gdt: dd 0, 0 gdt_code: db 0FFh, 0FFh, 0, 0, 0, 10011010b, 11001111b, 0 gdt_data: db 0FFh, 0FFh, 0, 0, 0, 10010010b, 11001111b, 0 gdt_end: gdt_descriptor: dw gdt_end - gdt - 1 dd gdt org 0600h+$ use32 clear_pipe: mov ax, 10h mov ds, ax mov ss, ax mov esp, 090000h ;mov byte [ds:0B8000h], 'P' ;mov byte [ds:0B8001h], 1Bh mov bx, 0A000h mov es, bx mov ebx, 0 mov ah, 0 mov cx, 64000 startloop: mov [es:ebx], ah inc ebx inc ah loop startloop infinite_loop: jmp infinite_loop times 442-($-$$) db 0 I thought that I was doing this correctly because it works when I'm in 16-bit real mode. So I'm pretty much confused. |
|||
08 Aug 2006, 18:22 |
|
zhak 09 Aug 2006, 06:52
you cannot just use
mov bx, 0A000h mov es, bx in protected mode. This won't work. I suggest you to try reading IA-32 manuals... |
|||
09 Aug 2006, 06:52 |
|
rhyno_dagreat 09 Aug 2006, 19:06
Well, I have read the IA32 manuals, but I don't recall them talking about accessing video modes.
|
|||
09 Aug 2006, 19:06 |
|
zhak 09 Aug 2006, 20:41
it's a question of segmentation, but not video memory addressing.
when you're in protected mode, you cannot just load segment selector via mov gp_reg, addr mov segment_reg, gp_reg remember? you did lgdt [gdt_descriptor] to load GDTR. So, if you defined GDTR Base = 0 then you can access video memory with its linear address. for example mov byte [es:0A0000h], 'A' |
|||
09 Aug 2006, 20:41 |
|
rhyno_dagreat 10 Aug 2006, 23:56
Of course! I think I see what you're saying now! I'm loading it from segment 0, in which instead I should be loading it from segment 10h (I think that's a segment number, at least)!!! LOL, and it even showed that in the freakin' code! Man... Sorry for the nuisance, I guess I've just been a bit off lately with things. But I think I'm starting to understand more what you're saying. Y'see, I'm still kinda new to how the descriptor tables work.
Thank you though for your patience and kindness in these matters. |
|||
10 Aug 2006, 23:56 |
|
rhyno_dagreat 11 Aug 2006, 00:20
Well, I guess I still must have it wrong, because it still doesn't work. I tried what was commented out as far as the textual video memory, the:
;mov byte [ds:0B8000h], 'P' ;mov byte [ds:0B8001h], 1Bh And instead did this: Code: mov ah, 0 mov ebx, 0A000h mov cx, 64000 ;Loop counter startloop: mov byte [ds:ebx], ah ;ds is still set to what it's set to above, 10h inc ebx inc ah loop startloop And basically nothing shows up on the screen. |
|||
11 Aug 2006, 00:20 |
|
zhak 11 Aug 2006, 00:56
oh, my! didn't you find your mistake, yet?
mov ebx, 0A000h you write 0A000h to ebx, which is the real-mode segment address. you should write 0A0000h, because linear_address = segment*10h+offset |
|||
11 Aug 2006, 00:56 |
|
rhyno_dagreat 11 Aug 2006, 02:41
Sorry I didn't reply sooner! I found it out earlier, yes. Nevertheless, thank you.
The reason that I was using 0A000 was because of the segment:offset, and 0A000 was the segment, but this time the video memory is the offset with the segment being memory segment 10h. Thank you for your time and help. Also, does it matter whether or not I use ecx as opposed to cx since I'm in 32-bit mode now? Still I'm curious why Artlav told me to do this: Code: add dword [gdt_descriptor+2],600h Again, I am sorry if I am being a nuisance here, but as I have said previously I'm still new to how the GDT deals with memory. |
|||
11 Aug 2006, 02:41 |
|
zhak 11 Aug 2006, 06:53
Quote: Again, I am sorry if I am being a nuisance here Hey, stop your excuses. We're here to ask questions and learn new things. you have to add 600h to gdt_descriptor, because you load linear address with LGDT command, not segment:offset. one more thing, never use loop instruction. it's toooo slooooow label: . . . dec ecx jnz label is much faster. you may use any GP registers you like both in protected and real modes. Yea, I forgot to write about Gate-A20 last time... Where's your Gate-A20 enable routine? find and read some articles about A20 if you're not familiar with it. |
|||
11 Aug 2006, 06:53 |
|
rhyno_dagreat 11 Aug 2006, 08:28
Okay, I've heard of it, but still don't know what it is used for (most things I've looked at that have mentioned it just beat around the bush and never exactly explained what it does). Thanks for all the help!
|
|||
11 Aug 2006, 08:28 |
|
zhak 11 Aug 2006, 08:43
A20 is an address line which allows you to access 64kbytes of memory above 1MB (100000h) in real mode (from 0FFFFh:0010h to 0FFFFh:0FFFFh). Also, if this line is disabled, then 1MB addresses will be wrapped. In example, if you try to write a byte at address 0FFFFh:0610h (100600h linear), then this byte will be actually written at address 0:0600h (000600h) because 20th bit cannot be set (it's not allowed that this bit is equal to 1). It concerns all address ranges that have 20th bit set: from 100000h to 1FFFFFh; from 300000h to 3FFFFFh, etc.
|
|||
11 Aug 2006, 08:43 |
|
rhyno_dagreat 11 Aug 2006, 21:40
Cool... Wait, you mean the 4GB of memory altogether? I thought I already set that up in my code. If you look closely I have both a data and code segment set up, which I thought the two together worked together to allow me to have 4GB of memory?
But then again, could you give me some links on it, just in case I'm wrong on that? |
|||
11 Aug 2006, 21:40 |
|
zhak 11 Aug 2006, 22:16
I don't have any links on this topic. try google, wikipedia, osdever.net and other OSDev related sites. The whole Internet is for you...
Yes, you've enabled protected mode with 4GB segments... but try to write smth. at address 100000h and read the same value. I'm sure, you'll get wrong result if A20 isn't enabled. |
|||
11 Aug 2006, 22:16 |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.