Page 1 of 1

Allocating small amounts of memory with interrupts?

Posted: Tue Nov 18, 2008 1:55 pm
by Frawley
Hello again. I was wondering if it is it possible to allocate small amounts of memory using a specific interrupt from real mode? I tried to use the following:

Code: Select all

__asm__ ("mov $0x20, %bx;");
__asm__ ("mov $0x100, %ax;");
__asm__ ("int $0x31;"); // Call DPMI host
This caused a crash on the virtual machine even though I didn't do anything after attempting to allocate. Thank you for your help!

EDIT: I found out that int 31 is part of protected mode, so that has been causing the crash. However, I am still unsure as to how I can use memory in real mode. Can I just choose any segment I want and write to it? Or do I have to call an interrupt that manages the memory for me?

Re: Allocating small amounts of memory with interrupts?

Posted: Tue Nov 18, 2008 2:59 pm
by ru2aqare
Frawley wrote:Hello again. I was wondering if it is it possible to allocate small amounts of memory using a specific interrupt from real mode? I tried to use the following:

Code: Select all

__asm__ ("mov $0x20, %bx;");
__asm__ ("mov $0x100, %ax;");
__asm__ ("int $0x31;"); // Call DPMI host
This caused a crash on the virtual machine even though I didn't do anything after attempting to allocate. Thank you for your help!
This obviously only works if you have a DPMI host loaded... If you use real mode, you can either call the appropriate MS-DOS interrupt (int 21h) or if you don't have any OS loaded, you can manage the memory allocation yourself.

Re: Allocating small amounts of memory with interrupts?

Posted: Tue Nov 18, 2008 3:02 pm
by Frawley
Haha, I was in the middle of editing my post when you replied. I do not have any OS loaded yet. I am just using a basic kernel that I wrote and it needs a small buffer for another interrupt. Since there is no OS loaded, can I just choose any segment I want to?

Re: Allocating small amounts of memory with interrupts?

Posted: Tue Nov 18, 2008 3:37 pm
by ru2aqare
Frawley wrote:Haha, I was in the middle of editing my post when you replied. I do not have any OS loaded yet. I am just using a basic kernel that I wrote and it needs a small buffer for another interrupt. Since there is no OS loaded, can I just choose any segment I want to?
Almost any. Since you are in real mode, you should get the amount of base memory installed (int 12h, if I remember correctly, also int 15h/eax=E820h may be of use). The memory from 0 to 4FFh is reserved (real-mode interrupt vector table and BIOS data area), also the last few kilobytes of conventional memory (9C00h-9FFFh is a typical range) is reserved for the Extended BIOS Data Area. Other that that, any memory is available.

Edit: since you allocate memory in a interrupt, I would make my memory allocation routines thread-safe - since interrupts can occur anytime, you don't want the memory allocator to be in an inconsistent state when entering the interrupt handler. This means that locking and other synchronisation mechanisms will be necessary. However, in real mode, when there is only one processor executing code, a simple cli/sti type locking will suffice.

Also, if the amount of memory required is small (less than say one kilobyte), I would try to use the stack of the interrupt handler.

Re: Allocating small amounts of memory with interrupts?

Posted: Tue Nov 18, 2008 4:15 pm
by Frawley
Well as a simple disk writing example, I am trying to write to the MBR of my virtual hard disk. I am using int 13 function 3 to write data to the specified track, sector, and head of the hard disk. I am still getting the same error though. Here is the full code I am using:

Code: Select all

__asm__ ("mov $0x500, %ax;");
__asm__ ("mov %ax, %es;");
__asm__ ("xor %bx, %bx;");
__asm__ ("mov $0x0301, %ax;");
__asm__ ("mov $0x0001, %cx;");
__asm__ ("mov $0x0080, %dx;");
__asm__ ("int $0x13;");
A reference for the required parameters for int13 is located here http://www.delorie.com/djgpp/doc/rbinter/id/14/6.html

Re: Allocating small amounts of memory with interrupts?

Posted: Tue Nov 18, 2008 4:24 pm
by Combuster
- Are you using a 32 bit compiler to generate 16-bit code (which wont work without the necessary precautions)?
- What is your VM?
- Does it even have a harddrive configured?
- Define "crash"

Re: Allocating small amounts of memory with interrupts?

Posted: Tue Nov 18, 2008 4:37 pm
by Frawley
I'm using gcc to compile the kernel and using vmware workstation to run it. And yes, there is an 8gb virtual hard disk enabled on it. When I boot up the kernel (using grub) vmware gives me an error that says something similar to
"Virtual machine kernel stack fault. The virtual machine just suffered a stack fault in kernel mode. On a real computer, this would result to a reset of the processor..."

Re: Allocating small amounts of memory with interrupts?

Posted: Tue Nov 18, 2008 5:04 pm
by Combuster
Well, right now I expect that you're either
- trying to call a real mode interrupt from protected mode (crash guarantueed)
- executing 32-bits code as 16 bits code (which cause the most weird errors, including crashes)

Re: Allocating small amounts of memory with interrupts?

Posted: Tue Nov 18, 2008 5:35 pm
by Frawley
It seems to be the first suggestion to me :P
Well since I'm unsure of what to do from here, could you give me a few tips? Should I figure out how to switch back to real mode or should I do something entirely different?

Re: Allocating small amounts of memory with interrupts?

Posted: Wed Nov 19, 2008 4:20 am
by ru2aqare
Frawley wrote:It seems to be the first suggestion to me :P
Well since I'm unsure of what to do from here, could you give me a few tips? Should I figure out how to switch back to real mode or should I do something entirely different?
When GRUB passes control to your kernel, the processor is already in protected mode. If you want to read the hard disk, and use BIOS for it, you either have to switch back to real mode, or write a V86 monitor (it's not that hard, even my boot loader has one, and I managed to get it working without taking a look at any of the available tutorials). Or, you could write a protected-mode ATA driver that does not require the BIOS at all.

Besides, most 32-bit compilers (gcc and msvc included) assume a protected-mode environment. Injecting assembly code intended to be run in a real-mode environment is guaranteed to make something crash...