Page 1 of 4

What's problem with this code?

Posted: Wed Sep 17, 2008 4:33 am
by InsightSoft
well, I cannot see any problem... Can you help me, please???

run at: 7000:0000 (16bit)
stack: 1000:ffff

(it does not return to rmode safely... but no problem at this stage)

Why the bochs emulator ends like that?

Code: Select all

;-------------------start
[BITS 16]

;structures
	struc gdt_adr
		.limit 		resw 1
		.base		resd 1
	endstruc

	struc gdt_tbl
		.dummy		resb	8
		.ks1code	resb	8
		.ks1video	resb	8
		.ks2code	resb	8
	endstruc

	_ptr	equ	0x0	

	
;External functions



;the code
	global start
	start:
		
		;write to the screen on rm 
		mov ax,  0xb800 
		mov es, ax 	
		mov si, -2
		dox:
			add si, 2
			mov ax, si		
			mov byte [es:si], Al
		 	cmp si, 0xfe
		jne dox		
		mov ax, 0
		int 0x16
		
		
		;where is this code? (16 bits)
		mov ax, cs
		mov ds, ax	
		
		;kernel stage 1 gdt.base
	    and eax, 0xFFFF
        shl eax, 4
      	add ax, gdt + _ptr
	    mov [gdt + gdt_adr.base + _ptr], eax  
	      	      
		;kernel stage 1 gdt.limit
		mov Eax, gdt_tbl_finish - gdt_tbl_start
	    mov [gdt + gdt_adr.limit + _ptr], ax    

		;code
		xor eax, eax
		mov ax, cs
		
		and eax, 0xFFFF
		shl eax, 4
        add ax, start + _ptr
        mov word [gdt_tbl_start + gdt_tbl.ks1code + _ptr + 2], ax
        shr eax,16
        mov byte [gdt_tbl_start + gdt_tbl.ks1code + _ptr + 4], al    		
		
		cli		
		;enable a20 gate   
		call Enable_A20		
		;load gdt
		LGDT [gdt + _ptr]		
		;goto PM - no interrup, there's no IDT
		mov eax, cr0
        or eax, 1
        mov cr0, eax 
		;jmp to PM code (clear buffer)
		db 0xEA
        dw pm_start + _ptr
        dw 8											; 00000000 00001000:x
                                                        ;              ||+-> 00=higest level
                                                        ;			   |+-->  0=gdt
                                                        ;              +--->  1=selector 1 

		pm_start:
			mov ax, 16									; 00000000 00010000 (Video Memory)
			     										;              ||+-> 00=higest level
                                                        ;			   |+-->  0=gdt
                                                        ;              +---> 10=selector 2 
		;write to the screen in pm
		mov es, ax 	
		mov si, -2
		doy:
			add si, 2
			mov ax, si		
			mov byte [es:si], Al
		 	cmp si, 0xfe
		jne doy		

		
		
		;-------------Enable A20 Gate-----------------------------------------------
		Enable_A20:
	        call    a20wait
	        mov     al,0xAD
	        out     0x64,al
	        call    a20wait
	        mov     al,0xD0
	        out     0x64,al	
	        call    a20wait2
	        in      al,0x60
	        push    eax	
	        call    a20wait
	        mov     al,0xD1
	        out     0x64,al
	        call    a20wait
	        pop     eax
	        or      al,2
	        out     0x60,al
	        call    a20wait
	        mov     al,0xAE
	        out     0x64,al
	        call    a20wait
	        sti
	        ret	
			a20wait:
		        in      al,0x64
		        test    al,2
		        jnz     a20wait
		        ret
			a20wait2:
		        in      al,0x64
		        test    al,1
		        jz      a20wait2
		        ret				
		;-------------Global Descriptor Table-----------------------------------------
		gdt:	
			istruc gdt_adr
				at gdt_adr.limit, 		dw 0x0000		;at run-time
				at gdt_adr.base, 		dd 0x00000000	;at run-time
			iend
		
		gdt_tbl_start:
			istruc gdt_tbl
				at gdt_tbl.dummy, 		db 0			;Empty
				
				at gdt_tbl.ks1code, 	dw 0x0			;size 1 e 2
										dw 0x0			;base 1 e 2
		                   				db 0x0			;base 3
		                   				db 0xca			;flag1 	>	1 10 0 1010		> [p=1 (in mem); dpl=10 (level); s=0 (system); segtype=1010]
		                   				db 0x1A			;flag2	>	0 0 0 1 1010	> [g=0 (len in byts); d/b=0 (); 0; avl=1; seg size nib=1010 ();  ] 00011010
		                   				db 0x0			;base4
		                   				                ; 00 00 00 00 (32 bits) (0000:0000) 
		                   								; 04|03|01|02			(7000:0000)
		                   				
				at gdt_tbl.ks1video, 	dw 0x0FA0		;at run-time:fixed/size 0fA0=4.000 bytes
		                   				dw 0x8000		;base1 e 2
		                   				db 0x0B			;base3
		                   				db 0x92			;flag1	> 1 00 1 0010 	> [p=1 (in mem); dpl=00 (level); s=1 (not system); segtype=0010]
		                   				db 0x0			;flag2	> 0 0 0 0 0000 	> [g=0 (len in bytes); d/b=0 (data); 0; avl=0 (?); sg size nib=0000]
		                   				db 0x0			;at run-time:fixed
		                   								;000B8000 32 bits (b800:0000 bits)
		                   								;04030102
		                   				
				at gdt_tbl.ks2code, 	dw 0x0			;	segment for C code
		                   				dw 0x0			;
		                   				db 0x0			;
		                   				db 0x0			;
		                   				db 0x0			;
		                   				db 0x0			;
			iend	
		gdt_tbl_finish:
		;-------------end of Global Descriptor Table-----------------------------------
