QEMU black screen

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
guowkkk
Posts: 2
Joined: Mon May 30, 2022 4:05 am
Libera.chat IRC: guowkkk

QEMU black screen

Post by guowkkk »

Hello,I made a OS run on floppy,it can run in qemu and vmware,then I modify it to a hard disk version,I use lba28 mode to read disk img,it can run in vmware normally,but can not run in qemu,the screen will become 1024*768 size,but is black screen,I have no idea what's going on here,the os is 32bit,segmentation,no paging,the loader is:

Code: Select all

[INSTRSET "i486p"]		

BOOTPACK_SEC_CNT		EQU			128*1024/512			
BOOTPACK_SEC		EQU			578						
BOOTPAK_ADR		EQU		0x00280000		 
DISK_CACHE_ADR		EQU		0x00100000		
DISK_CAC0		EQU		0x00008000		
VBE_MODE		EQU			0x105		;1024×768

;BOOT_INFO
CYLS EQU 0x0ff0		
LEDS EQU 0x0ff1		
VMODE EQU 0x0ff2	
SCRNX EQU 0x0ff4	
SCRNY EQU 0x0ff6	
VRAM EQU 0x0ff8		
SYS_ESP	EQU	0x0ffc		

PIC0_IMR  EQU    0x0021           
PIC1_IMR  EQU    0x00a1   		  
REGISTER_KBC_STA    EQU    0x0064      		 
REGISTER_KBC_CMD    EQU    0x0064      		  
REGISTER_KBC_DATA	EQU		 0x0060      	 
CMD_KBC_WRITE_OUTREGISTER	EQU    0xd1				
CMD_KBC_OUTREGISTER_A20G_ENABLE		EQU		 0xdf		;A20GATE ON

	ORG 0x8000	
		; DB			"hello asmhead"
		; DB			0	

		MOV 		AH,0x02	
		INT 		 0x16	
		MOV 		BYTE [LEDS],AL
		; JMP			 scrn320

		MOV			AX,0x9000		
		MOV			ES,AX
		MOV			DI,0x00			;ES:DI=0x90000
		MOV			AX,0x4f00		
		INT			 0x10			
		CMP			AX,0x004f		
		JE			 vbe			

scrn320:	
		MOV 		AH,0			
		MOV 		AL,0x13			;320×200×8
		INT 		 0x10			

		MOV 		BYTE [VMODE],8	
		MOV 		WORD [SCRNX],320	
		MOV 		WORD [SCRNY],200	
		MOV 		DWORD [VRAM],0xa0000	
		JMP			 setPIC	
vbe:
		MOV			AX,[ES:DI+4]		;VBE
		CMP			AX,0x0200			;2.0
		JB			 scrn320	
;0x105
		MOV			CX,VBE_MODE			;0x105
		MOV			AX,0x4f01
		INT			 0x10
		CMP			AX,0x004f
		JNE			 scrn320
		 		
		CMP			BYTE [ES:DI+0x19],8						
		JNE			 scrn320	 
		CMP			BYTE [ES:DI+0x1b],4						
		JNE			 scrn320	
		MOV			AX,WORD [ES:DI+0x00]				
		SHR			 AL,7								
		CMP			AL,1						 
		JNE			 scrn320			
;0x105,1024× 768× 8bit
		MOV			AX,0x4f02
		MOV			BX,VBE_MODE+0x4000			
		INT		 	 0x10				 
		MOV 		BYTE [VMODE],8	
		MOV			AX,WORD [ES:DI+0x12]		;x		
		MOV 		WORD [SCRNX],AX
		MOV			AX,WORD [ES:DI+0x14]		;y			
		MOV 		WORD [SCRNY],AX
		MOV			EAX,DWORD [ES:DI+0x28]		;VRAM	
		MOV 		DWORD [VRAM],EAX			

setPIC: 		
	MOV 		AL,0xff			
	OUT 		PIC0_IMR,AL			
	NOP                     	;
	MOV 		AL,0xff			
	OUT 		PIC1_IMR,AL				
	CLI 						
;A20GATE ON
	CALL 		waitKBCReady			;KBC
	MOV 		AL,CMD_KBC_WRITE_OUTREGISTER
	OUT 		REGISTER_KBC_CMD,AL		
	CALL 		waitKBCReady			
	MOV 		AL,CMD_KBC_OUTREGISTER_A20G_ENABLE
	OUT 		REGISTER_KBC_DATA,AL			;A20GATE
	CALL 		waitKBCReady			

;protect mode
	LGDT 		[GDTR0]				
	MOV 		EAX,CR0				
	AND 		EAX,0x7fffffff			
	OR 			EAX,0x00000001			
	MOV 		CR0,EAX
	JMP			pipelineflush
pipelineflush:
	MOV			AX,1*8		
	MOV			DS,AX
	MOV			ES,AX
	MOV			SS,AX
	MOV			GS,AX
	MOV			FS,AX

