943,923 Members | Top Members by Rank

Ad:
  • Assembly Discussion Thread
  • Unsolved
  • Views: 1877
  • Assembly RSS
May 24th, 2009
0

protected mode switch

Expand Post »
Hello all. I am attempting to write a small operating system, just for kicks (i'm a strange person...), only problem is, i can't seem to make the protected mode switch. I am targeting Intel 80386 and better using NASM to assemble the source. Here is that source:

assembly Syntax (Toggle Plain Text)
  1. bits 16
  2. org 0x00
  3.  
  4. jmp start_os
  5.  
  6. ;these lines are the messages to be printed by our OS
  7.  
  8. switching_msg db "Currently placing processor in 32-bit Protected mode...",0
  9. done_msg db "Done with placing processor in 32-bit Protected mode. I can't believe I finally made it!!!",0
  10. cur_char dw 0x0
  11.  
  12. ;these functions print messages on the screen in 16-bit and 32-bit mode, respectively
  13. print_ln_16:
  14.  
  15. mov ah,0x0e
  16. mov bx,0x0007
  17.  
  18. .print_loop
  19.  
  20. lodsb
  21. or al,al
  22. jz .done
  23.  
  24. int 0x10
  25. jmp .print_loop
  26.  
  27. .done
  28.  
  29. retn
  30.  
  31. bits 32
  32. print_ln_32:
  33.  
  34. mov ax,video_selector
  35. mov gs,ax
  36.  
  37. .print_loop:
  38.  
  39. lodsb
  40. or al,al
  41. jz .done
  42.  
  43. mov ah,0x07
  44. mov word [gs:cur_char],ax
  45. inc word [cur_char]
  46. inc word [cur_char]
  47.  
  48. jmp .print_loop
  49.  
  50. .done:
  51.  
  52. retn
  53.  
  54. bits 16
  55. start_os:
  56.  
  57. mov ax,0x0050
  58. mov ds,ax
  59. mov es,ax
  60.  
  61. mov si,switching_msg
  62. call print_ln_16
  63.  
  64. cli
  65.  
  66. lgdt [global_descriptor]
  67.  
  68. mov eax,cr0
  69. or eax,0x01
  70. mov cr0,eax
  71.  
  72. jmp 0x08:pmode_jmp
  73.  
  74. bits 32
  75. pmode_jmp:
  76.  
  77. mov ax,0x10
  78. mov ds,ax
  79. mov es,ax
  80.  
  81. mov ax,0x18
  82. mov gs,ax
  83.  
  84. mov word [gs:0],0x0641
  85.  
  86. jmp pmode_jmp
  87.  
  88. hang:
  89.  
  90. jmp hang
  91.  
  92. bits 16
  93. global_descriptor:
  94.  
  95. dw gdt_end - gdt_begin -1 ;total length of global descriptor table
  96. dd gdt_begin ;beginning of global descriptor table
  97.  
  98. gdt_begin:
  99.  
  100. empty_selector equ $-gdt_begin ;empty selector located at 0x0 in the table
  101.  
  102. gdt_0 ;first entry is to be a null descriptor
  103.  
  104. dd 0x0 ;make all the entries in
  105. dd 0x0 ;this descriptor null
  106.  
  107. code_selector equ $-gdt_begin ;code selector located at 0x08 in the table
  108.  
  109. gdt_code ;this entry is our code selector
  110.  
  111. dw 0xFFFF ;4 Gb limit
  112. dw 0x0000 ;base is at 0x0
  113. db 0x00
  114. db 0x9A
  115. db 0xCF
  116. db 0x00
  117.  
  118. data_selector equ $-gdt_begin ;data selector located at 0x10
  119.  
  120. gdt_data ;this entry is the data selector
  121.  
  122. dw 0xFFFF ;4 Gb limit
  123. dw 0x0000 ;base is at 0x0
  124. db 0x00
  125. db 0x92
  126. db 0xCF
  127. db 0x00
  128.  
  129. video_selector equ $-gdt_begin ;video selector at 0x18
  130.  
  131. gdt_video ;video selector
  132.  
  133. dw 3999 ;this selector should have a limit of ((80*25)*2)-1 or 3999 decimal
  134. dw 0x8000 ;and should start at 0xB800, video memory
  135. db 0x0B
  136. db 0x92
  137. db 0x00
  138. db 0x00
  139.  
  140. gdt_end

Alot of this was borrowed from a tutorial and i would credit them if i could remember the name. This code just makes the processor reset over and over. What is going wrong with this code? I am using bochs to test the code and here is the log file concerning the processor around reset:

Assembly Syntax (Toggle Plain Text)
  1. 00105544372i[BIOS ] Booting from 0000:7c00
  2. 00107450657e[CPU0 ] check_cs(0x0008): not a valid code segment !
  3. 00107450657i[CPU0 ] CPU is in protected mode (active)
  4. 00107450657i[CPU0 ] CS.d_b = 16 bit
  5. 00107450657i[CPU0 ] SS.d_b = 16 bit
  6. 00107450657i[CPU0 ] EFER = 0x00000000
  7. 00107450657i[CPU0 ] | RAX=0000000060000011 RBX=0000000000000007
  8. 00107450657i[CPU0 ] | RCX=0000000000000003 RDX=0000000000000fff
  9. 00107450657i[CPU0 ] | RSP=000000000000fffb RBP=0000000000000000
  10. 00107450657i[CPU0 ] | RSI=00000000ffff003b RDI=0000000000080005
  11. 00107450657i[CPU0 ] | R8=0000000000000000 R9=0000000000000000
  12. 00107450657i[CPU0 ] | R10=0000000000000000 R11=0000000000000000
  13. 00107450657i[CPU0 ] | R12=0000000000000000 R13=0000000000000000
  14. 00107450657i[CPU0 ] | R14=0000000000000000 R15=0000000000000000
  15. 00107450657i[CPU0 ] | IOPL=0 id vip vif ac vm RF nt of df if tf sf zf af PF cf
  16. 00107450657i[CPU0 ] | SEG selector base limit G D
  17. 00107450657i[CPU0 ] | SEG sltr(index|ti|rpl) base limit G D
  18. 00107450657i[CPU0 ] | CS:0050( 0004| 0| 0) 00000500 0000ffff 0 0
  19. 00107450657i[CPU0 ] | DS:0050( 0005| 0| 0) 00000500 0000ffff 0 0
  20. 00107450657i[CPU0 ] | SS:0000( 0005| 0| 0) 00000000 0000ffff 0 0
  21. 00107450657i[CPU0 ] | ES:0050( 0005| 0| 0) 00000500 0000ffff 0 0
  22. 00107450657i[CPU0 ] | FS:07c0( 0005| 0| 0) 00007c00 0000ffff 0 0
  23. 00107450657i[CPU0 ] | GS:07c0( 0005| 0| 0) 00007c00 0000ffff 0 0
  24. 00107450657i[CPU0 ] | MSR_FS_BASE:0000000000007c00
  25. 00107450657i[CPU0 ] | MSR_GS_BASE:0000000000007c00
  26. 00107450657i[CPU0 ] | RIP=00000000000000eb (00000000000000eb)
  27. 00107450657i[CPU0 ] | CR0=0x60000011 CR1=0x0 CR2=0x0000000000000000
  28. 00107450657i[CPU0 ] | CR3=0x00000000 CR4=0x00000000
  29. 00107450657i[CPU0 ] >> jmp far 0008:00f0 : EAF0000800
  30. 00107450657e[CPU0 ] exception(): 3rd (13) exception with no resolution, shutdown status is 00h, resetting
  31. 00107450657i[SYS ] bx_pc_system_c::Reset(SOFTWARE) called
  32. 00107450657i[CPU0 ] cpu software reset

Sorry this is so long but i just can't seem to figure out where i am going wrong. I studied all of intel's documents but cant seem to find out where i am going wrong!!!!
Last edited by xixpsychoxix; May 24th, 2009 at 10:27 am. Reason: put wrong bochs output in
Similar Threads
Reputation Points: 10
Solved Threads: 0
Newbie Poster
xixpsychoxix is offline Offline
14 posts
since May 2009
Jun 25th, 2009
0

Re: protected mode switch

The triple fault seems to happen when you execute the jump following the switch into protected mode. That makes me wonder whether the org 0 at the beginning of the file corresponds to where you have the file loaded.

Let's say the pmode_jmp label is 256 bytes into the file.
Then jmp 0x08:pmode_jmp will translate into jmp 0x8:0x100, which is fine if you want to end up in the middle of the interrupt vector table. If the file was loaded at 0x8000 (say) what you would really want is jmp 0x8:0x8100.

To get that you would need to have an org 0x8000 at the beginning of the file. Correspondingly, the jump in the boot sector would then be

jmp 0x0000:0x8000
Last edited by mathematician; Jun 25th, 2009 at 8:53 pm.
Reputation Points: 14
Solved Threads: 4
Junior Poster
mathematician is offline Offline
149 posts
since Nov 2006
Jun 26th, 2009
0

Re: protected mode switch

You're reseting the processor so you come up in real mode, you set your CS and DS segment registers and the first thing you do is use the stack in your video interrupt call!

Shouldn't you be setting up your stack as well before you use it?

(Just a thought!)

Once you get this working your next step will probably be instituting a thunk mechanism so you can thunk down from 32-bit to 16-bit for doing your hardware I/O operations.
Reputation Points: 546
Solved Threads: 99
Practically a Posting Shark
wildgoose is offline Offline
891 posts
since Jun 2009
Jun 26th, 2009
0

Re: protected mode switch

Oh and if I remember correctly, you have to initiate the video card before using any of the VIDEO bios interrupts! The graphics chip has to be configured!
Reputation Points: 546
Solved Threads: 99
Practically a Posting Shark
wildgoose is offline Offline
891 posts
since Jun 2009
Jun 26th, 2009
0

Re: protected mode switch

Click to Expand / Collapse  Quote originally posted by wildgoose ...
You're reseting the processor so you come up in real mode, you set your CS and DS segment registers and the first thing you do is use the stack in your video interrupt call!

Shouldn't you be setting up your stack as well before you use it?

(Just a thought!)

Once you get this working your next step will probably be instituting a thunk mechanism so you can thunk down from 32-bit to 16-bit for doing your hardware I/O operations.
He can carry on using the stack he set up in the boot sector, until after he has switched into protected mode.

One of the great joys of writing protected mode operating systems is that, once in protected mode, you can no longer use the BIOS calls (because they were writtent for real mode). Therefore you have to do what the BIOS itself does, and program the hardware directly; usually via i/o ports.
Reputation Points: 14
Solved Threads: 4
Junior Poster
mathematician is offline Offline
149 posts
since Nov 2006
Jun 26th, 2009
0

Re: protected mode switch

Click to Expand / Collapse  Quote originally posted by wildgoose ...
Oh and if I remember correctly, you have to initiate the video card before using any of the VIDEO bios interrupts! The graphics chip has to be configured!
No configuration is needed before you can use int 10h to put text on the screen. Any configuration which may have been necessary will already have been done by the BIOS, which, after all, commonly writes to the screen itself during start up.
Reputation Points: 14
Solved Threads: 4
Junior Poster
mathematician is offline Offline
149 posts
since Nov 2006
Jun 26th, 2009
0

Re: protected mode switch

Okay then I'm confused. The original poster xixpsychoxix wants to write his own operating system and he's starting from the reset entry vector. Nothing is initialized at that time. Thus the Video Bios initialization has to be called to configure the GPU so it can be used properly.

Or am I missing something?
Reputation Points: 546
Solved Threads: 99
Practically a Posting Shark
wildgoose is offline Offline
891 posts
since Jun 2009
Jun 26th, 2009
0

Re: protected mode switch

Click to Expand / Collapse  Quote originally posted by wildgoose ...
Okay then I'm confused. The original poster xixpsychoxix wants to write his own operating system and he's starting from the reset entry vector. Nothing is initialized at that time. Thus the Video Bios initialization has to be called to configure the GPU so it can be used properly.

Or am I missing something?
I am not sure why he has decided to load his OS at 0x50000, because that location usually contains the tail end of the bios data area and a table used by the floppy disk driver.

When a PC boots it starts executing at the address 0xFFFF:0000. Since it is running in real mode, and that address is very near the top of the first 1mb, that just leaves room for a jump instruction to a more sensible location. The BIOS code then sets about the business of initioalising the CRT controller, the Programmable interval timer, the keyboard controller, the peripheral interrupt controller, the floppy disk controller, and others. Having done that, it then reads the first sector from track 0 of the floppy disk, if there is one in the drive. By convention that sector is read into memory at 0x0:7c00. The bios then performs a far jump to that location, and the OS bootstrap code begins executing. From looking at his code it appears that he has arranged for the bootstrap code to read his kernel into memory at 0x50:0000. By the time the kernel is read into memory, the CRT controller, which is the only thing which needs initialising for text mode, has already been set up by the BIOS.

The "reset" he refers to in his post is known as a triple fault. In this case it is probably the result of an attempt to execute an invalid opcode. The processor then generates an exception, only to find that, as yet, no exception handler has been installed. So then it generates another exception, and then another. Upon the third attempt it gives up the unequal struggle and resets itself.
Last edited by mathematician; Jun 26th, 2009 at 5:17 pm.
Reputation Points: 14
Solved Threads: 4
Junior Poster
mathematician is offline Offline
149 posts
since Nov 2006
Jun 26th, 2009
0

Re: protected mode switch

Yes you're absolutely right. I work with too many processor families and got my INT0 mixed up with Reset on the 80x86 family.

And so now it makes more sense, he's not creating an embedded 80x86 product, he's using an off the shelf PC and wants to create his own Operating System for that.

Of course you are correct, BIOS is up and running, fully initialized!
Reputation Points: 546
Solved Threads: 99
Practically a Posting Shark
wildgoose is offline Offline
891 posts
since Jun 2009
Jul 2nd, 2009
0

Re: protected mode switch

Well, i'm just tinkering around with creating my own os for the fun of it, not really because i want to make my own to use. i just program this sort of thing to entertain me and keep my thought process running strong. so i will try to use your ideas here to save my poor operating system and see what i can do. thanx guys
Reputation Points: 10
Solved Threads: 0
Newbie Poster
xixpsychoxix is offline Offline
14 posts
since May 2009

This thread is more than three months old

No one has posted to this discussion for at least three months. Please let old threads die and do not reply to them unless you feel you have something new and valuable to contribute that absolutely must be added to make the discussion complete. Otherwise, please start a new thread in this forum instead.
Message:
Previous Thread in Assembly Forum Timeline: Printing prime numbers in MIPS
Next Thread in Assembly Forum Timeline: write() error code





About Us | Contact Us | Advertise | Acceptable Use Policy
Forum Index | Build Custom RSS Feed


Follow us on Twitter


© 2011 DaniWeb® LLC