Hello Kevin,
I can use SeaBIOS to initialize vga and return to coreboot now.
But when I returned to coreboot and call int19, nothing happens. It can boot correctly when call int19 in SeaBIOS. Maybe it has something to do with the stack? How can I call the interrupt of SeaBIOS in coreboot?
2008/7/14, Zhang Rui zrfail@gmail.com:
2008/7/14, Kevin O'Connor kevin@koconnor.net:
[...] Right - seabios needs to be using its stack in order to call 16bit functions. You probably need to save and restore the stack.
[...] I used this: "movl %esp, %esi\n" "movl $" __stringify(BUILD_STACK_ADDR) ", %esp\n" "ljmp $0x10, $post_coreboot\n"
and added this at the end of post_coreboot() function: asm( "movl %esi, %esp\n" "retl" ); Then it can return to coreboot correctly. Till the payload(I used no payload here)
But pci_dev_init() is executed more than one time so vga is initialized more than one time in SeaBIOS. A flag variable would be used to run SeaBIOS only once.
This is fixed now.
However, note that the above wont save/restore the idt/gdt. And again, I'm not sure if coreboot puts its stack/idt/gdt somewhere where seabios may overwrite it.
[...]
And I want to know where will SeaBIOS write in the memory. Such as the range of bda and ebda?
?
Best regards. Zhang Rui
Zhang Rui wrote:
Hello Kevin,
I can use SeaBIOS to initialize vga and return to coreboot now.
But when I returned to coreboot and call int19, nothing happens. It can boot correctly when call int19 in SeaBIOS. Maybe it has something to do with the stack? How can I call the interrupt of SeaBIOS in coreboot?
How are you doing this currently? Maybe coreboot-v2/src/mainboard/via/epia-m/vgabios.c:void vga_enable_console() (around line 233) helps?
But pci_dev_init() is executed more than one time so vga is initialized more than one time in SeaBIOS. A flag variable would be used to run SeaBIOS only once.
This is fixed now.
How are you doing it? I think the correct way is to only initialize one given device for every call into the init function.
Stefan
2008/7/16 Stefan Reinauer stepan@coresystems.de:
Zhang Rui wrote:
Hello Kevin,
I can use SeaBIOS to initialize vga and return to coreboot now.
But when I returned to coreboot and call int19, nothing happens. It can boot correctly when call int19 in SeaBIOS. Maybe it has something to do with the stack? How can I call the interrupt of SeaBIOS in coreboot?
How are you doing this currently? Maybe coreboot-v2/src/mainboard/via/epia-m/vgabios.c:void vga_enable_console() (around line 233) helps?
to use SeaBIOS to initialize vga, refer to http://www.coreboot.org/pipermail/coreboot/2008-July/036593.html to return to coreboot from SeaBIOS, refer to http://www.coreboot.org/pipermail/coreboot/2008-July/036620.html
For calling int19 in coreboot, I wrote a function in SeaBIOS: void VISIBLE32 boot_coreboot() { struct bregs br; dprintf(1, "boot_coreboot: begin\n"); memset(&br, 0, sizeof(br)); dprintf(1, "boot_coreboot: call int 19\n"); call16_int(0x19, &br); dprintf(1, "boot_coreboot: end\n"); } and then use run_address() to execute this boot_coreboot() function in coreboot.
I will read coreboot-v2/src/mainboard/via/epia-m/vgabios.c:void vga_enable_console() to see if it can help.
But pci_dev_init() is executed more than one time so vga is initialized more than one time in SeaBIOS. A flag variable would be used to run SeaBIOS only once.
This is fixed now.
How are you doing it? I think the correct way is to only initialize one given device for every call into the init function.
I inserted some codes at the beginning of run_seabios() which I wrote in vm86.c: static int entered = 0; if (1 == entered) return; entered = 1; So run_seabios() will run only once.
And original pci_dev_init() function in pci_device.c can not execute to the run_bios() function, so I modified it to the following code:
void pci_dev_init(struct device *dev) { printk(BIOS_SPEW, "PCI: pci_dev_init\n"); #if 0 #ifdef CONFIG_PCI_OPTION_ROM_RUN void run_bios(struct device *dev, unsigned long addr); struct rom_header *rom, *ram;
printk(BIOS_INFO, "Probing for option ROM\n"); rom = pci_rom_probe(dev); if (rom == NULL) return; ram = pci_rom_load(dev, rom); if (ram == NULL) return; run_bios(dev, (unsigned long)ram); #endif #else #ifdef CONFIG_PCI_OPTION_ROM_RUN //zhang rui void run_seabios(); run_seabios(); #endif #endif }
Is this OK?
Zhang Rui
On Tue, Jul 15, 2008 at 11:21:38PM +0800, Zhang Rui wrote:
But when I returned to coreboot and call int19, nothing happens. It can boot correctly when call int19 in SeaBIOS. Maybe it has something to do with the stack? How can I call the interrupt of SeaBIOS in coreboot?
Not sure how you tried to do this. It should just be a matter of transitioning to 16bit mode and then executing 'int 0x19'. You do not need to worry about the stack as seabios already initializes that as part of its int19 code.
-Kevin
2008/7/16 Kevin O'Connor kevin@koconnor.net:
On Tue, Jul 15, 2008 at 11:21:38PM +0800, Zhang Rui wrote:
But when I returned to coreboot and call int19, nothing happens. It can boot correctly when call int19 in SeaBIOS. Maybe it has something to do with the stack? How can I call the interrupt of SeaBIOS in coreboot?
Not sure how you tried to do this. It should just be a matter of transitioning to 16bit mode and then executing 'int 0x19'. You do not need to worry about the stack as seabios already initializes that as part of its int19 code.
I wrote a function in SeaBIOS: void VISIBLE32 boot_coreboot() { struct bregs br; dprintf(1, "boot_coreboot: begin\n"); memset(&br, 0, sizeof(br)); dprintf(1, "boot_coreboot: call int 19\n"); call16_int(0x19, &br); dprintf(1, "boot_coreboot: end\n"); } and then use run_address() to execute this boot_coreboot() function in coreboot. "boot_coreboot: begin" can be displayed but "boot_coreboot: end" can not. The program become quiet after executing "call16_int(0x19, &br);"
why this can not run correctly? If I manually change to 16bit mode then call int19 in coreboot, will it be OK? If it does, the 16bit mode option rom codes can use the int handler of SeaBIOS?
Zhang Rui
On Thu, Jul 17, 2008 at 09:58:59AM +0800, Zhang Rui wrote:
I wrote a function in SeaBIOS: void VISIBLE32 boot_coreboot()
[...]
and then use run_address() to execute this boot_coreboot() function in coreboot.
If you want to return to seabios to invoke int19, then you'll need to load seabios' gdt and stack prior to running any C code. (Just like is done for the other 32bit seabios entry points.)
If I manually change to 16bit mode then call int19 in coreboot, will it be OK? If it does, the 16bit mode option rom codes can use the int handler of SeaBIOS?
It should work.
-Kevin
Hello, I am blocked with calling interrupt in coreboot. I tryed these ways: 1. use "asm("int $0x19 \n");". Qemu has no output when executeed here and nothing happens. The reason is that it should jump to real mode before calling int 19.
2. write a function boot_coreboot() in seabios. like:
void VISIBLE32 boot_coreboot() { struct bregs br; dprintf(1, "boot_coreboot: begin\n"); memset(&br, 0, sizeof(br)); dprintf(1, "boot_coreboot: call int 19\n"); call16_int(0x19, &br); dprintf(1, "boot_coreboot: end\n"); } then call boot_coreboot() in seabios. It booted successfully.
I have read the source code of call16_int, it jump to real mode and jump to the int 19 handler function directly, but do not use "int $0x19" asm code. why?
3. write asm code to jump to real mode and call int 19. but in coreboot there is compiling errors when I write asm codes with lables in it in vm86.c. for a simple example: __asm__ __volatile__ ( /* paranoia -- does ecx get saved? not sure. This is * the easiest safe thing to do. */ " pushal \n" " ljmp $0x28, $cbint16bit\n" "cbint16bit: \n" " .code16 \n" " popal\n" );
will cause errors: {standard input}: Assembler messages: {standard input}:746: Error: symbol `cbint16bit' is already defined in seabios there is compiling errors because of ".code16": out/../src/post.c:349: relocation truncated to fit: R_386_16 against `.text'
what is wrong here?
2008/7/17, Kevin O'Connor kevin@koconnor.net:
On Thu, Jul 17, 2008 at 09:58:59AM +0800, Zhang Rui wrote: [...]
If I manually change to 16bit mode then call int19 in coreboot, will it be OK? If it does, the 16bit mode option rom codes can use the int handler of SeaBIOS?
It should work.
On Tue, Aug 05, 2008 at 12:50:54PM +0800, Zhang Rui wrote:
Hello, I am blocked with calling interrupt in coreboot. I tryed these ways:
- use "asm("int $0x19 \n");". Qemu has no output when executeed
here and nothing happens. The reason is that it should jump to real mode before calling int 19.
Right. You'd need to call "int 0x19" after transitioning to real mode.
- write a function boot_coreboot() in seabios. like:
void VISIBLE32 boot_coreboot() { struct bregs br; dprintf(1, "boot_coreboot: begin\n"); memset(&br, 0, sizeof(br)); dprintf(1, "boot_coreboot: call int 19\n"); call16_int(0x19, &br); dprintf(1, "boot_coreboot: end\n"); }
then call boot_coreboot() in seabios. It booted successfully.
I have read the source code of call16_int, it jump to real mode and jump to the int 19 handler function directly, but do not use "int $0x19" asm code. why?
No. The call_int16(0x19, ...) function will call irq_trampoline_0x19 in real mode (see src/util.h). The irq_trampoline_0x19 code is defined in src/romlayout.S (see macro "IRQ_TRAMPOLINE 19") which runs "int 0x19".
- write asm code to jump to real mode and call int 19.
but in coreboot there is compiling errors when I write asm codes with lables in it in vm86.c. for a simple example: __asm__ __volatile__ ( /* paranoia -- does ecx get saved? not sure. This is * the easiest safe thing to do. */ " pushal \n" " ljmp $0x28, $cbint16bit\n" "cbint16bit: \n" " .code16 \n" " popal\n" );
will cause errors: {standard input}: Assembler messages: {standard input}:746: Error: symbol `cbint16bit' is already defined
in seabios there is compiling errors because of ".code16": out/../src/post.c:349: relocation truncated to fit: R_386_16 against `.text'
what is wrong here?
I'm guessing you didn't issue a ".code32" after the ".code16". Not putting the assembler back into 32bit mode will totally confuse it.
Also, you may be running into trouble with the segmented memory model - the 32bit code runs at 0xfxxxx and uses 32bit offsets, while the 16bit code runs at 0xf000:xxxx and uses 16bit offsets.
I'm not sure why you'd want to do this in seabios though - option 2 above would be the preferred way to call int19.
-Kevin
Hello,
2008/8/6, Kevin O'Connor kevin@koconnor.net:
On Tue, Aug 05, 2008 at 12:50:54PM +0800, Zhang Rui wrote: No. The call_int16(0x19, ...) function will call irq_trampoline_0x19 in real mode (see src/util.h). The irq_trampoline_0x19 code is defined in src/romlayout.S (see macro "IRQ_TRAMPOLINE 19") which runs "int 0x19".
yes. My mistake. I see.
3. write asm code to jump to real mode and call int 19. but in coreboot there is compiling errors when I write asm codes with
lables in it in vm86.c. for a simple example: __asm__ __volatile__ ( /* paranoia -- does ecx get saved? not sure. This is * the easiest safe thing to do. */ " pushal \n" " ljmp $0x28, $cbint16bit\n" "cbint16bit: \n" " .code16 \n" " popal\n" );
will cause errors: {standard input}: Assembler messages: {standard input}:746: Error: symbol `cbint16bit' is already defined
I changed all labels to numbers and use "ljmp $0x28, $1f\n". Then It can successfully call interrupt of seabios in coreboot now.
in seabios there is compiling errors because of ".code16": out/../src/post.c:349: relocation truncated to fit: R_386_16 against `.text' what is wrong here?
I'm guessing you didn't issue a ".code32" after the ".code16". Not putting the assembler back into 32bit mode will totally confuse it.
Also, you may be running into trouble with the segmented memory model
- the 32bit code runs at 0xfxxxx and uses 32bit offsets, while the
16bit code runs at 0xf000:xxxx and uses 16bit offsets.
I added ".code32" and the code is now: void tmpboot() { asm( " lgdt %cs:__mygdtaddr \n"
" ljmp $0x20, $boot_16bit\n" "boot_16bit: \n" ".code16 \n" " mov $0x28, %ax \n" " mov %ax, %ds \n" " mov %ax, %es \n" " mov %ax, %fs \n" " mov %ax, %gs \n" " mov %ax, %ss \n"
" movl %cr0, %eax \n" " andl $0xFFFFFFFE, %eax\n" " movl %eax, %cr0 \n"
" ljmp $0xf000, $boot_real \n" "boot_real: \n"
" int $0x19 \n" " .code32\n" ); }
The compiling error also exist. But when I removed "ljmp $0xf000, $boot_real \n", It can go through compilation. Why?
I'm not sure why you'd want to do this in seabios though - option 2 above would be the preferred way to call int19.
I am testing if the interrupt can be called. Now I can call int19 in coreboot with asm codes and in seabios using call_int16() function.
Zhang Rui