;-------------------end
the resulte is:

Code: Select all

00032241352i[CPU0 ] CPU is in protected mode (active)
00032241352i[CPU0 ] CS.d_b = 16 bit
00032241352i[CPU0 ] SS.d_b = 16 bit
00032241352i[CPU0 ] EFER   = 0x00000000
00032241352i[CPU0 ] | RAX=0000000060000011  RBX=0000000000000000
00032241352i[CPU0 ] | RCX=0000000000000002  RDX=0000000000000000
00032241352i[CPU0 ] | RSP=000000000000fffd  RBP=0000000000000000
00032241352i[CPU0 ] | RSI=00000000ffff00fe  RDI=000000000008ffac
00032241352i[CPU0 ] |  R8=0000000000000000   R9=0000000000000000
00032241352i[CPU0 ] | R10=0000000000000000  R11=0000000000000000
00032241352i[CPU0 ] | R12=0000000000000000  R13=0000000000000000
00032241352i[CPU0 ] | R14=0000000000000000  R15=0000000000000000
00032241352i[CPU0 ] | IOPL=0 id vip vif ac vm RF nt of df IF tf sf zf af PF cf
00032241352i[CPU0 ] | SEG selector     base    limit G D
00032241352i[CPU0 ] | SEG sltr(index|ti|rpl)     base    limit G D
00032241352i[CPU0 ] |  CS:7000( 0004| 0|  0) 00070000 0000ffff 0 0
00032241352i[CPU0 ] |  DS:7000( 0005| 0|  0) 00070000 0000ffff 0 0
00032241352i[CPU0 ] |  SS:1000( 0005| 0|  0) 00010000 0000ffff 0 0
00032241352i[CPU0 ] |  ES:b800( 0005| 0|  0) 000b8000 0000ffff 0 0
00032241352i[CPU0 ] |  FS:0000( 0005| 0|  0) 00000000 0000ffff 0 0
00032241352i[CPU0 ] |  GS:0000( 0005| 0|  0) 00000000 0000ffff 0 0
00032241352i[CPU0 ] |  MSR_FS_BASE:0000000000000000
00032241352i[CPU0 ] |  MSR_GS_BASE:0000000000000000
00032241352i[CPU0 ] | RIP=000000000000006b (000000000000006b)
00032241352i[CPU0 ] | CR0=0x60000011 CR1=0x0 CR2=0x0000000000000000
00032241352i[CPU0 ] | CR3=0x00000000 CR4=0x00000000
00032241352i[CPU0 ] >> jmp far 0008:0070 : EA70000800
00032241352e[CPU0 ] exception(): 3rd (13) exception with no resolution, shutdown
 status is 00h, resetting

[EDIT] Code tags added by Brendan [/EDIT]

Re: What's problem with this code?

Posted: Wed Sep 17, 2008 4:37 am
by jal
InsightSoft wrote:Why the bochs emulator ends like that?
You enable interrupts at the end of your enable A20 routine, but I cannot see an IDT being set up?


JAL

Re: What's problem with this code?

Posted: Wed Sep 17, 2008 6:19 am
by bewing
jal is right. What is that STI there for?
The next clock interrupt after you enter pmode is what kills you, because you enabled the interrupts with the STI.

Re: What's problem with this code?

Posted: Wed Sep 17, 2008 8:06 am
by InsightSoft
You are right...
but, even deleting that instruction (sti)... the result is the same

Re: What's problem with this code?

Posted: Wed Sep 17, 2008 8:23 am
by ru2aqare
InsightSoft wrote:

