Writing an option rom, a few problems

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
User avatar
sdose
Posts: 9
Joined: Wed Nov 02, 2016 2:20 am

Writing an option rom, a few problems

Post by sdose »

Hi,

I'm working on an AM186 system and need a way to debug while building the system.
What i have so far is a working system with a ZIF-socket for ROM/flash.
I built an "in-system" programmer using a microcontroller and some latches, driving the whole thing into reset and the bus is disconnected from the flash.

Now i want to write some test code, that can run either on a PC, an emulator or on my hardware. The hardware will be more or less PC compatible anyway. I hope i'll end up having a debug-tool on a 8bit ISA card.

I wrote the following piece of code and I'm trying to emulate this with qemu. The problem is, i want to clear the screen and write a few chars to 0,0. Nothing happens, but of a few chars from qemu-bios gets "recolored" in the color i specified in my printing routine. There's also a screenshot attached.

These routines are working when using it in bootloader code on a floppy.

Code: Select all

	bits	16
	org		0x0000
	
	db		0x55
	db		0xAA	; signature
	
	db		16		; length of option rom in 512b increments = 8k
	
	call	rom_init
	retf
	
	
rom_init:
		call clrscr 
		mov bl, 0x03
		mov al, '@'
		mov	cx, 10		
		mov	ah, 0x09
		int	0x10			; print CX n chars in AL with color BL to cursor

		retn	

clrscr:
	mov dh, 0
	mov dl, 0
	call set_cursor
	mov ah, 0x0a
	mov al, ' '
	mov bh, 0
	mov cx, 2000
	int 0x10
	ret	

; DH = row, DL = col
set_cursor:
	mov ah, 0x02
	int 0x10
	ret
	
msg_init	db	"option rom init.", 0

; fill with zeroes till signature
times 	8191-($-$$) db	0x00
					db 	0x00	; checksum
								; will be calculated by script
ROM checksum gets calculated after assembling using a script provided by qemu (signrom.py). This seems to work. If i don't sign, nothing happens at all on boot.

nasm+qemu invocation:

Code: Select all

nasm -f bin -o rom.bin rom.asm
python signrom.py rom.bin rom.bin.signed
qemu-system-i386 -net none -option-rom rom.bin.signed
Also i couldn't find any option to specifiy address in qemu for that option rom. I wonder where it gets loaded...

Thanks
Attachments
qemu.png
qemu.png (1.95 KiB) Viewed 6402 times
User avatar
bzt
Member
Member
Posts: 1584
Joined: Thu Oct 13, 2016 4:55 pm
Contact:

Re: Writing an option rom, a few problems

Post by bzt »

Just a couple of things:
- not sure what that python script does, as BIOS ROM does not need to be signed.
- you don't have a stack, so most probably your first call fails.

