cant print anything after movint to PMode

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
alek
Posts: 5
Joined: Sat Dec 05, 2009 4:58 pm

cant print anything after movint to PMode

Post by alek »

hi,

i am developing simple OS, but after moving into PMode I cannot use 0xb8000 memory to write something to te screen.

Till now, ive done
- INT 10H to change video mode to 0 ( 40x25 chars)
- load "kernel" to 0x500:0 (with INT 0x13)
- load simple GDT (code descriptor from 0x0 up to 4gb, same to data descriptor)
- move to PMode (with far jump after this)
- load IDT (filled with zeros at this time )
- configure PIC
- enable A20gate by 0x64 keyboard port

know i tried many various methods, not only with b800 but also a0000, b0000 but nothing happened. I use VMWare 6.5.2, but i tested on VirtualBox with the same result.

Compilator - nasm

bootloader:

Code: Select all

; ==================================== STAGE 1 ====================================
ORG 0x7C00			; w ktorym miejscu pamieci sie znajdujemy		
BITS 16				; jestesmy w trybie 16 bitowym

  MOV ah,0x0
  MOV al,0
  INT 0x10

; odczytujemy drugi sektor dysku twardego
  MOV ah,0x02		; nr funkcji
  MOV al,5			; liczba sektorow do odczytania
  MOV ch,0			; nr cylindra
  MOV cl,2			; nr sektora
  MOV dh,0			; glowica
  MOV dl,0x80		; numer napedu (0x80 - dysk #0, 0x81 - dysk #1 )

; nasz kod znajdzie sie pod adresem ES:BX - 0x50:0
  MOV bx,0x050
  MOV es,bx			; wrzucamy adres do es
  XOR bx,bx			; zerujemy bx

  INT 0x13
  
  JC blad
  JMP 0x050:0x0000

  blad:
    HLT				; zatrzymujemy procesor

times 510-($-$$) db 0
dw 0xAA55			; standardowa koncowka bootloadera
second file

Code: Select all

ORG 0x500
BITS 16
; ==================================== STAGE 2 ====================================
	CLI
	XOR ax,ax
	MOV ds,ax
	MOV es,ax
	MOV ax,0x9000
	MOV ss,ax
	MOV sp,0xFFFF
	CLI
	LGDT [toc]
    JMP far_jump_after_lgdt
    far_jump_after_lgdt:
	;CALL load_gdt	; ladujemy GDT
	
	MOV ebx,cr0		; rejestru cr0 nie mozemy bezposrednio modyfikowac
	OR ebx,0x1		; ustawiamy najmlodszy bit
	MOV cr0,ebx
	JMP Stage3
	
; ==================================== STAGE 3 ====================================
 		; witamy w 32bitowym swiecie:)
Stage3:
BITS 32
	CLI
	
	MOV ax,0x10
	MOV ds,ax
	MOV ss,ax
	MOV es,ax
	MOV esp,0x90000
	
	LIDT[idt_ptr]
	
	MOV al, 0x11
	OUT 0x20,al
	OUT 0xA0,al
	; ICW2
	MOV al,0x20
	OUT 0x21,al
	MOV al,0x28
	OUT 0xA1,al

	; ICW 3
	MOV al,0x4
	OUT 0x21,al

    ;ICW4
    MOV al,0x1
    OUT 0x21,al
    OUT 0xA1,al
    
    MOV al,0x0
    OUT 0x21,al
    OUT 0xA1,al
    
    ; A20
    CLI
    MOV al,0xDD
    OUT 0x64,al
    
    ;MOV ebx,0xb8000
    ; nothing works! cant write to the screen!
    MOV byte [es:0xb8000],'A'
    MOV byte [es:0xb8001],1
    MOV byte [es:0xb0000],'A'
    MOV byte [es:0xb0001],1
	
    ; instead of HLT
	aaa:
	JMP aaa
	

; ================================ INSTRUKCJE GDT =================================
; This is the beginning of the GDT. Because of this, its offset is 0.
gdt_data:

; null descriptor  offset 0x0
	dd 0 				; null descriptor--just fill 8 bytes with zero
	dd 0 

; code descriptor		offset 0x8
	dw 0FFFFh 			; limit low
	dw 0 				; base low
	db 0 				; base middle
	db 10011010b 		; access
	db 11001111b 		; granularity
	db 0 				; base high

; data descriptor:		offset 0x10
	dw 0FFFFh 			; limit low (Same as code)
	dw 0 				; base low
	db 0 				; base middle
	db 10010010b 		; access
	db 11001111b 		; granularity
	db 0				; base high
end_of_gdt:


toc: 
	dw end_of_gdt - gdt_data - 1 	; limit (Size of GDT)
	dd gdt_data 			; base of GDT
end_data:

idt_start: times 256 dq 0
idt_end:

idt_ptr:
  .limit dw idt_end - idt_start
  .base dd idt_start

