Problem Loading Kernel To 0x100000

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

Problem Loading Kernel To 0x100000

Post by brodeur235 »

Bochs will not let me load my kernel to 0x100000 (1MB) in memory. Here is the code:

Code: Select all

;((~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~))
;((               BOOT LOADER STAGE TWO               ))
;((~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~))
%define BLS2
%include "system.inc"

[BITS 16]

global BLS2_MAIN
BLS2_MAIN:
	
	; disable interrupts
	cli
	
	; setup the stack (will call procedures)
	mov ax,0x0000
	mov ss,ax
	mov esp,0x00007E00
	
	; setup data segment
	mov ax,0x0000
	mov ds,ax
	
	; enable A20 line
	call A20_ENABLE
	
	; load kernel
	call K_LOADER
	
	; load GDT
	lgdt [BL2_LOC(GDT_DESC)]
	
	; enter protected mode
	mov eax,cr0
	or eax,0x01
	mov cr0,eax
	
	jmp DWORD 0x0008:0x00100000
	
global K_LOADER
K_LOADER:
	
	mov dl,0x00
	mov dh,0x00
	mov cl,0x0B
	mov ch,0x00
	mov al,0x01
	mov ah,0x02
	mov bx,0x0010
	mov es,bx
	mov bx,0x0000
	int 0x13
	
	ret

global A20_ENABLE
A20_ENABLE:
	call    A20_PROBE
	mov     al,0xAD
	out     0x64,al
	
	call    A20_PROBE
	mov     al,0xD0
	out     0x64,al
	
	call    A20_PROBE2
	in      al,0x60
	push    eax
	
	call    A20_PROBE
	mov     al,0xD1
	out     0x64,al
	
	call    A20_PROBE
	pop     eax
	or      al,2
	out     0x60,al
	
	call    A20_PROBE
	mov     al,0xAE
	out     0x64,al
	
	call    A20_PROBE
	ret
 
A20_PROBE:
        in      al,0x64
        test    al,2
        jnz     A20_PROBE
        ret
 
 
A20_PROBE2:
        in      al,0x64
        test    al,1
        jz      A20_PROBE2
        ret
	
global GDT_TABLE
GDT_TABLE:
	
	; null entry
	db 00000000b
	db 00000000b
	db 00000000b
	db 00000000b
	db 00000000b
	db 00000000b
	db 00000000b
	db 00000000b
	
	; kernel code segment (offset = 0x0008)
	db 11111111b
	db 11111111b
	db 00000000b
	db 00000000b
	db 00000000b
	db 10011010b
	db 11001111b
	db 00000000b
	
	; kernel data segment (offset = 0x0010)
	db 11111111b
	db 11111111b
	db 00000000b
	db 00000000b
	db 00000000b
	db 10010010b
	db 11001111b
	db 00000000b
	
global GDT_DESC
GDT_DESC:
	
	size dw ((GDT_DESC - GDT_TABLE) - 1)
	off  dd BL2_LOC(GDT_TABLE)

	
	; pad to 4.5 Kb
	times (0x1200 - ($ - BLS2_MAIN)) db 0x00
As a result, Boch's repeatedlt triple faults with this dump:

Code: Select all