You can take a look at my ROM loader code here, maybe you'll get an idea what and how to do:
https://github.com/bztsrc/osz/tree/master/loader
(As it's GPL, you can use it if you like to boot your elf kernel. Just put your kernel as the first elf in an initrd (either tar or cpio) and copy the initrd to the first partition of your disk. My loader is clever enough to locate it, regardless to file system.)

bzt
User avatar
sdose
Posts: 9
Joined: Wed Nov 02, 2016 2:20 am

Re: Writing an option rom, a few problems

Post by sdose »

- not sure what that python script does, as BIOS ROM does not need to be signed.
It is not a BIOS ROM I am attempting to write, it is an option rom and these need to be signed with a checksum.
I started writing a small tool for that job already, when i discovered this python script.
If i do not sign, the ROM gets not executed at all.
you don't have a stack, so most probably your first call fails.
Your code has a lot of information to show, you are far further than me, but i couldn't find a solution there.
I found this https://sites.google.com/site/pinczakko ... ansion-rom
From this place i got the hint to use a PNP rom and try to claim to be an Adaptec SCSI controller - it works, the code is attached.

There's still the question, where does an option rom in qemu gets loaded? To which address? I only could find the argument -option-rom, nothing else.

Code: Select all

	cpu		186
	bits	16
	org		0x0000
	
	db		0x55
	db		0xAA	; signature
	
	db		16		; length of option rom in 512b increments = 8k
	
	jmp rom_init
	retf
	
	Times 	0x18-($-$$) db 0	;;zero fill in between
	dw	PCI_DATA_STRUC			;;Pointer to PCI HDR structure (at 18h)

	Times 	0x1A-($-$$) db 0	;;zero fill in between
	dw	PnP_Header				;;PnP Expansion Header Pointer (at 1Ah)

;----------------------------
; PCI data structure
;----------------------------
PCI_DATA_STRUC:
	db	'PCIR'		;PCI Header Sign
	dw	0x9004		;Vendor ID; 0x9004 = Adaptec
	dw	0x8178		;Device ID; If Vendor == Adaptec => Ultra/Ultra-Wide SCSI Ctrlr
	dw	0x00		;VPD, Vital Product Data can be used for revision information or something else
	dw	0x18		;PCI data struc length (byte)
	db	0x00		;PCI Data struct Rev
	db	0x02		;Base class code, 02h == Network Controller
	db	0x00		;Sub class code = 00h and interface = 00h -->Ethernet Controller
	db	0x00		;Interface code, see PCI Rev2.2 Spec Appendix D
	dw	16			;Image length in mul of 512 byte, little endian format
	dw	0x00		;rev level
	db	0x00		;Code type = x86
	db	0x80		;last image indicator
	dw	0x00		;reserved

;-----------------------------
; PnP ROM Bios Header
;-----------------------------
PnP_Header:
	db	'$PnP'			;PnP Rom header sign
	db	0x01			;Structure Revision
	db	0x02			;Header structure Length in mul of 16 bytes
	dw	0x00			;Offset to next header (00 if none)
	db	0x00			;reserved
	db	0x7A			;8 Bit checksum (for this header, -->
						; --> check again after compile and repair if needed)   <= ?! TODO ?! 
	dd	0x00			;PnP Device ID --> 0h in Realtek RPL ROM
	dw	msg_author		;pointer to manufacturer string
	dw	msg_product		;pointer to product string
	db	0x02,0x00,0x00	;Device Type code 3 byte
	db	0x14			;Device Indicator, 14h from RPL ROM-->See Page 18 of
						;PnP BIOS spec., Lo nibble (4) means IPL device

	dw	0x00			;Boot Connection Vector, 00h = disabled
	dw	0x00			;Disconnect Vector, 00h = disabled
	dw	os_init 		;Bootstrap Entry Vector (BEV)
	dw	0x00			;reserved
	dw	0x00			;Static resource Information vector (0000h if unused)

rom_init:
		pusha
		cli
		mov	ax,cs		
		mov	ds,ax
		mov	es,ax
		
		; stack is at 0000:2000
		mov ax, 0x0000
		mov ss, ax
		mov sp, 0x2000
		sti				; enable interrupts	
		
		call clrscr
		call clrscr
		
		mov bl, 0x0F
		
		mov si, msg_init
		call print_str
		
		call new_line
		
		popa
		retf

os_init: jmp os_init

; print a zero terminated string, args:
; si = string, bl = color
; prints to current cursor position	
print_str:				; si = string, bl = color
	cld
	lodsb
	test	al, al		; test if zero char
	jz	outhere
put_char:
	mov	cx, 1		
	mov	ah, 0x09
	int	0x10			; print CX n chars in AL with color BL to cursor
	call inc_cursor
	jmp	print_str
outhere:
	ret

inc_cursor:
	mov	ah, 0x03 	; get cursor
	int	0x10		; now DH=row DL=col
	inc	dl
	mov	ah, 0x02 	; set cursor
	int	0x10
	ret

new_line:
	mov ah, 0x03
	int 0x10
	inc dh
	xor dl,dl
	mov ah, 0x02
	int 0x10
	ret

clrscr:
	mov dh, 0
	mov dl, 0
	call set_cursor
	mov ah, 0x0a
	mov al, ' '
	mov bh, 0
	mov cx, 2000
	int 0x10
	ret	

; DH = row, DL = col
set_cursor:
	mov ah, 0x02
	int 0x10
	ret

msg_init		db	"option rom init.", 0
msg_author  	db	"nils stec", 0
msg_product		db	"option rom", 0

; fill with zeroes till signature
times 	8191-($-$$) db	0x00
					db 	0x00	; checksum
								; will be calculated by script
User avatar
beyondsociety
Member
Member
Posts: 39
Joined: Tue Oct 17, 2006 10:35 pm
Location: Eagle, ID (USA)
Contact:

Re: Writing an option rom, a few problems

Post by beyondsociety »

Have you tried running it on bochs, it supports loading option roms besides bios, you just need to edit the bochs configuration file and add the rom to it. Not sure how it works in bochs or what is the load address for it as i haven't had a use for it yet. Best bet is to check the documentation for it, hope this helps.
"I think it may be time for some guru meditation"
"Barbarians don't do advanced wizardry"
User avatar
bzt
Member
Member
Posts: 1584
Joined: Thu Oct 13, 2016 4:55 pm
Contact:

Re: Writing an option rom, a few problems

Post by bzt »

sdose wrote:It is not a BIOS ROM I am attempting to write, it is an option rom and these need to be signed with a checksum.
No worries, they are the same. It's a real mode ROM that's executed by BIOS.
I started writing a small tool for that job already, when i discovered this python script.
If i do not sign, the ROM gets not executed at all.
I wouldn't call that signing, but yes, you're right, the checksum must be correct.
There's still the question, where does an option rom in qemu gets loaded? To which address? I only could find the argument -option-rom, nothing else.
Well, you don't know the address. That's why my code relocate itself. To find out which address the rom is mapped to I use:

Code: Select all

; this will push the return address on stack and continue execution on next instruction
call .label
.label:
; get the address and clean up stack
pop si
davidm71
Posts: 3
Joined: Sun Sep 03, 2017 9:26 pm

Re: Writing an option rom, a few problems

Post by davidm71 »

Have you guys been able to load your option rom in either Qemu or Bochs? I can run my test Helloworld type ISA rom in Qemu with the ‘option-rom’ option but it prints garbage on the screen. Bochs just faults with an error stating ‘Rom address out of range’ error no matter if I put in C8000, E0000 or any other address in the Bochs memory address config setting. As for fixing the checksum Pinczakko’s self patching rom has code built in that auto corrects the checksum once compiled by Fasm.
linuxyne
Member
Member
Posts: 211
Joined: Sat Jul 02, 2016 7:02 am

Re: Writing an option rom, a few problems

Post by linuxyne »

SeaBIOS debugging facilities show the addresses from where the option roms are run.

The debug messages are enabled using the QEMU option

Code: Select all

-chardev stdio,id=seabios -device isa-debugcon,iobase=0x402,chardev=seabios
init_optionrom function within SeaBIOS shows that it calls the rom if it is a vga-rom or a pnp-rom.
davidm71
Posts: 3
Joined: Sun Sep 03, 2017 9:26 pm

Re: Writing an option rom, a few problems

Post by davidm71 »

Anyway for an option rom to load and work for 'Any' vendor device id? Or are they all keyed to a particular device?

Thanks
linuxyne
Member
Member
Posts: 211
Joined: Sat Jul 02, 2016 7:02 am

Re: Writing an option rom, a few problems

Post by linuxyne »

Restricting ourselves to SeaBIOS, its config, under "Option ROMs" says that it does support ROMs not associated with any device, although it seems that such a ROM must at least expose a PNP header if it is not a vgarom.
Post Reply