Code: Select all

 at gdt_tbl.ks1code,
                 dw 0x0           ;size 1 e 2
                 dw 0x0           ;base 1 e 2
                 db 0x0           ;base 3
                 db 0xca          ;flag1
                 db 0x1A          ;flag2nib=1010 ()
                 db 0x0           ;base4
I am not familiar with this "at" syntax, but are you sure the descriptor flag bytes are correct? Bochs triple-faults on the jump instruction, because something is wrong with the descriptor whose selector you are trying to load into cs:.

My bootloader uses the following values: 9A 00 for the 16-bit code segment, 92 00 for the 16-bit data segment, and 9A CF and 92 CF for the 32-bit code and data segments, respectively.


On a side note, posting code with tabs and spaces mixed guarantees that the result will look messed up.

Re: What's problem with this code?

Posted: Wed Sep 17, 2008 8:28 am
by InsightSoft
probably this is my problem... I will try your suggestion... The 3 descriptor will feet the C 32 bits code... which will sets a new GDT, IDT, etc...

I will try your code...
Thanks...

Re: What's problem with this code?

Posted: Wed Sep 17, 2008 8:43 am
by InsightSoft
No way... the result is the same...

No worry about addresses... (Here is like a tipicaly .COM code...)

Code: Select all

0C98:0100  B8 00 B8 8E C0 BE FE FF 81 C6 02 00 89 F0 26 88  ╕.╕Ä└╛■ ü╞☻.ë≡&ê
0C98:0110  04 81 FE FE 00 75 F1 B8 00 00 CD 16 8C C8 8E D8  ♦ü■■.u±╕..═▬î╚Ä╪
0C98:0120  66 25 FF FF 00 00 66 C1 E0 04 05 CA 00 66 A3 CC  f%  ..f┴α♦♣╩.fú╠
0C98:0130  00 66 B8 20 00 00 00 A3 CA 00 66 31 C0 8C C8 66  .f╕ ...ú╩.f1└î╚f
0C98:0140  25 FF FF 00 00 66 C1 E0 04 05 00 00 A3 DA 00 66  %  ..f┴α♦♣..ú┌.f
0C98:0150  C1 E8 10 A2 DC 00 FA E8 32 00 0F 01 16 CA 00 0F  ┴Φ►ó▄.·Φ2.☼☺▬╩.☼
0C98:0160  20 C0 66 0D 01 00 00 00 0F 22 C0 EA 70 00 08 00   └f♪☺...☼"└Ωp.◘.
0C98:0170  B8 10 00 8E C0 BE FE FF 81 C6 02 00 89 F0 26 88  ╕►.Ä└╛■ ü╞☻.ë≡&ê
0C98:0180  04 81 FE FE 00 75 F1 B8 00 00 CD 16 E8 2D 00 B0  ♦ü■■.u±╕..═▬Φ-.░
0C98:0190  AD E6 64 E8 26 00 B0 D0 E6 64 E8 26 00 E4 60 66  ¡µdΦ&.░╨µdΦ&.Σ`f
0C98:01A0  50 E8 18 00 B0 D1 E6 64 E8 11 00 66 58 0C 02 E6  PΦ↑.░╤µdΦ◄.fX♀☻µ
0C98:01B0  60 E8 08 00 B0 AE E6 64 E8 01 00 C3 E4 64 A8 02  `Φ◘.░«µdΦ☺.├Σd¿☻
0C98:01C0  75 FA C3 E4 64 A8 01 74 FA C3 [color=#804000]00 00 00 00 00 00[/color]  u·├Σd¿☺t·├......
0C98:01D0  [color=#40BF40]00 00 00 00 00 00 00 00[/color][color=#4040FF] 00 00 00 00 00 9A 00 00[/color]  .............Ü..
0C98:01E0  [color=#FF0000]A0 0F 00 80 0B 92 00 00[/color] 00 00 00 00 00 00 00 00  á☼.Ç♂Æ..........
0C98:01F0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0C98:0200  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0C98:0210  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0C98:0220  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0C98:0230  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0C98:0240  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0C98:0250  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0C98:0260  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0C98:0270  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0C98:0280  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0C98:0290  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0C98:02A0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0C98:02B0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0C98:02C0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0C98:02D0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0C98:02E0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0C98:02F0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................

By colors: gdt limit + gtd base + 1 descriptor + 2 second, etc


about 'at': Is there any other elegant way to initialize data in structure??? [Im starting with nasm (: ]

but it seems to me the the values are correct in memory...

Re: What's problem with this code?

Posted: Wed Sep 17, 2008 9:20 am
by Combuster
run at: 7000:0000 (16bit)
0C98:0100
Any reason for that difference?

Edit: you may want to look at this too:

Code: Select all

       add ax, gdt + _ptr
       mov [gdt + gdt_adr.base + _ptr], eax  

Re: What's problem with this code?

Posted: Wed Sep 17, 2008 9:34 am
by ru2aqare
InsightSoft wrote:No way... the result is the same...
By colors: gdt limit + gtd base + 1 descriptor + 2 second, etc
The colors don't show, as the board doesn't recognize the directive or disallows HTML.
InsightSoft wrote: about 'at': Is there any other elegant way to initialize data in structure??? [Im starting with nasm (: ]

but it seems to me the the values are correct in memory...
I am not familiar with nasm at all. I have tried it a few years back, but found soon that it doesn't support structures. So I stuck with masm since.

About your descriptors: the limit=0 field for the code descriptor seems wrong. It should be 65535 for 16-bit segment descriptors.

Re: What's problem with this code?

Posted: Wed Sep 17, 2008 11:04 am
by InsightSoft
Ya ....
The reason is that when I start from bochs, it comes from a boot, that loads the code to 7000:0000...
That address appears because I use CV.EXE from microsoft just to make a simple debug... (: (as you can see, it interprets like a pure COM file starting X:0100) ...

I make simple debug to see if the addresses were calculating the right way... (that's why the variable _ptr; when running under CV.EXE like a .COM the _ptr is 0x0100, and with that I can see the program operating with memory, filling the run-time attributes of the descriptors) (When it run bochs coming from boot the value of _ptr is 0x0)

The last message was to see if the 'at' masm initialize correctly the members of the structure...

About Masm: Really I prefer this program, and I'm using from a long time... but because I can get a pure .BIN files from nasm joined with a C code... I start trying!

Re: What's problem with this code?

Posted: Wed Sep 17, 2008 11:16 am
by InsightSoft
ru2aqare, you right... this it is a bug!
Any way, I have already correct that problem... and (uufff) ... the result is the same!!!

Code: Select all

00014721354i[CPU0 ] | CR3=0x00000000 CR4=0x00000000
00014721354i[CPU0 ] >> jmp far 0008:0070 : EA70000800
00014721354e[CPU0 ] exception(): 3rd (13) exception with no resolution, shutdow
 status is 00h, resetting

Re: What's problem with this code?

Posted: Wed Sep 17, 2008 11:29 am
by InsightSoft
Combuster wrote:
run at: 7000:0000 (16bit)
0C98:0100
Any reason for that difference?

Edit: you may want to look at this too:

Code: Select all

       add ax, gdt + _ptr
       mov [gdt + gdt_adr.base + _ptr], eax  


What's wrong? (I perform a debug and seems working correctly)

Re: What's problem with this code?

Posted: Wed Sep 17, 2008 11:57 am
by ru2aqare
InsightSoft wrote:
Combuster wrote:
run at: 7000:0000 (16bit)
0C98:0100
Any reason for that difference?

Edit: you may want to look at this too:

Code: Select all

       add ax, gdt + _ptr
       mov [gdt + gdt_adr.base + _ptr], eax  
what's wrong? (I perform a debug and seems working correctly)

I believe it should be

Code: Select all

  xor eax, eax
  mov ax, cs 
  mov ds, ax   
; and eax, 0xFFFF ; no need for that, the upper 16 bits are already cleared
  shl eax, 4
  add eax, offset gdt_tbl_start + _ptr ; note the gdt_tbl_start
  mov [gdt + gdt_adr.base + _ptr], eax 
Your terminology is slightly off. What you named "gdt" is actually the GDTR - the Global Descriptor Table Register; and the "gdt_tbl_start" is the actual GDT. The GDTR contains the linear address and the limit of the GDT. The GDT contains the descriptors.

Re: What's problem with this code?

Posted: Wed Sep 17, 2008 12:13 pm
by InsightSoft
You solve my problem...
You are my god...
Any way, offset is not valid or necessary in NASM...
The problem is solved!!!!

Thanks...

Re: What's problem with this code?

Posted: Wed Sep 17, 2008 12:38 pm
by ru2aqare
InsightSoft wrote:You solve my problem...
You are my god...
Any way, offset is not valid or necessary in NASM...
The problem is solved!!!!

Thanks...
The credit goes to Combuster, he spotted the problem. I just explained it.

Off topic: The lack of offset keyword is another reason I don't like nasm. When reading other people's code, I never know if a line like "mov eax, some_name" refers to a label or a constant. Although masm doesn't require the offset keyword, people use it more often, leading to more easily-readable code. And yes, I know if can define offset to an empty constant with nasm, however not everyone does this.