00004629754i[BIOS ] Booting from 0000:7c00
00004748562e[CPU0 ] write_virtual_checks(): write beyond limit, r/w
00004748562i[CPU0 ] CPU is in protected mode (active)
00004748562i[CPU0 ] CS.d_b = 32 bit
00004748562i[CPU0 ] SS.d_b = 16 bit
00004748562i[CPU0 ] EFER   = 0x00000000
00004748562i[CPU0 ] | RAX=0000000060000011  RBX=0000000000000000
00004748562i[CPU0 ] | RCX=000000000000000b  RDX=0000000000000000
00004748562i[CPU0 ] | RSP=0000000000007e00  RBP=0000000000000000
00004748562i[CPU0 ] | RSI=00000000ffff0000  RDI=000000000008ffac
00004748562i[CPU0 ] |  R8=0000000000000000   R9=0000000000000000
00004748562i[CPU0 ] | R10=0000000000000000  R11=0000000000000000
00004748562i[CPU0 ] | R12=0000000000000000  R13=0000000000000000
00004748562i[CPU0 ] | R14=0000000000000000  R15=0000000000000000
00004748562i[CPU0 ] | IOPL=0 id vip vif ac vm RF nt of df if tf sf zf af PF cf
00004748562i[CPU0 ] | SEG selector     base    limit G D
00004748562i[CPU0 ] | SEG sltr(index|ti|rpl)     base    limit G D
00004748562i[CPU0 ] |  CS:0008( 0001| 0|  0) 00000000 000fffff 1 1
00004748562i[CPU0 ] |  DS:0000( 0005| 0|  0) 00000000 0000ffff 0 0
00004748562i[CPU0 ] |  SS:0000( 0005| 0|  0) 00000000 0000ffff 0 0
00004748562i[CPU0 ] |  ES:0010( 0005| 0|  0) 00000100 0000ffff 0 0
00004748562i[CPU0 ] |  FS:0000( 0005| 0|  0) 00000000 0000ffff 0 0
00004748562i[CPU0 ] |  GS:0000( 0005| 0|  0) 00000000 0000ffff 0 0
00004748562i[CPU0 ] |  MSR_FS_BASE:0000000000000000
00004748562i[CPU0 ] |  MSR_GS_BASE:0000000000000000
00004748562i[CPU0 ] | RIP=0000000000100000 (0000000000100000)
00004748562i[CPU0 ] | CR0=0x60000011 CR1=0x0 CR2=0x0000000000000000
00004748562i[CPU0 ] | CR3=0x00000000 CR4=0x00000000
00004748562i[CPU0 ] >> add byte ptr ds:[eax], al : 0000
00004748562e[CPU0 ] exception(): 3rd (13) exception with no resolution, shutdown status is 00h, resetting
00004748562i[SYS  ] bx_pc_system_c::Reset(SOFTWARE) called
00004748562i[CPU0 ] cpu software reset
The line of interest is:

Code: Select all

00004748562e[CPU0 ] write_virtual_checks(): write beyond limit, r/w
Because if I simply change the kernel loading function to load the kernel to 0x9000 instead of 0x100000, like so:

Code: Select all

global K_LOADER
K_LOADER:
	
	mov dl,0x00
	mov dh,0x00
	mov cl,0x0B
	mov ch,0x00
	mov al,0x01
	mov ah,0x02
	mov bx,0x0000;0x0010
	mov es,bx
	mov bx,0x9000;0x0000
	int 0x13
	
	ret
Then everything executes fine and there is no bochs read/write/virtual checks error or triple fault there is no triple fault.

I know what causes the error, but not why it causes the error...
Help appreciated,

Brodeur235
Gigasoft
Member
Member
Posts: 856
Joined: Sat Nov 21, 2009 5:11 pm

Re: Problem Loading Kernel To 0x100000

Post by Gigasoft »

That's because you're loading it to address 100h, not 100000h. To load something at 100000h, you should have ES=0ffffh and BX=10h. I don't know if this works on all BIOSes, so it's perhaps better to load it to a low memoy location and then copy it to 0ffffh:10h.
Selenic
Member
Member
Posts: 123
Joined: Sat Jan 23, 2010 2:56 pm

Re: Problem Loading Kernel To 0x100000

Post by Selenic »

What you'd probably be best off doing is switching to Unreal Mode; that allows you to copy data/whatever above 1MB using standard instructions (as long as you remember the a32 prefix for stuff like stos*)
User avatar
lemonyii
Member
Member
Posts: 153
Joined: Thu Mar 25, 2010 11:28 pm
Location: China

Re: Problem Loading Kernel To 0x100000

Post by lemonyii »

i load my kernel to 0x100000.
the easiest way is to load it to some place within 1M and then put it to right place.it will be useful if it is ELF or some other format which needs remapping.
for future use,you may need to use multi stage bootloader. maybe GRUB is a good choice.
good luck!
Enjoy my life!------A fish with a tattooed retina
Post Reply