[U-Boot] [PATCH 2/2] x86: Add support for booting Linux using the 32 bit boot protocol

Gabe Black gabeblack at chromium.org
Wed Nov 30 04:29:36 CET 2011


Hmm, that's in an intervening patch. I didn't think that one was necessary
but apparently it is. I'll add that to the series and send this out again.

Gabe

On Tue, Nov 29, 2011 at 7:23 PM, Graeme Russ <graeme.russ at gmail.com> wrote:

> Hi Gabe,
>
> Thanks, I've been itching for this :)
>
> On Wed, Nov 30, 2011 at 2:11 PM, Gabe Black <gabeblack at chromium.org>
> wrote:
> > This change conditionally modifies the zboot command so that it can use
> the
> > 32 bit boot protocol. This is necessary because the 16 bit realmode entry
> > point assumes that it can call BIOS services which neither coreboot nor
> > u-boot provide.
> >
> > Signed-off-by: Gabe Black <gabeblack at chromium.org>
> > ---
> >  arch/x86/include/asm/zimage.h |    4 +-
> >  arch/x86/lib/bootm.c          |    6 +++-
> >  arch/x86/lib/zimage.c         |   49
> +++++++++++++++++++++++++++++++---------
> >  3 files changed, 44 insertions(+), 15 deletions(-)
> >
> > diff --git a/arch/x86/include/asm/zimage.h
> b/arch/x86/include/asm/zimage.h
> > index 1a77e00..8ee6a74 100644
> > --- a/arch/x86/include/asm/zimage.h
> > +++ b/arch/x86/include/asm/zimage.h
> > @@ -46,8 +46,8 @@
> >
> >  void *load_zimage(char *image, unsigned long kernel_size,
> >                  unsigned long initrd_addr, unsigned long initrd_size,
> > -                 int auto_boot);
> > +                 int auto_boot, void **load_address);
> >
> > -void boot_zimage(void *setup_base);
> > +void boot_zimage(void *setup_base, void *load_address);
> >
> >  #endif
> > diff --git a/arch/x86/lib/bootm.c b/arch/x86/lib/bootm.c
> > index bac7b4f..0905809 100644
> > --- a/arch/x86/lib/bootm.c
> > +++ b/arch/x86/lib/bootm.c
> > @@ -38,6 +38,7 @@ int do_bootm_linux(int flag, int argc, char * const
> argv[],
> >        void            *base_ptr = NULL;
> >        ulong           os_data, os_len;
> >        image_header_t  *hdr;
> > +       void            *load_address;
> >
> >  #if defined(CONFIG_FIT)
> >        const void      *data;
> > @@ -75,7 +76,8 @@ int do_bootm_linux(int flag, int argc, char * const
> argv[],
> >
> >  #ifdef CONFIG_CMD_ZBOOT
> >        base_ptr = load_zimage((void *)os_data, os_len,
> > -                       images->rd_start, images->rd_end -
> images->rd_start, 0);
> > +                       images->rd_start, images->rd_end -
> images->rd_start,
> > +                       0, &load_address);
> >  #endif
> >
> >        if (NULL == base_ptr) {
> > @@ -92,7 +94,7 @@ int do_bootm_linux(int flag, int argc, char * const
> argv[],
> >        /* we assume that the kernel is in place */
> >        printf("\nStarting kernel ...\n\n");
> >
> > -       boot_zimage(base_ptr);
> > +       boot_zimage(base_ptr, load_address);
> >        /* does not return */
> >
> >  error:
> > diff --git a/arch/x86/lib/zimage.c b/arch/x86/lib/zimage.c
> > index 3b33486..1003929 100644
> > --- a/arch/x86/lib/zimage.c
> > +++ b/arch/x86/lib/zimage.c
> > @@ -83,13 +83,12 @@ static void build_command_line(char *command_line,
> int auto_boot)
> >
> >  void *load_zimage(char *image, unsigned long kernel_size,
> >                  unsigned long initrd_addr, unsigned long initrd_size,
> > -                 int auto_boot)
> > +                 int auto_boot, void **load_address)
> >  {
> >        struct boot_params *setup_base;
> >        int setup_size;
> >        int bootproto;
> >        int big_image;
> > -       void *load_address;
> >
> >        struct boot_params *params = (struct boot_params *)image;
> >        struct setup_header *hdr = &params->hdr;
> > @@ -136,14 +135,23 @@ void *load_zimage(char *image, unsigned long
> kernel_size,
> >
> >        /* Determine load address */
> >        if (big_image)
> > -               load_address = (void *)BZIMAGE_LOAD_ADDR;
> > +               *load_address = (void *)BZIMAGE_LOAD_ADDR;
> >        else
> > -               load_address = (void *)ZIMAGE_LOAD_ADDR;
> > +               *load_address = (void *)ZIMAGE_LOAD_ADDR;
> > +
> > +#if defined CONFIG_ZBOOT_32
> > +       printf("Building boot_params at 0x%8.8lx\n", (ulong)setup_base);
> > +       memset(setup_base, 0, sizeof(*setup_base));
> > +       setup_base->hdr = params->hdr;
> >
> > +       setup_base->e820_entries = install_e820_map(
> > +               ARRAY_SIZE(setup_base->e820_map), setup_base->e820_map);
>
> Where is  install_e820_map() defined?
>
> > +#else
> >        /* load setup */
> >        printf("Moving Real-Mode Code to 0x%8.8lx (%d bytes)\n",
> >               (ulong)setup_base, setup_size);
> >        memmove(setup_base, image, setup_size);
> > +#endif
> >
> >        printf("Using boot protocol version %x.%02x\n",
> >               (bootproto & 0xff00) >> 8, bootproto & 0xff);
> > @@ -182,7 +190,7 @@ void *load_zimage(char *image, unsigned long
> kernel_size,
> >
> >                if (hdr->setup_sects >= 15) {
> >                        printf("Linux kernel version %s\n",
> > -                              (char *)setup_base +
> > +                              (char *)params +
> >                               hdr->kernel_version + 0x200);
> >                } else {
> >                        printf("Setup Sectors < 15 - "
> > @@ -237,17 +245,33 @@ void *load_zimage(char *image, unsigned long
> kernel_size,
> >        build_command_line((char *)setup_base + COMMAND_LINE_OFFSET,
> auto_boot);
> >
> >        printf("Loading %czImage at address 0x%08x (%ld bytes)\n",
> > -              big_image ? 'b' : ' ', (u32)load_address, kernel_size);
> > +              big_image ? 'b' : ' ', (u32)*load_address, kernel_size);
> >
> > -
> > -       memmove(load_address, image + setup_size, kernel_size);
> > +       memmove(*load_address, image + setup_size, kernel_size);
> >
> >        /* ready for booting */
> >        return setup_base;
> >  }
> >
> > -void boot_zimage(void *setup_base)
> > +void boot_zimage(void *setup_base, void *load_address)
> >  {
> > +#if defined CONFIG_ZBOOT_32
> > +       /*
> > +        * Set %ebx, %ebp, and %edi to 0, %esi to point to the
> boot_params
> > +        * structure, and then jump to the kernel. We assume that %cs is
> > +        * 0x10, 4GB flat, and read/execute, and the data segments are
> 0x18,
> > +        * 4GB flat, and read/write. U-boot is setting them up that way
> for
> > +        * itself in arch/i386/cpu/cpu.c.
> > +        */
> > +       __asm__ __volatile__ (
> > +       "movl $0, %%ebp         \n"
> > +       "cli                    \n"
> > +       "jmp %[kernel_entry]    \n"
> > +       :: [kernel_entry]"r"(load_address),
> > +          [boot_params] "S"(setup_base),
> > +          "b"(0), "D"(0)
> > +       );
> > +#else
> >        struct pt_regs regs;
> >
> >        memset(&regs, 0, sizeof(struct pt_regs));
> > @@ -258,12 +282,14 @@ void boot_zimage(void *setup_base)
> >        regs.eflags = 0;
> >        enter_realmode(((u32)setup_base + SETUP_START_OFFSET) >> 4, 0,
> >                       &regs, &regs);
> > +#endif
> >  }
> >
> >  int do_zboot(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
> >  {
> >        void *base_ptr;
> >        void *bzImage_addr = NULL;
> > +       void *load_address;
> >        char *s;
> >        ulong bzImage_size = 0;
> >
> > @@ -287,7 +313,8 @@ int do_zboot(cmd_tbl_t *cmdtp, int flag, int argc,
> char *const argv[])
> >                bzImage_size = simple_strtoul(argv[2], NULL, 16);
> >
> >        /* Lets look for */
> > -       base_ptr = load_zimage(bzImage_addr, bzImage_size, 0, 0, 0);
> > +       base_ptr = load_zimage(bzImage_addr, bzImage_size, 0, 0, 0,
> > +               &load_address);
> >
> >        if (!base_ptr) {
> >                printf("## Kernel loading failed ...\n");
> > @@ -299,7 +326,7 @@ int do_zboot(cmd_tbl_t *cmdtp, int flag, int argc,
> char *const argv[])
> >                /* we assume that the kernel is in place */
> >                printf("\nStarting kernel ...\n\n");
> >
> > -               boot_zimage(base_ptr);
> > +               boot_zimage(base_ptr, load_address);
> >                /* does not return */
> >        }
> >
> > --
> > 1.7.3.1
> >
>
> Regards,
>
> Graeme
>


More information about the U-Boot mailing list