Page 1 of 1
Can't Handle IRQ's in Real Mode
Posted: Thu Sep 27, 2018 5:13 pm
by yasar11732
I am using following code to handler timer and keyboard IRQ's
Code: Select all
.code16
.text
setup:
cli
# setup stack segment
xor %ax, %ax
mov %ax, %ss
mov $0x7bf, %ax
mov %ax, %sp
# setup data segment
xor %ax,%ax
mov %ax, %ds
# setup video memory
mov $0xB800, %ax
mov %ax, %gs
sti
init_random_value:
mov $0,%ah
int $0x1a
mov %dx,random
register_interrupt_handlers:
cli
# timer (int $0x08)
push %es
push $0
pop %es
# IRQ0->INT 8 (4*8 = 32)
mov $32,%bx
movw $timer_handler,%es:(%bx)
inc %bx
inc %bx
movw $0,%es:(%bx)
inc %bx
inc %bx
movw $keyboard_handler,%es:(%bx)
inc %bx
inc %bx
movw $0,%es:(%bx)
pop %es
sti
busy_loop:
mov timer_ticks,%ax
add $18,%ax
_wait:
mov timer_ticks,%bx
cmp %ax,%bx
jg stop_waiting
hlt
jmp _wait
stop_waiting:
call get_random
mov $0x0E, %ah
int $0x10 # output random value
jmp busy_loop
timer_handler:
pusha
incw timer_ticks
mov $20,%al
out %al,$20
popa
iret
keyboard_handler:
pusha
in $0x60,%al
mov %al,scancode
mov $20,%al
out %al,$20
popa
iret
/* Returns 16bit pseudo-random number in ax */
.global get_random
.type get_random,@function
get_random:
mov random,%ax
shl $2,%ax
inc %ax
mov %ax,random
ret
.data
.align 2
random:
.2byte 0
timer_ticks:
.2byte 0
scancode:
.2byte 0
I run this code in VirtualBox and check the memory address where timer_ticks and scancode supposed to be. It appears that IRQ handlers are not fired.
How can I make this work?
Re: Can't Handle IRQ's in Real Mode
Posted: Thu Sep 27, 2018 6:23 pm
by MichaelPetch
You could be having issues because of how you build this or how it is run .I don't know if this was in a bootloader or not. Are you using a linker script, if not what linker command do you use? Showing us exactly how you generate the code, and tell us how you run it.
With that being said the most obvious thing I see wrong is how you send EOI to the PIC. You do:
(youdo this in two places). That should be 0x20 hex not decimal. Try
Re: Can't Handle IRQ's in Real Mode
Posted: Thu Sep 27, 2018 11:33 pm
by Brendan
Hi,
yasar11732 wrote:I am using following code to handler timer and keyboard IRQ's
There's multiple issues here (in addition to the EOI problem MichaelPetch mentioned).
The BIOS will probably need a few KiB of stack space, but you set SS:SP to 0x0000:0x07BF so that there's only about half a KiB of space before the BIOS overwrites its own data in the BDA. It's also strange to misalign the stack. I'm thinking that this might have been a typo (and that you actually wanted SS:SP to 0x0000:0x7C00 so that the first word pushed on the stack ends up just below the code at 0x00007BFE).
If you're not using a linker (which doesn't make too much sense given that most tools don't support real mode); then you're missing an "ORG 0x7C00" at the top or something to define sections.
When registering your interrupt handlers, you're saving and restoring ES for no reason (because it wasn't set to anything that matters in the first place) and could use DS instead of ES (because DS is already set to 0x0000) and avoid an extra "segment override prefix" on some instructions. It would also be more efficient to do direct writes, so the entire thing becomes something like:
Code: Select all
cli
movw $timer_handler,(32)
movw $0,(34)
movw $keyboard_handler,(36)
movw $0,(38)
sti
Your code to get a random number seems strange - after being called 8 times you can guarantee it will always return 0x5555, and after being called 4 times you can guarantee the value 0x55 will be in AL. I'm not sure if you wanted the last instruction to be "xor %ax,random".
Finally; I'm not sure why you're doing this in the first place. The BIOS already has IRQ handlers that aren't broken (e.g. that convert scan codes to ASCII for you and may work with USB keyboards when the nasty and often buggy "PS/2 emulation" isn't enabled); and I'm worried that you're planning to fall into the
"real mode OS trap".
Cheers,
Brendan
Re: Can't Handle IRQ's in Real Mode
Posted: Thu Sep 27, 2018 11:44 pm
by MichaelPetch
Brendan wrote:If you're not using a linker (which doesn't make too much sense given that most tools don't support real mode); then you're missing an "ORG 0x7C00" at the top or something to define sections.
The ORG directive (.org) doesn't work the same in GNU assembler as it does in NASM as far as I know. It is possible to do without an ORG directive using the linker with the default linker script. By linking with
-Ttext=0x7c00 .However this would pose a different problem since the OP declares a .data section which would likely default to 4kb alignment. I felt the OP might be using a linker script since the boot signature was notably absent. Was the main reason I inquired about how this was being built.
Re: Can't Handle IRQ's in Real Mode
Posted: Fri Sep 28, 2018 12:05 am
by Brendan
Hi,
MichaelPetch wrote:Brendan wrote:If you're not using a linker (which doesn't make too much sense given that most tools don't support real mode); then you're missing an "ORG 0x7C00" at the top or something to define sections.
The ORG directive (.org) doesn't work the same in GNU assembler as it does in NASM as far as I know. It is possible to do without an ORG directive using the linker with the default linker script. By linking with
-Ttext=0x7c00 .However this would pose a different problem since the OP declares a .data section which would likely default to 4kb alignment. I felt the OP might be using a linker script since the boot signature was notably absent. Was the main reason I inquired about how this was being built.
Ah - you're right (I forgot ORG works very different for GAS).
I hope they're not using the GNU linker - it doesn't support real mode properly. More specifically, it doesn't support segmentation and only has partial support for "16-bit code pretending not to be 32-bit code". I'm not sure what other options there are (YASM supports AT&T and flat binary but I'm not sure about the directives).
Cheers,
Brendan
Re: Can't Handle IRQ's in Real Mode
Posted: Fri Sep 28, 2018 1:08 am
by yasar11732
MichaelPetch wrote:You could be having issues because of how you build this or how it is run .I don't know if this was in a bootloader or not. Are you using a linker script, if not what linker command do you use? Showing us exactly how you generate the code, and tell us how you run it.
This is my Makefile
Code: Select all
boot.iso: deploy/boot.bin
mkisofs -b boot.bin -hide boot.bin -iso-level 3 -no-emul-boot -o boot.iso deploy/
deploy/boot.bin: build/snake.o
ld -Ttext 7c00 --oformat=binary build/snake.o -nostartfiles -nostdlib -o deploy/boot.bin
build/snake.o: snake.s
as snake.s -o build/snake.o
MichaelPetch wrote:
With that being said the most obvious thing I see wrong is how you send EOI to the PIC. You do:
(youdo this in two places). That should be 0x20 hex not decimal. Try
Thanks, that fixed the problem of IRQ's not firing.
Brendan wrote:Hi,
The BIOS will probably need a few KiB of stack space, but you set SS:SP to 0x0000:0x07BF so that there's only about half a KiB of space before the BIOS overwrites its own data in the BDA. It's also strange to misalign the stack. I'm thinking that this might have been a typo (and that you actually wanted SS:SP to 0x0000:0x7C00 so that the first word pushed on the stack ends up just below the code at 0x00007BFE).
My intention was to put stack 2 byte below the 0x7C00. It was supposed to be 0x7BFD. I was in the impression that putting the stack at 0x7C00 would overwrite my code.
Brendan wrote:
If you're not using a linker (which doesn't make too much sense given that most tools don't support real mode); then you're missing an "ORG 0x7C00" at the top or something to define sections.
I am passing -Ttext 7c00 to my ld. Since I am booting with El Torito, I am not using bios magic value, since it works without it too.
Brendan wrote:Hi,
When registering your interrupt handlers, you're saving and restoring ES for no reason (because it wasn't set to anything that matters in the first place) and could use DS instead of ES (because DS is already set to 0x0000) and avoid an extra "segment override prefix" on some instructions. It would also be more efficient to do direct writes, so the entire thing becomes something like:
Code: Select all
cli
movw $timer_handler,(32)
movw $0,(34)
movw $keyboard_handler,(36)
movw $0,(38)
sti
That was the first thing I tried. After seeing that it didn't work, I tried random things until I gave up and started this thread.
Brendan wrote:
Your code to get a random number seems strange - after being called 8 times you can guarantee it will always return 0x5555, and after being called 4 times you can guarantee the value 0x55 will be in AL. I'm not sure if you wanted the last instruction to be "xor %ax,random".
My random sequence was supposed to be next = 5 * prev + 1 (mod 2^16). Maybe I should sleep more :/ Fixed it now.
Brendan wrote:
Finally; I'm not sure why you're doing this in the first place. The BIOS already has IRQ handlers that aren't broken (e.g. that convert scan codes to ASCII for you and may work with USB keyboards when the nasty and often buggy "PS/2 emulation" isn't enabled); and I'm worried that you're planning to fall into the
"real mode OS trap".
I am trying to do Snake game that works in real mode. I will read direction keys with keyboard interrupts and run main loop with timer interrupts.
Re: Can't Handle IRQ's in Real Mode
Posted: Fri Sep 28, 2018 1:30 am
by yasar11732
MichaelPetch wrote:Brendan wrote:If you're not using a linker (which doesn't make too much sense given that most tools don't support real mode); then you're missing an "ORG 0x7C00" at the top or something to define sections.
The ORG directive (.org) doesn't work the same in GNU assembler as it does in NASM as far as I know. It is possible to do without an ORG directive using the linker with the default linker script. By linking with
-Ttext=0x7c00 .However this would pose a different problem since the OP declares a .data section which would likely default to 4kb alignment. I felt the OP might be using a linker script since the boot signature was notably absent. Was the main reason I inquired about how this was being built.
That explains why I am getting huge binary for no reason
I thought I would get away with not using a linker script.
Re: Can't Handle IRQ's in Real Mode
Posted: Fri Sep 28, 2018 2:19 am
by MichaelPetch
Just combine your .data into your .text section. This can easily be done by getting rid of the .data line.