[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH] Move assembly code out of the kernel

From: Bean
Subject: Re: [PATCH] Move assembly code out of the kernel
Date: Thu, 31 Jul 2008 15:46:47 +0800

On Thu, Jul 31, 2008 at 5:20 AM, Bean <address@hidden> wrote:
> 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 make some adjustment for the patch. First, I don't try to remap
blocks anymore, it's not so reliable. and anyway, the real stub area
is 0x8000 long, which is more than enough for the assembly code. If
the area would ever overflow, I just halt grub2. This makes the code
much simpler, and also, there is no need for an extra field to store
the mapped address, we just replace the original address with the
mapped one.

I also add a grub_alloc_real_stub function, which can be used to
allocate memory from the stub area that can be used to to  communicate
with real mode service. Please note that once allocated, the space
can't be released, so remember to save the pointer for later use.

Some real mode service need some kind of alignment for the input data,
so I add two more function grub_call_real_stub_align and
grub_alloc_real_stub_align, which have a alignment parameter. 1 means
no alignment, 2 word alignment, 4 dword alignment, etc. Don't use 0,
it will cause problem for the function.

2008-07-31  Bean  <address@hidden>

        * conf/i386-pc.rmk (biosdisk_mod_SOURCES): Add

        * disk/i386/pc/biosdisk_stub.S: New file.

        * include/grub/i386/pc/biosdisk.h (grub_biosdisk_rw_int13_extensions):
        Remove EXPORT_FUNC, as we have moved it out of the kernel.
        (grub_biosdisk_rw_standard): Likewise.
        (grub_biosdisk_check_int13_extensions): Likewise.
        (grub_biosdisk_get_diskinfo_int13_extensions): Likewise.
        (grub_biosdisk_get_cdinfo_int13_extensions): Likewise.
        (grub_biosdisk_get_diskinfo_standard): Likewise.
        (grub_biosdisk_get_num_floppies): Likewise.

        * include/grub/i386/pc/kernel.h (grub_real_stub): New structure.
        (grub_alloc_real_stub): New function.
        (grub_alloc_real_stub_align): Likewise.
        (grub_call_real_stub): Likewise.
        (grub_call_real_stub_align): Likewise.

        * include/grub/i386/pc/memory.h (GRUB_MEMORY_MACHINE_REAL_STUB_START):
        New macro.

        * include/symbol.h (REAL_STUB_START): New macro.
        (REAL_STUB_END): Likewise.

        * kern/i386/pc/startup.S (real_stub_addr): New variable.
        (grub_alloc_real_stub): New function.
        (grub_alloc_real_stub_align): Likewise.
        (grub_call_real_stub): Likewise.
        (grub_call_real_stub_align): Likewise.
        (grub_biosdisk_rw_int13_extensions): Moved to biosdisk_stub.S.
        (grub_biosdisk_rw_standard): Likewise.
        (grub_biosdisk_check_int13_extensions): Likewise.
        (grub_biosdisk_get_diskinfo_int13_extensions): Likewise.
        (grub_biosdisk_get_cdinfo_int13_extensions): Likewise.
        (grub_biosdisk_get_diskinfo_standard): Likewise.
        (grub_biosdisk_get_num_floppies): Likewise.


Attachment: stub_2.diff
Description: Text Data

reply via email to

[Prev in Thread] Current Thread [Next in Thread]