in case: i load output data with:

sudo dd if=boot_st1.bin of=/dev/sdb/ bs=512 count=1
sudo dd if=boot_st2.bin of=/dev/sdb/ bs=512 count=1 seek=2

and - some comments are in polish ;)
User avatar
djsilence
Member
Member
Posts: 70
Joined: Wed Oct 01, 2008 11:18 am
Location: Ukraine, Kiev
Contact:

Re: cant print anything after movint to PMode

Post by djsilence »

- INT 10H to change video mode to 0 ( 40x25 chars)
Does printing work with 80x25 mode (it is standard mode and used by default). try not to change mode and test it.
know i tried many various methods, not only with b800 but also a0000, b0000 but nothing happened. I use VMWare 6.5.2, but i tested on VirtualBox with the same result.
Have you tried 0xC0000, 0xA8000 and 0xC8000?
MOV byte [es:0xb8000],'A'
MOV byte [es:0xb8001],1
MOV byte [es:0xb0000],'A'
MOV byte [es:0xb0001],1
try this:

Code: Select all

    MOV byte [0xb8000],'A'
    MOV byte [0xb8001],1
    MOV byte [0xb0000],'A'
    MOV byte [0xb0001],1
and does everything works before PM in your "kernel"? you have no function to print in real mode in your kernel. you can use it to know if your kernel loaded and executed successful. try this (written in nasm):

Code: Select all

;************************************************;
;	Puts16 ()
;		-Prints a null terminated string
;	DS=>SI: 0 terminated string
;************************************************;

bits	16

Puts16:
		pusha				; save registers
.Loop1:
		lodsb				; load next byte from string from SI to AL
		or	al, al			; Does AL=0?
		jz	Puts16Done		; Yep, null terminator found-bail out
		mov	ah, 0eh			; Nope-Print the character
		int	10h			; invoke BIOS
		jmp	.Loop1			; Repeat until null terminator found
Puts16Done:
		popa				; restore registers
		ret
PS: you twice called "CLI" but there is no "STI". :D :D :D

Daniel.
Don't think a ****, but in ukrainian schools English is TOO BAD!
Hangin10
Member
Member
Posts: 162
Joined: Wed Feb 27, 2008 12:40 am

Re: cant print anything after movint to PMode

Post by Hangin10 »

Code: Select all

LGDT [toc]
    JMP far_jump_after_lgdt
    far_jump_after_lgdt:
   ;CALL load_gdt   ; ladujemy GDT
   
   MOV ebx,cr0      ; rejestru cr0 nie mozemy bezposrednio modyfikowac
   OR ebx,0x1      ; ustawiamy najmlodszy bit
   MOV cr0,ebx
   JMP Stage3
First, I think this is in the wrong order, you should load the GDT, enable protected mode, then
far jump to set CS.

Also, that is not a far jump, read the instruction set reference.
User avatar
djsilence
Member
Member
Posts: 70
Joined: Wed Oct 01, 2008 11:18 am
Location: Ukraine, Kiev
Contact:

Re: cant print anything after movint to PMode

Post by djsilence »

I recommend to load A20 before comming to PM.
You have to jump throug CODE_DESCRIPTOR: I mean that you have to use jmp 0x08:Stage3, not jmp Stage3.

Daniel.
Don't think a ****, but in ukrainian schools English is TOO BAD!
egos
Member
Member
Posts: 612
Joined: Fri Nov 16, 2007 1:59 pm

Re: cant print anything after movint to PMode

Post by egos »

I recommend to set A20 correctly.
You have to jump throug CODE_DESCRIPTOR: I mean that you have to use jmp 0x08:Stage3, not jmp Stage3.
Yes.

alek, try to use mode 3 or same mode which sets by own pm vga driver before outputting on the screen occurs.
If you have seen bad English in my words, tell me what's wrong, please.
jal
Member
Member
Posts: 1385
Joined: Wed Oct 31, 2007 9:09 am

Re: cant print anything after movint to PMode

Post by jal »

If you cannot comment smartly, don't comment at all. As if setting mode 0 instead of mode 3 would solve anything. If the guy likes his 40x25, just let him, ok? Maybe he's vision impaired for all we know...


JAL
jal
Member
Member
Posts: 1385
Joined: Wed Oct 31, 2007 9:09 am

Re: cant print anything after movint to PMode

Post by jal »

alek wrote:load IDT (filled with zeros at this time )
You can't have it filled with zeroes, as the first exception will trigger a tripple fault. At least fill the first 20 entries with a value pointing to an infinite loop, or whatever. The other entries needn't be filled, as you don't want to bother yourself with hardware IRQs or software interrupts just yet.
configure PIC
Don't, for reasons mentioned above. If you cannot even print to the screen, handling hardware is far, far away into the future.
enable A20gate by 0x64 keyboard port
I'd do this before entering pmode.

Code: Select all

