2 Stage Boot Loader

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
brodeur235
Member
Member
Posts: 86
Joined: Sat Jun 06, 2009 11:55 am

2 Stage Boot Loader

Post by brodeur235 »

I'm re-writing my boot loader to be two stages primarily to avoid the 512 byte limit on the regular sized boot loader. Before I get redirected, I have read this thread and it hasn't helped:

http://forum.osdev.org/viewtopic.php?f= ... ed#p154971

Stages one and two of the boot loader work exactly as expected right up until the very last nasm command at the end of stage two: the far jump. The error I get looks like this:

Code: Select all

00460046282i[BIOS ] Booting from 0000:7c00
00461184682e[CPU0 ] jump_protected: gate type 0 unsupported
00461184682i[CPU0 ] CPU is in protected mode (active)
00461184682i[CPU0 ] CS.d_b = 16 bit
00461184682i[CPU0 ] SS.d_b = 16 bit
00461184682i[CPU0 ] EFER   = 0x00000000
00461184682i[CPU0 ] | RAX=0000000060000011  RBX=000000000000be00
00461184682i[CPU0 ] | RCX=0000000000000000  RDX=0000000000000000
00461184682i[CPU0 ] | RSP=0000000000007e00  RBP=0000000000000000
00461184682i[CPU0 ] | RSI=00000000000e7ed4  RDI=000000000000ffac
00461184682i[CPU0 ] |  R8=0000000000000000   R9=0000000000000000
00461184682i[CPU0 ] | R10=0000000000000000  R11=0000000000000000
00461184682i[CPU0 ] | R12=0000000000000000  R13=0000000000000000
00461184682i[CPU0 ] | R14=0000000000000000  R15=0000000000000000
00461184682i[CPU0 ] | IOPL=0 id vip vif ac vm RF nt of df if tf sf zf af PF cf
00461184682i[CPU0 ] | SEG selector     base    limit G D
00461184682i[CPU0 ] | SEG sltr(index|ti|rpl)     base    limit G D
00461184682i[CPU0 ] |  CS:0000( 0004| 0|  0) 00000000 0000ffff 0 0
00461184682i[CPU0 ] |  DS:0000( 0005| 0|  0) 00000000 0000ffff 0 0
00461184682i[CPU0 ] |  SS:0000( 0005| 0|  0) 00000000 0000ffff 0 0
00461184682i[CPU0 ] |  ES:0000( 0005| 0|  0) 00000000 0000ffff 0 0
00461184682i[CPU0 ] |  FS:0000( 0005| 0|  0) 00000000 0000ffff 0 0
00461184682i[CPU0 ] |  GS:0000( 0005| 0|  0) 00000000 0000ffff 0 0
00461184682i[CPU0 ] |  MSR_FS_BASE:0000000000000000
00461184682i[CPU0 ] |  MSR_GS_BASE:0000000000000000
00461184682i[CPU0 ] | RIP=0000000000007e30 (0000000000007e30)
00461184682i[CPU0 ] | CR0=0x60000011 CR1=0x0 CR2=0x0000000000000000
00461184682i[CPU0 ] | CR3=0x00000000 CR4=0x00000000
00461184682i[CPU0 ] >> jmp far 0008:0000b000 : 66EA00B000000800
00461184682e[CPU0 ] exception(): 3rd (13) exception with no resolution, shutdown status is 00h, resetting
00461184682i[SYS  ] bx_pc_system_c::Reset(SOFTWARE) called
00461184682i[CPU0 ] cpu software reset
my stage two code it:

Code: Select all

; declare a "main"
bl_s2_main:
	
	; ensure interrupts are disabled
	cli
	
	; ensure the stack is setup correctly
	xor ax,ax
	mov ss,ax
	mov sp,STAGE_TWO_OFFSET
	
	; ensure data segments are correct
	xor ax,ax
	mov ds,ax
	mov es,ax
	mov fs,ax
	mov gs,ax
	
	; load the kernel
	call load_kernel
	
	; load the GDT
	lgdt [ BLOC_S2(gdt_descriptor) ]
	
	; enter p_mode
	mov eax,cr0
	or eax,1
	mov cr0,eax
	
	; CODE WORKS PERFECTLY UP TO THIS POINT (NO BOCHS ERRORS AND DBG STATEMENTS WILL OUTPUT FINE HERE)
	
	; jump to kernel
	jmp DWORD 0x0008:KERNEL_OFFSET
I think the problem might be that I'm trying to read from too many disk sectors without increasing the track... How can I tell how many sectors there are in each track so that I know when to carry over X number of sectors and increase the track amount?

Brodeur235
User avatar
~
Member
Member
Posts: 1228
Joined: Tue Mar 06, 2007 11:17 am
Libera.chat IRC: ArcheFire

Re: 2 Stage Boot Loader

Post by ~ »

Are you sure to have enabled A20? If not, you might not be writing anything to an odd Megabyte (0x100000, 0x300000, etc.) and instead writing somewhere at the Megabyte just before.

You should press the SUSPEND button of Bochs and save the machine state in an empty folder (when asked if you want to save disk states answer YES) --- it may make Bochs to freeze, but then with a hex editor with good disassembly capabilities you can inspect the "memory.ram" file to see if your program is properly loaded in the memory areas intended.

You can also inspect the other files to see if everything makes sense. Some files, or maybe all of them, like the "cpu0" file are plaintext files containing the device state (register values).

But you must make sure to add a "jmp $" or some sort of infinite loop just before the crash so you can have an opportunity to SUSPEND to save state.

NOTE: also check carefuly the correctness of the GDT fields of each entry (what's that Gate Type 0 not supported???). You could use the previous method to find out if the GDT is really well-built in the memory.
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: 2 Stage Boot Loader

Post by Brendan »

Hi,
brodeur235 wrote:I think the problem might be that I'm trying to read from too many disk sectors without increasing the track... How can I tell how many sectors there are in each track so that I know when to carry over X number of sectors and increase the track amount?
The CPU will let you JMP to a dodgy address (you'd crash after the JMP, not during the JMP). Your problem is that the GDT is dodgy (e.g. wrong address used for the "lgdt" instruction), or descriptor 0x0008 is wrong.

On a higher level, switching to protected mode in a 512-byte first stage is always a design failure - it leaves you no way for the second stage to load anything (e.g. the third stage or the kernel or the boot image or whatever). I guess what I'm saying is that it's a good idea to load everything your OS will need to get device drivers working (using the BIOS) and gather any information from the BIOS that your OS will need (memory map, VBE, etc); and only switch to protected mode after all this is done (and you don't need the BIOS anymore).


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
Post Reply