;0x280000  pio  lba28 	 	 
	MOV			AL,150				
	MOV         ECX,150  					
    SHL         ECX,8                  
	MOV			DX,0x01f2		
	OUT         DX,AL
	   
    MOV         AX,BOOTPACK_SEC      	  
    ;0~7              
    MOV         DX,0x01f3              
    OUT         DX,AL               
    ;8~15
    SHR         AX,8
    MOV         DX,0x01f4              
    OUT         DX,AL
    ;16~23
    XOR			AL,AL                     
    MOV         DX,0x01f5              
    OUT         DX,AL
    ;24~27,4:0,5:1,6:1(LBA),7:1     
    MOV         AL,0xe0                 
    MOV         DX,0x01f6              
    OUT         DX,AL
	
    MOV         AL,0x20                  
    MOV         DX,0x01f7             
    OUT         DX,AL
.waitHDReady:
    IN          AL,DX                   
    AND         AL,0x88                 
    CMP         AL,0x08                 
    JNE         .waitHDReady           
    MOV         DX,0x01f0                    
	MOV			EBX,BOOTPAK_ADR				;0x280000		
.read_word:    
    IN          AX,DX                   
    MOV        WORD [EBX],AX			
    ADD         EBX,2
    DEC         ECX					
    JNZ         .read_word				

;copy data section
	MOV 		EAX,BOOTPAK_ADR		 	;0x280000
	MOV 		EDX,[EAX+16]		;data section bytes count
	ADD 		EDX,3				
	SHR			EDX,2				;double words count
	JZ			Go					
	MOV 		EBX,[EAX+20]		;data section start byte address
	ADD 		EBX,BOOTPAK_ADR		
	MOV 		ECX,[EAX+12]		;esp
	CALL		memcpy		
Go:
	MOV 		EAX,BOOTPAK_ADR		 	
	MOV 		ESP,DWORD [EAX+12]		 
	MOV 		DWORD [SYS_ESP],ESP		
	JMP	 		DWORD 2*8:0x0000001b		;far jump

waitKBCReady:		
	IN 			AL,REGISTER_KBC_STA	
	AND 		AL,0x02			
	JNZ 		waitKBCReady	 
	RET

memcpy:			; EBX:source address,ECX:destination, EDX:double words count
	MOV 		EAX,DWORD [EBX]
	MOV 		DWORD [ECX],EAX
	ADD 		EBX,4
	ADD			ECX,4
	SUB 		EDX,1
	JNZ			memcpy
	RET

	ALIGNB	16	
GDT0:			;GDT
	RESB 8		
	DB 		0xff,0xff,0x00,0x00,0x00,0x92,0xcf,0x00		;set_segmdesc(gdt + 1, 0xffffffff, 0x00000000, 0x4092);
	DW		0xffff,0x0000,0x9a28,0x0047				;set_segmdesc(gdt + 2, 0x0007ffff, 0x00280000, 0x409a);
	DW 		0
GDTR0:		;GDTR
	DW 		8*3-1		
	DD		GDT0		

	ALIGNB	16
The qemu version is 7.0.0,and the start command is

Code: Select all

qemu-system-x86_64.exe -name test -L . -m 1024 -hda haribHD.img  -boot c
Octocontrabass
Member
Member
Posts: 5563
Joined: Mon Mar 25, 2013 7:01 pm

Re: QEMU black screen

Post by Octocontrabass »

guowkkk wrote:32bit,segmentation
Why?

Code: Select all

VBE_MODE		EQU			0x105		;1024×768
This works fine in QEMU, but on some PCs mode 0x105 is not 1024x768x8.

Code: Select all

	OR 			EAX,0x00000001			
	MOV 		CR0,EAX
	JMP			pipelineflush
You need a far JMP. Using real-mode segment descriptors in protected mode is undefined behavior.

Code: Select all

.read_word:    
    IN          AX,DX                   
    MOV        WORD [EBX],AX			
    ADD         EBX,2
    DEC         ECX					
    JNZ         .read_word				
You need to wait for the drive to be ready before reading each sector, not just before reading the first sector.

Code: Select all

	CALL		memcpy		
You need to set ESP before using CALL.
guowkkk
Posts: 2
Joined: Mon May 30, 2022 4:05 am
Libera.chat IRC: guowkkk

Re: QEMU black screen

Post by guowkkk »

Octocontrabass wrote:
guowkkk wrote:32bit,segmentation
Why?

Code: Select all

VBE_MODE		EQU			0x105		;1024×768
This works fine in QEMU, but on some PCs mode 0x105 is not 1024x768x8.

Code: Select all

	OR 			EAX,0x00000001			
	MOV 		CR0,EAX
	JMP			pipelineflush
You need a far JMP. Using real-mode segment descriptors in protected mode is undefined behavior.

Code: Select all

.read_word:    
    IN          AX,DX                   
    MOV        WORD [EBX],AX			
    ADD         EBX,2
    DEC         ECX					
    JNZ         .read_word				
You need to wait for the drive to be ready before reading each sector, not just before reading the first sector.

Code: Select all

	CALL		memcpy		
You need to set ESP before using CALL.

Thank you very much!!It's the .read_word problem,qemu can display now.and I use 32bit,segmentation because I'm quite new on os develop,I think segmentation is easier,so I start from it.
Post Reply