CLI
	XOR ax,ax
	MOV ds,ax
	MOV es,ax
	MOV ax,0x9000
	MOV ss,ax
	MOV sp,0xFFFF
	CLI
Why again a CLI? You just did one.

Code: Select all

LGDT [toc]
    JMP far_jump_after_lgdt
    far_jump_after_lgdt:
	;CALL load_gdt	; ladujemy GDT
	
	MOV ebx,cr0		; rejestru cr0 nie mozemy bezposrednio modyfikowac
	OR ebx,0x1		; ustawiamy najmlodszy bit
	MOV cr0,ebx
	JMP Stage3
You really should read the manuals or at least the WIKI. The correct sequence for entering pmode is:

- load GDT
- set PM bit in CR0
- do far jmp

You first do the jump, then set the bit and do a near jump to Stage3. That won't work.

Code: Select all

Stage3:
	CLI
You seem to really wanna disable those pesky interrupts, don't you? But you already did that. Twice.

Code: Select all

MOV ax,0x10
	MOV ds,ax
	MOV ss,ax
	MOV es,ax
For completeness, I'd also set fs and gs.

Code: Select all

MOV al, 0x11
	OUT 0x20,al
	OUT 0xA0,al
I'd really forget about the PIC until you have something useful to do with it. Now is not the time.
; nothing works! cant write to the screen!
That's no doubt because you don't reach this point at all. Have you tried running your code in Bochs and use the debugger?

Code: Select all

idt_start: times 256 dq 0
Having an IDT with all zeroes is just the same as having none at all.


JAL
egos
Member
Member
Posts: 612
Joined: Fri Nov 16, 2007 1:59 pm

Re: cant print anything after movint to PMode

Post by egos »

jal, don't explain me how to comment the posts. It's my affair. :evil:
If you have seen bad English in my words, tell me what's wrong, please.
jal
Member
Member
Posts: 1385
Joined: Wed Oct 31, 2007 9:09 am

Re: cant print anything after movint to PMode

Post by jal »

egos wrote:jal, don't explain me how to comment the posts. It's my affair.
1) This is a public forum, if you comment on it, expect to be read and critisized. PM someone if you don't like that.
2) I didn't name you in person, it was a generic remark since you were not the only one commenting this. Mode 0 is exactly equal to mode 3 with regards to memory location, and has thus nothing to do with the problem at hand.


JAL
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: cant print anything after movint to PMode

Post by Combuster »

jal wrote:Mode 0 is exactly equal to mode 3 with regards to memory location, and has thus nothing to do with the problem at hand.
Yet nobody uses it, which means that it is relatively untested in emulators. Knowing about a ton of bugs in Bochs' and QEmu's VGA implementation, setting a "weird" mode may only be adding to the problem.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
jal
Member
Member
Posts: 1385
Joined: Wed Oct 31, 2007 9:09 am

Re: cant print anything after movint to PMode

Post by jal »

Combuster wrote:Yet nobody uses it, which means that it is relatively untested in emulators.
Well, relatively untested by the community. I hope emulator makers perform run some test suites on all supported modes. Also, since mode 0 and 3 are so similar, I'd be surprised mode 0 wouldn't work at all. When something doesn't work, assume it's your code, not your tools.
Knowing about a ton of bugs in Bochs' and QEmu's VGA implementation, setting a "weird" mode may only be adding to the problem.
I wouldn't call it "weird". "Not often used on modern computers" would be true, but not "weird", as it is basically mode 3 with half the characters (I'd scold any emulator builder that would put it in separate code).

And yes, Bochs is not fully VGA compatible, but the "bugs" have in my experience mostly to do with being lenient towards bad settings more than not supporting standard operation.


JAL
alek
Posts: 5
Joined: Sat Dec 05, 2009 4:58 pm

Re: cant print anything after movint to PMode

Post by alek »

ok, I covered all mistakes you have told me and now everything works:) I can use 0xB8000 to write to the screen:) (and I removed INT 0x10, I dont change video mode anymore)

But, till now i thought that when I fill IDT with zeros I clear Present Flag ergo any procedure would be called. So I have done STI and was shocked, why did I have Triple Fault ;)
So, at the beggining I must point hardware interrupts to procedure with empty body and then I could do STI?
Of course I dont want to do this with first 32 interrupts, I must know when my system crashes:)
jal
Member
Member
Posts: 1385
Joined: Wed Oct 31, 2007 9:09 am

Re: cant print anything after movint to PMode

Post by jal »

alek wrote:So, at the beggining I must point hardware interrupts to procedure with empty body and then I could do STI?
I wouldn't do STI until you're really ready for handling hardware. This is usually not before you've setup everything else, including proper memory management with paging etc.
Of course I dont want to do this with first 32 interrupts, I must know when my system crashes:)
Those are better called exceptions. They will come whether or not you have cleared the interrupt flag.


JAL
Post Reply