Bean [EMAIL PROTECTED] kirjoitti:
Hi,

Currently, most assembly code are in startup.S. This is normally used
to ensure that the function address are below 1m, which is required if
it would switch to real mode and call bios services. However, this
make the kernel larger. For example, the biosdisk functions are only
used by biodisk module, they should not be placed inside the kernel.

This patch support splitting such code from startup.S. For example, we
create a new module biosdisk_stub.mod for assembly code of biosdisk.
Instead of call prot_to_real and real_to_prot, we call
grub_call_real_stub to enter real mode. grub_call_real_stub would copy
the code to real mode and do the mode switch.

To avoid unnecessary memory transfer, grub_call_real_stub would not
erase the real mode stub when it's done, so that it can be used
directly next time. When the stub area is full, it zero it out and
start anew. The area uses a simple verification method so that the old
mapping is invalidated, the code would need be copied again on their
next use.

The patch shows how to do it for the biosdisk module, here is the new
grub_biosdisk_rw_int13_extensions function.

REAL_STUB_START(grub_biosdisk_rw_int13_extensions)
        movb    %dh, %ah
        movw    %cx, %ds
        int     $0x13           /* do the operation */
        movb    %ah, %dl        /* save return value */
        lret
REAL_STUB_END(grub_biosdisk_rw_int13_extensions)

FUNCTION(grub_biosdisk_rw_int13_extensions)
        pushl   %ebp
        pushl   %esi

        /* compute the address of disk_address_packet */
        movw    %cx, %si
        xorw    %cx, %cx
        shrl    $4, %ecx        /* save the segment to cx */

        /* ah */
        movb    %al, %dh

        leal    grub_biosdisk_rw_int13_extensions_stub, %eax
        call    EXT_C(grub_call_real_stub)

        movb    %dl, %al        /* return value in %eax */

        popl    %esi
        popl    %ebp

        ret

Real mode code is enclosed between REAL_STUB_START and REAL_STUB_END,
no need to use .code16 and .code32 as it's handled by the macro. In
the main function, use

        leal    grub_biosdisk_rw_int13_extensions_stub, %eax
        call    EXT_C(grub_call_real_stub)

to invoke grub_call_real_stub. grub_biosdisk_rw_int13_extensions_stub
is defined in the REAL_STUB_START macro.

This same method can be applied to loaders, vbe, etc. In fact, almost
all function behind grub_call_real_stub can be moved out of startup.S.

I have made generic function that does basically the same thing for bios 
service 0x10 (video). In that modification you prepare registers structure that 
will be configured during real mode switching. I am yet to commit it for 
review, but I think it would be more generic way to do this. When I come back 
from my holiday I will commit the code for review.

So please wait a bit before committing this :)

Thanks,
Vesa Jääskeläinen


_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/grub-devel

Reply via email to