Changeset 139


Ignore:
Timestamp:
Dec 10, 2010, 5:09:57 AM (3 years ago)
Author:
stuge
Message:

Support Linux boot protocol v2.10

The current version of FILO is only aware of the Linux boot protocol up
to the version 2.03. This makes it impossible to, e.g., load newer
kernels compiled with CONFIG_RELOCATABLE=y because they require the boot
loader to at least support version 2.05 of the Linux boot loader
protocol. Otherwise the kernel will just panic while trying to
uncompress (because it thinks the load address is NULL).
The attached patch fixes this problem by enhancing the current
implementation to cover the newer protocol versions and respect the new
members, specifically "relocatable_kernel" and "kernel_alignment".

Signed-off-by: Mathias Krause <mathias.krause@…>
Acked-by: Peter Stuge <peter@…>

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/filo/i386/linux_load.c

    r138 r139  
    5858        u8 setup_sects;         /* 0x1f1 */ 
    5959        u16 root_flags;         /* 0x1f2 */ 
    60         u8 reserved2[6];        /* 0x1f4 */ 
     60        u32 syssize;            /* 0x1f4 (2.04+) */ 
     61        u8 reserved2[2];        /* 0x1f8 */ 
    6162        u16 vid_mode;           /* 0x1fa */ 
    6263        u16 root_dev;           /* 0x1fc */ 
     
    8384        /* 2.03+ */ 
    8485        u32 initrd_addr_max;    /* 0x22c */ 
     86        /* 2.05+ */ 
     87        u32 kernel_alignment;   /* 0x230 */ 
     88        u8 relocatable_kernel;  /* 0x234 */ 
     89        u8 min_alignment;       /* 0x235 (2.10+) */ 
     90        u8 reserved6[2];        /* 0x236 */ 
     91        /* 2.06+ */ 
     92        u32 cmdline_size;       /* 0x238 */ 
     93        /* 2.07+ */ 
     94        u32 hardware_subarch;   /* 0x23c */ 
     95        u64 hardware_subarch_data;/* 0x240 */ 
     96        /* 2.08+ */ 
     97        u32 payload_offset;     /* 0x248 */ 
     98        u32 payload_length;     /* 0x24c */ 
     99        /* 2.09+ */ 
     100        u64 setup_data;         /* 0x250 */ 
     101        /* 2.10+ */ 
     102        u64 pref_address;       /* 0x258 */ 
     103        u32 init_size;          /* 0x260 */ 
    85104} __attribute__ ((packed)); 
    86105 
     
    161180        u8 reserved12_5[8];     /* 0x220 */ 
    162181        u32 cmd_line_ptr;       /* 0x228 */ 
    163         u8 reserved13[164];     /* 0x22c */ 
     182        u32 initrd_addr_max;    /* 0x22c */ 
     183        u32 kernel_alignment;   /* 0x230 */ 
     184        u8 relocatable_kernel;  /* 0x234 */ 
     185        u8 reserved13[155];             /* 0x22c */ 
    164186        struct e820entry e820_map[E820MAX];     /* 0x2d0 */ 
    165187        u8 reserved16[688];     /* 0x550 */ 
     
    177199static u32 load_linux_header(struct linux_header *hdr) 
    178200{ 
     201        u32 kern_addr = 0; 
    179202        int load_high; 
    180         u32 kern_addr; 
    181203 
    182204        if (file_read(hdr, sizeof *hdr) != sizeof *hdr) { 
     
    222244                load_high = hdr->loadflags & 1; 
    223245        } 
     246 
     247        /* determine kernel load address */ 
     248        if (hdr->protocol_version >= 0x20a) { 
     249                if (hdr->pref_address >> 32) { 
     250                        debug(" (ignoring 64bit pref_address)"); 
     251                } else { 
     252                        kern_addr = hdr->pref_address; 
     253                } 
     254        } 
     255 
     256        if (hdr->protocol_version >= 0x205 && hdr->relocatable_kernel) { 
     257                printf(" relocatable"); 
     258        } 
     259 
    224260        if (load_high) { 
    225261                printf(" bzImage"); 
    226                 kern_addr = 0x100000; 
     262                if (kern_addr == 0) 
     263                        kern_addr = 0x100000; 
    227264        } else { 
    228265                printf(" zImage or Image"); 
    229                 kern_addr = 0x1000; 
     266                if (kern_addr == 0) 
     267                        kern_addr = 0x1000; 
    230268        } 
    231269 
     
    258296 
    259297        params->loader_type = 0xff;     /* Unregistered Linux loader */ 
     298 
     299        /* copy alignment fields for relocatable kernels */ 
     300        if (hdr->protocol_version >= 0x205) { 
     301                params->relocatable_kernel = hdr->relocatable_kernel; 
     302                params->kernel_alignment = hdr->kernel_alignment; 
     303        } 
    260304} 
    261305 
     
    677721        ctx->eip = kern_addr; 
    678722 
     723        /* set this field in any case to support relocatable kernels */ 
     724        params->kernel_start = kern_addr; 
     725 
    679726        debug("EIP=%#x\n", kern_addr); 
    680727        printf("Jumping to entry point...\n"); 
Note: See TracChangeset for help on using the changeset viewer.