[coreboot] [FILO] r131 - trunk/filo/i386
repository service
svn at coreboot.org
Wed May 19 18:31:37 CEST 2010
Author: stepan
Date: Wed May 19 18:31:36 2010
New Revision: 131
URL: http://tracker.coreboot.org/trac/filo/changeset/131
Log:
gnu indent
Signed-off-by: Stefan Reinauer <stepan at coresystems.de>
Acked-by: Stefan Reinauer <stepan at coresystems.de>
Modified:
trunk/filo/i386/context.c
trunk/filo/i386/context.h
trunk/filo/i386/linux_load.c
trunk/filo/i386/segment.c
trunk/filo/i386/segment.h
trunk/filo/i386/sys_info.c
Modified: trunk/filo/i386/context.c
==============================================================================
--- trunk/filo/i386/context.c Wed Apr 21 14:55:47 2010 (r130)
+++ trunk/filo/i386/context.c Wed May 19 18:31:36 2010 (r131)
@@ -29,26 +29,23 @@
#define MAIN_STACK_SIZE 16384
#define IMAGE_STACK_SIZE 4096
-static void start_main(void); /* forward decl. */
-void __exit_context(void); /* assembly routine */
+static void start_main(void); /* forward decl. */
+void __exit_context(void); /* assembly routine */
/*
* Main context structure
* It is placed at the bottom of our stack, and loaded by assembly routine
* to start us up.
*/
-struct context main_ctx __attribute__((section (".initctx"))) = {
- .gdt_base = (u32) gdt,
- .gdt_limit = GDT_LIMIT,
- .cs = FLAT_CS,
- .ds = FLAT_DS,
- .es = FLAT_DS,
- .fs = FLAT_DS,
- .gs = FLAT_DS,
- .ss = FLAT_DS,
- .esp = (u32) ESP_LOC(&main_ctx),
- .eip = (u32) start_main,
- .return_addr = (u32) __exit_context,
+struct context main_ctx __attribute__ ((section(".initctx"))) = {
+ .gdt_base = (u32) gdt,
+ .gdt_limit = GDT_LIMIT,
+ .cs = FLAT_CS, .ds = FLAT_DS,
+ .es = FLAT_DS, .fs = FLAT_DS,
+ .gs = FLAT_DS, .ss = FLAT_DS,
+ .esp = (u32)ESP_LOC(&main_ctx),
+ .eip = (u32) start_main,
+ .return_addr = (u32) __exit_context
};
/* This is used by assembly routine to load/store the context which
@@ -67,73 +64,72 @@
*/
static void start_main(void)
{
- int retval;
- extern int main(void);
+ int retval;
+ extern int main(void);
- /* Save startup context, so we can refer to it later.
- * We have to keep it in physical address since we will relocate. */
- __boot_ctx = virt_to_phys(__context);
+ /* Save startup context, so we can refer to it later.
+ * We have to keep it in physical address since we will relocate. */
+ __boot_ctx = virt_to_phys(__context);
- /* Start the real fun */
- retval = main();
+ /* Start the real fun */
+ retval = main();
- /* Pass return value to startup context. Bootloader may see it. */
- boot_ctx->eax = retval;
+ /* Pass return value to startup context. Bootloader may see it. */
+ boot_ctx->eax = retval;
- /* Returning from here should jump to __exit_context */
- __context = boot_ctx;
+ /* Returning from here should jump to __exit_context */
+ __context = boot_ctx;
}
/* Setup a new context using the given stack.
*/
-struct context *
-init_context(u8 *stack, u32 stack_size, int num_params)
+struct context *init_context(u8 * stack, u32 stack_size, int num_params)
{
- struct context *ctx;
+ struct context *ctx;
- ctx = (struct context *)
- (stack + stack_size - (sizeof(*ctx) + num_params*sizeof(u32)));
- memset(ctx, 0, sizeof(*ctx));
-
- /* Fill in reasonable default for flat memory model */
- ctx->gdt_base = virt_to_phys(gdt);
- ctx->gdt_limit = GDT_LIMIT;
- ctx->cs = FLAT_CS;
- ctx->ds = FLAT_DS;
- ctx->es = FLAT_DS;
- ctx->fs = FLAT_DS;
- ctx->gs = FLAT_DS;
- ctx->ss = FLAT_DS;
- ctx->esp = virt_to_phys(ESP_LOC(ctx));
- ctx->return_addr = virt_to_phys(__exit_context);
+ ctx = (struct context *) (stack + stack_size -
+ (sizeof(*ctx) + num_params * sizeof(u32)));
+ memset(ctx, 0, sizeof(*ctx));
+
+ /* Fill in reasonable default for flat memory model */
+ ctx->gdt_base = virt_to_phys(gdt);
+ ctx->gdt_limit = GDT_LIMIT;
+ ctx->cs = FLAT_CS;
+ ctx->ds = FLAT_DS;
+ ctx->es = FLAT_DS;
+ ctx->fs = FLAT_DS;
+ ctx->gs = FLAT_DS;
+ ctx->ss = FLAT_DS;
+ ctx->esp = virt_to_phys(ESP_LOC(ctx));
+ ctx->return_addr = virt_to_phys(__exit_context);
- return ctx;
+ return ctx;
}
/* Switch to another context. */
struct context *switch_to(struct context *ctx)
{
- struct context *save, *ret;
+ struct context *save, *ret;
- save = __context;
- __context = ctx;
- asm volatile ("push %%cs; call __switch_context" : : : "memory");
- ret = __context;
- __context = save;
- return ret;
+ save = __context;
+ __context = ctx;
+ asm volatile ("push %%cs; call __switch_context" ::: "memory");
+ ret = __context;
+ __context = save;
+ return ret;
}
/* Start ELF Boot image */
u32 start_elf(u32 entry_point, u32 param)
{
- struct context *ctx;
+ struct context *ctx;
- ctx = init_context(image_stack, sizeof image_stack, 1);
- ctx->eip = entry_point;
- ctx->param[0] = param;
- ctx->eax = 0xe1fb007;
- ctx->ebx = param;
+ ctx = init_context(image_stack, sizeof image_stack, 1);
+ ctx->eip = entry_point;
+ ctx->param[0] = param;
+ ctx->eax = 0xe1fb007;
+ ctx->ebx = param;
- ctx = switch_to(ctx);
- return ctx->eax;
+ ctx = switch_to(ctx);
+ return ctx->eax;
}
Modified: trunk/filo/i386/context.h
==============================================================================
--- trunk/filo/i386/context.h Wed Apr 21 14:55:47 2010 (r130)
+++ trunk/filo/i386/context.h Wed May 19 18:31:36 2010 (r131)
@@ -20,39 +20,38 @@
#define i386_CONTEXT_H
struct context {
- /* Stack Segment, placed here because of the alignment issue... */
- u16 ss;
- /* Used with sgdt/lgdt */
- u16 gdt_limit;
- u32 gdt_base;
- /* General registers, accessed with pushal/popal */
- u32 edi;
- u32 esi;
- u32 ebp;
- u32 esp; /* points just below eax */
- u32 ebx;
- u32 edx;
- u32 ecx;
- u32 eax;
+ /* Stack Segment, placed here because of the alignment issue... */
+ u16 ss;
+ /* Used with sgdt/lgdt */
+ u16 gdt_limit;
+ u32 gdt_base;
+ /* General registers, accessed with pushal/popal */
+ u32 edi;
+ u32 esi;
+ u32 ebp;
+ u32 esp; /* points just below eax */
+ u32 ebx;
+ u32 edx;
+ u32 ecx;
+ u32 eax;
#define ESP_LOC(ctx) (&(ctx)->gs)
- /* Segment registers */
- u32 gs;
- u32 fs;
- u32 es;
- u32 ds;
- /* Flags */
- u32 eflags;
- /* Code segment:offset */
- u32 eip;
- u32 cs;
- /* Optional stack contents */
- u32 return_addr;
- u32 param[0];
+ /* Segment registers */
+ u32 gs;
+ u32 fs;
+ u32 es;
+ u32 ds;
+ /* Flags */
+ u32 eflags;
+ /* Code segment:offset */
+ u32 eip;
+ u32 cs;
+ /* Optional stack contents */
+ u32 return_addr;
+ u32 param[0];
};
/* Create a new context in the given stack */
-struct context *
-init_context(u8 *stack, u32 stack_size, int num_param);
+struct context *init_context(u8 * stack, u32 stack_size, int num_param);
/* Switch context */
struct context *switch_to(struct context *);
@@ -63,4 +62,4 @@
/* This can always be safely used to refer to the boot context */
#define boot_ctx ((struct context *) phys_to_virt(__boot_ctx))
-#endif /* i386_CONTEXT_H */
+#endif /* i386_CONTEXT_H */
Modified: trunk/filo/i386/linux_load.c
==============================================================================
--- trunk/filo/i386/linux_load.c Wed Apr 21 14:55:47 2010 (r130)
+++ trunk/filo/i386/linux_load.c Wed May 19 18:31:36 2010 (r131)
@@ -45,262 +45,266 @@
struct e820entry {
unsigned long long addr; /* start of memory segment */
unsigned long long size; /* size of memory segment */
- unsigned long type; /* type of memory segment */
+ unsigned long type; /* type of memory segment */
#define E820_RAM 1
#define E820_RESERVED 2
-#define E820_ACPI 3 /* usable as RAM once ACPI tables have been read */
+#define E820_ACPI 3 /* usable as RAM once ACPI tables have been read */
#define E820_NVS 4
};
/* The header of Linux/i386 kernel */
struct linux_header {
- u8 reserved1[0x1f1]; /* 0x000 */
- u8 setup_sects; /* 0x1f1 */
- u16 root_flags; /* 0x1f2 */
- u8 reserved2[6]; /* 0x1f4 */
- u16 vid_mode; /* 0x1fa */
- u16 root_dev; /* 0x1fc */
- u16 boot_sector_magic; /* 0x1fe */
- /* 2.00+ */
- u8 reserved3[2]; /* 0x200 */
- u8 header_magic[4]; /* 0x202 */
- u16 protocol_version; /* 0x206 */
- u32 realmode_swtch; /* 0x208 */
- u16 start_sys; /* 0x20c */
- u16 kver_addr; /* 0x20e */
- u8 type_of_loader; /* 0x210 */
- u8 loadflags; /* 0x211 */
- u16 setup_move_size; /* 0x212 */
- u32 code32_start; /* 0x214 */
- u32 ramdisk_image; /* 0x218 */
- u32 ramdisk_size; /* 0x21c */
- u8 reserved4[4]; /* 0x220 */
- /* 2.01+ */
- u16 heap_end_ptr; /* 0x224 */
- u8 reserved5[2]; /* 0x226 */
- /* 2.02+ */
- u32 cmd_line_ptr; /* 0x228 */
- /* 2.03+ */
- u32 initrd_addr_max; /* 0x22c */
+ u8 reserved1[0x1f1]; /* 0x000 */
+ u8 setup_sects; /* 0x1f1 */
+ u16 root_flags; /* 0x1f2 */
+ u8 reserved2[6]; /* 0x1f4 */
+ u16 vid_mode; /* 0x1fa */
+ u16 root_dev; /* 0x1fc */
+ u16 boot_sector_magic; /* 0x1fe */
+ /* 2.00+ */
+ u8 reserved3[2]; /* 0x200 */
+ u8 header_magic[4]; /* 0x202 */
+ u16 protocol_version; /* 0x206 */
+ u32 realmode_swtch; /* 0x208 */
+ u16 start_sys; /* 0x20c */
+ u16 kver_addr; /* 0x20e */
+ u8 type_of_loader; /* 0x210 */
+ u8 loadflags; /* 0x211 */
+ u16 setup_move_size; /* 0x212 */
+ u32 code32_start; /* 0x214 */
+ u32 ramdisk_image; /* 0x218 */
+ u32 ramdisk_size; /* 0x21c */
+ u8 reserved4[4]; /* 0x220 */
+ /* 2.01+ */
+ u16 heap_end_ptr; /* 0x224 */
+ u8 reserved5[2]; /* 0x226 */
+ /* 2.02+ */
+ u32 cmd_line_ptr; /* 0x228 */
+ /* 2.03+ */
+ u32 initrd_addr_max; /* 0x22c */
} __attribute__ ((packed));
-
/* Paramters passed to 32-bit part of Linux
* This is another view of the structure above.. */
struct linux_params {
- u8 orig_x; /* 0x00 */
- u8 orig_y; /* 0x01 */
- u16 ext_mem_k; /* 0x02 -- EXT_MEM_K sits here */
- u16 orig_video_page; /* 0x04 */
- u8 orig_video_mode; /* 0x06 */
- u8 orig_video_cols; /* 0x07 */
- u16 unused2; /* 0x08 */
- u16 orig_video_ega_bx; /* 0x0a */
- u16 unused3; /* 0x0c */
- u8 orig_video_lines; /* 0x0e */
- u8 orig_video_isVGA; /* 0x0f */
- u16 orig_video_points; /* 0x10 */
-
- /* VESA graphic mode -- linear frame buffer */
- u16 lfb_width; /* 0x12 */
- u16 lfb_height; /* 0x14 */
- u16 lfb_depth; /* 0x16 */
- u32 lfb_base; /* 0x18 */
- u32 lfb_size; /* 0x1c */
- u16 cl_magic; /* 0x20 */
+ u8 orig_x; /* 0x00 */
+ u8 orig_y; /* 0x01 */
+ u16 ext_mem_k; /* 0x02 -- EXT_MEM_K sits here */
+ u16 orig_video_page; /* 0x04 */
+ u8 orig_video_mode; /* 0x06 */
+ u8 orig_video_cols; /* 0x07 */
+ u16 unused2; /* 0x08 */
+ u16 orig_video_ega_bx; /* 0x0a */
+ u16 unused3; /* 0x0c */
+ u8 orig_video_lines; /* 0x0e */
+ u8 orig_video_isVGA; /* 0x0f */
+ u16 orig_video_points; /* 0x10 */
+
+ /* VESA graphic mode -- linear frame buffer */
+ u16 lfb_width; /* 0x12 */
+ u16 lfb_height; /* 0x14 */
+ u16 lfb_depth; /* 0x16 */
+ u32 lfb_base; /* 0x18 */
+ u32 lfb_size; /* 0x1c */
+ u16 cl_magic; /* 0x20 */
#define CL_MAGIC_VALUE 0xA33F
- u16 cl_offset; /* 0x22 */
- u16 lfb_linelength; /* 0x24 */
- u8 red_size; /* 0x26 */
- u8 red_pos; /* 0x27 */
- u8 green_size; /* 0x28 */
- u8 green_pos; /* 0x29 */
- u8 blue_size; /* 0x2a */
- u8 blue_pos; /* 0x2b */
- u8 rsvd_size; /* 0x2c */
- u8 rsvd_pos; /* 0x2d */
- u16 vesapm_seg; /* 0x2e */
- u16 vesapm_off; /* 0x30 */
- u16 pages; /* 0x32 */
- u8 reserved4[12]; /* 0x34 -- 0x3f reserved for future expansion */
-
- //struct apm_bios_info apm_bios_info; /* 0x40 */
- u8 apm_bios_info[0x40];
- //struct drive_info_struct drive_info; /* 0x80 */
- u8 drive_info[0x20];
- //struct sys_desc_table sys_desc_table; /* 0xa0 */
- u8 sys_desc_table[0x140];
- u32 alt_mem_k; /* 0x1e0 */
- u8 reserved5[4]; /* 0x1e4 */
- u8 e820_map_nr; /* 0x1e8 */
- u8 reserved6[9]; /* 0x1e9 */
- u16 mount_root_rdonly; /* 0x1f2 */
- u8 reserved7[4]; /* 0x1f4 */
- u16 ramdisk_flags; /* 0x1f8 */
+ u16 cl_offset; /* 0x22 */
+ u16 lfb_linelength; /* 0x24 */
+ u8 red_size; /* 0x26 */
+ u8 red_pos; /* 0x27 */
+ u8 green_size; /* 0x28 */
+ u8 green_pos; /* 0x29 */
+ u8 blue_size; /* 0x2a */
+ u8 blue_pos; /* 0x2b */
+ u8 rsvd_size; /* 0x2c */
+ u8 rsvd_pos; /* 0x2d */
+ u16 vesapm_seg; /* 0x2e */
+ u16 vesapm_off; /* 0x30 */
+ u16 pages; /* 0x32 */
+ u8 reserved4[12]; /* 0x34 -- 0x3f reserved for future expansion */
+
+ //struct apm_bios_info apm_bios_info; /* 0x40 */
+ u8 apm_bios_info[0x40];
+ //struct drive_info_struct drive_info; /* 0x80 */
+ u8 drive_info[0x20];
+ //struct sys_desc_table sys_desc_table; /* 0xa0 */
+ u8 sys_desc_table[0x140];
+ u32 alt_mem_k; /* 0x1e0 */
+ u8 reserved5[4]; /* 0x1e4 */
+ u8 e820_map_nr; /* 0x1e8 */
+ u8 reserved6[9]; /* 0x1e9 */
+ u16 mount_root_rdonly; /* 0x1f2 */
+ u8 reserved7[4]; /* 0x1f4 */
+ u16 ramdisk_flags; /* 0x1f8 */
#define RAMDISK_IMAGE_START_MASK 0x07FF
#define RAMDISK_PROMPT_FLAG 0x8000
-#define RAMDISK_LOAD_FLAG 0x4000
- u8 reserved8[2]; /* 0x1fa */
- u16 orig_root_dev; /* 0x1fc */
- u8 reserved9[1]; /* 0x1fe */
- u8 aux_device_info; /* 0x1ff */
- u8 reserved10[2]; /* 0x200 */
- u8 param_block_signature[4]; /* 0x202 */
- u16 param_block_version; /* 0x206 */
- u8 reserved11[8]; /* 0x208 */
- u8 loader_type; /* 0x210 */
+#define RAMDISK_LOAD_FLAG 0x4000
+ u8 reserved8[2]; /* 0x1fa */
+ u16 orig_root_dev; /* 0x1fc */
+ u8 reserved9[1]; /* 0x1fe */
+ u8 aux_device_info; /* 0x1ff */
+ u8 reserved10[2]; /* 0x200 */
+ u8 param_block_signature[4]; /* 0x202 */
+ u16 param_block_version; /* 0x206 */
+ u8 reserved11[8]; /* 0x208 */
+ u8 loader_type; /* 0x210 */
#define LOADER_TYPE_LOADLIN 1
#define LOADER_TYPE_BOOTSECT_LOADER 2
#define LOADER_TYPE_SYSLINUX 3
#define LOADER_TYPE_ETHERBOOT 4
#define LOADER_TYPE_KERNEL 5
- u8 loader_flags; /* 0x211 */
- u8 reserved12[2]; /* 0x212 */
- u32 kernel_start; /* 0x214 */
- u32 initrd_start; /* 0x218 */
- u32 initrd_size; /* 0x21c */
- u8 reserved12_5[8]; /* 0x220 */
- u32 cmd_line_ptr; /* 0x228 */
- u8 reserved13[164]; /* 0x22c */
- struct e820entry e820_map[E820MAX]; /* 0x2d0 */
- u8 reserved16[688]; /* 0x550 */
+ u8 loader_flags; /* 0x211 */
+ u8 reserved12[2]; /* 0x212 */
+ u32 kernel_start; /* 0x214 */
+ u32 initrd_start; /* 0x218 */
+ u32 initrd_size; /* 0x21c */
+ u8 reserved12_5[8]; /* 0x220 */
+ u32 cmd_line_ptr; /* 0x228 */
+ u8 reserved13[164]; /* 0x22c */
+ struct e820entry e820_map[E820MAX]; /* 0x2d0 */
+ u8 reserved16[688]; /* 0x550 */
#define COMMAND_LINE_SIZE 256
- /* Command line is copied here by 32-bit i386/kernel/head.S.
- * So I will follow the boot protocol, rather than putting it
- * directly here. --ts1 */
- u8 command_line[COMMAND_LINE_SIZE]; /* 0x800 */
- u8 reserved17[1792]; /* 0x900 - 0x1000 */
+ /* Command line is copied here by 32-bit i386/kernel/head.S.
+ * So I will follow the boot protocol, rather than putting it
+ * directly here. --ts1 */
+ u8 command_line[COMMAND_LINE_SIZE]; /* 0x800 */
+ u8 reserved17[1792]; /* 0x900 - 0x1000 */
};
-uint64_t forced_memsize;
+u64 forced_memsize;
/* Load the first part the file and check if it's Linux */
static u32 load_linux_header(struct linux_header *hdr)
{
- int load_high;
- u32 kern_addr;
+ int load_high;
+ u32 kern_addr;
- if (file_read(hdr, sizeof *hdr) != sizeof *hdr) {
- printf("Can't read Linux header\n");
- return 0;
- }
- if (hdr->boot_sector_magic != 0xaa55) {
- printf("Not a Linux kernel image\n");
- return 0;
- }
+ if (file_read(hdr, sizeof *hdr) != sizeof *hdr) {
+ printf("Can't read Linux header\n");
+ return 0;
+ }
+
+ if (hdr->boot_sector_magic != 0xaa55) {
+ printf("Not a Linux kernel image\n");
+ return 0;
+ }
+
+ /* Linux is found. Print some information */
+ if (memcmp(hdr->header_magic, "HdrS", 4) != 0) {
+ /* This may be floppy disk image or something.
+ * Perform a simple (incomplete) sanity check. */
+ if (hdr->setup_sects >= 16 || file_size() - (hdr->setup_sects << 9) >= 512 << 10) {
+ printf("This looks like a bootdisk image but not like Linux...\n");
+ return 0;
+ }
+
+ printf("Possible very old Linux");
+ /* This kernel does not even have a protocol version.
+ * Force the value. */
+ hdr->protocol_version = 0; /* pre-2.00 */
+ } else {
+ printf("Found Linux");
+ }
+
+ if (hdr->protocol_version >= 0x200 && hdr->kver_addr) {
+ char kver[256];
+ file_seek(hdr->kver_addr + 0x200);
+ if (file_read(kver, sizeof kver) != 0) {
+ kver[255] = 0;
+ printf(" version %s", kver);
+ }
+ }
+ debug(" (protocol %#x)", hdr->protocol_version);
+
+ load_high = 0;
+ if (hdr->protocol_version >= 0x200) {
+ debug(" (loadflags %#x)", hdr->loadflags);
+ load_high = hdr->loadflags & 1;
+ }
+ if (load_high) {
+ printf(" bzImage");
+ kern_addr = 0x100000;
+ } else {
+ printf(" zImage or Image");
+ kern_addr = 0x1000;
+ }
- /* Linux is found. Print some information */
- if (memcmp(hdr->header_magic, "HdrS", 4) != 0) {
- /* This may be floppy disk image or something.
- * Perform a simple (incomplete) sanity check. */
- if (hdr->setup_sects >= 16
- || file_size() - (hdr->setup_sects<<9) >= 512<<10) {
- printf("This looks like a bootdisk image but not like Linux...\n");
- return 0;
- }
-
- printf("Possible very old Linux");
- /* This kernel does not even have a protocol version.
- * Force the value. */
- hdr->protocol_version = 0; /* pre-2.00 */
- } else
- printf("Found Linux");
- if (hdr->protocol_version >= 0x200 && hdr->kver_addr) {
- char kver[256];
- file_seek(hdr->kver_addr + 0x200);
- if (file_read(kver, sizeof kver) != 0) {
- kver[255] = 0;
- printf(" version %s", kver);
- }
- }
- debug(" (protocol %#x)", hdr->protocol_version);
- load_high = 0;
- if (hdr->protocol_version >= 0x200) {
- debug(" (loadflags %#x)", hdr->loadflags);
- load_high = hdr->loadflags & 1;
- }
- if (load_high) {
- printf(" bzImage");
- kern_addr = 0x100000;
- } else {
- printf(" zImage or Image");
- kern_addr = 0x1000;
- }
- printf(".\n");
+ printf(".\n");
- return kern_addr;
+ return kern_addr;
}
/* Set up parameters for 32-bit kernel */
static void
init_linux_params(struct linux_params *params, struct linux_header *hdr)
{
- debug("Setting up paramters at %#lx\n", virt_to_phys(params));
- memset(params, 0, sizeof *params);
+ debug("Setting up paramters at %#lx\n", virt_to_phys(params));
+ memset(params, 0, sizeof *params);
- /* Copy some useful values from header */
- params->mount_root_rdonly = hdr->root_flags;
- params->orig_root_dev = hdr->root_dev;
-
- /* Video parameters.
- * This assumes we have VGA in standard 80x25 text mode,
- * just like our vga.c does.
- * Cursor position is filled later to allow some more printf's. */
- params->orig_video_mode = 3;
- params->orig_video_cols = 80;
- params->orig_video_lines = 25;
- params->orig_video_isVGA = 1;
- params->orig_video_points = 16;
+ /* Copy some useful values from header */
+ params->mount_root_rdonly = hdr->root_flags;
+ params->orig_root_dev = hdr->root_dev;
+
+ /* Video parameters.
+ * This assumes we have VGA in standard 80x25 text mode,
+ * just like our vga.c does.
+ * Cursor position is filled later to allow some more printf's.
+ */
+ params->orig_video_mode = 3;
+ params->orig_video_cols = 80;
+ params->orig_video_lines = 25;
+ params->orig_video_isVGA = 1;
+ params->orig_video_points = 16;
- params->loader_type = 0xff; /* Unregistered Linux loader */
+ params->loader_type = 0xff; /* Unregistered Linux loader */
}
/* Memory map */
-static void
-set_memory_size(struct linux_params *params)
+static void set_memory_size(struct linux_params *params)
{
- int i;
- uint64_t end;
- u32 ramtop = 0;
- struct e820entry *linux_map;
- struct sysinfo_t *info = &lib_sysinfo;
- struct memrange *filo_map;
-
- linux_map = params->e820_map;
- filo_map = info->memrange;
- for (i = 0; i < info->n_memranges; i++, linux_map++, filo_map++) {
- if (i < E820MAX) {
- /* Convert to BIOS e820 style */
- linux_map->addr = filo_map->base;
- linux_map->size = filo_map->size;
- linux_map->type = filo_map->type;
- debug("%016Lx - %016Lx (%d)\n", linux_map->addr,
- linux_map->addr + linux_map->size, linux_map->type);
- params->e820_map_nr = i+1;
- }
-
- /* Find out top of RAM. XXX This ignores hole above 1MB */
- end = filo_map->base + filo_map->size;
- if (end < (1ULL << 32)) { /* don't count memory above 4GB */
- if (end > ramtop)
- ramtop = (u32) end;
- }
- }
-
- debug("ramtop=%#x\n", ramtop);
- /* Size of memory above 1MB in KB */
- params->alt_mem_k = (ramtop - (1<<20)) >> 10;
- /* old style, 64MB max */
- if (ramtop >= (64<<20))
- params->ext_mem_k = (63<<10);
- else
- params->ext_mem_k = params->alt_mem_k;
- debug("ext_mem_k=%d, alt_mem_k=%d\n", params->ext_mem_k, params->alt_mem_k);
+ int i;
+ uint64_t end;
+ u32 ramtop = 0;
+ struct e820entry *linux_map;
+ struct sysinfo_t *info = &lib_sysinfo;
+ struct memrange *filo_map;
+
+ linux_map = params->e820_map;
+ filo_map = info->memrange;
+ for (i = 0; i < info->n_memranges; i++, linux_map++, filo_map++) {
+ if (i < E820MAX) {
+ /* Convert to BIOS e820 style */
+ linux_map->addr = filo_map->base;
+ linux_map->size = filo_map->size;
+ linux_map->type = filo_map->type;
+ debug("%016Lx - %016Lx (%d)\n", linux_map->addr,
+ linux_map->addr + linux_map->size,
+ linux_map->type);
+ params->e820_map_nr = i + 1;
+ }
+
+ /* Find out top of RAM. XXX This ignores hole above 1MB */
+ end = filo_map->base + filo_map->size;
+ if (end < (1ULL << 32)) { /* don't count memory above 4GB */
+ if (end > ramtop)
+ ramtop = (u32) end;
+ }
+ }
+
+ debug("ramtop=%#x\n", ramtop);
+ /* Size of memory above 1MB in KB */
+ params->alt_mem_k = (ramtop - (1 << 20)) >> 10;
+ /* old style, 64MB max */
+ if (ramtop >= (64 << 20))
+ params->ext_mem_k = (63 << 10);
+ else
+ params->ext_mem_k = params->alt_mem_k;
+ debug("ext_mem_k=%d, alt_mem_k=%d\n", params->ext_mem_k,
+ params->alt_mem_k);
}
/* Video mode */
-static void
-set_video_mode(struct linux_params *params)
+static void set_video_mode(struct linux_params *params)
{
#if CONFIG_COREBOOT_VIDEO_CONSOLE
/* Are we running on a framebuffer console? */
@@ -313,7 +317,8 @@
params->lfb_linelength = lib_sysinfo.framebuffer->bytes_per_line;
params->lfb_base = lib_sysinfo.framebuffer->physical_address;
// prolly not enough for the boot splash?!
- params->lfb_size = (params->lfb_linelength * params->lfb_height + 65535 ) >> 16;
+ params->lfb_size =
+ (params->lfb_linelength * params->lfb_height + 65535) >> 16;
params->red_size = lib_sysinfo.framebuffer->red_mask_size;
params->red_pos = lib_sysinfo.framebuffer->red_mask_pos;
params->green_size = lib_sysinfo.framebuffer->green_mask_size;
@@ -331,396 +336,415 @@
* we are responsible to process them.
* Parameters for kernel are copied to kern_cmdline. Returns name of initrd.
*/
-static char *parse_command_line(const char *orig_cmdline, char *kern_cmdline)
+static char *parse_command_line(const char *orig_cmdline,
+ char *kern_cmdline)
{
- const char *start, *sep, *end, *val;
- char name[64];
- int len;
- int k_len;
- int to_kern;
- char *initrd = 0;
- int toolong = 0;
-
- forced_memsize = 0;
+ const char *start, *sep, *end, *val;
+ char name[64];
+ int len;
+ int k_len;
+ int to_kern;
+ char *initrd = 0;
+ int toolong = 0;
+
+ forced_memsize = 0;
+
+ if (!orig_cmdline) {
+ *kern_cmdline = 0;
+ return 0;
+ }
- if (!orig_cmdline) {
- *kern_cmdline = 0;
- return 0;
- }
+ k_len = 0;
+ debug("original command line: \"%s\"\n", orig_cmdline);
+ debug("kernel command line at %#lx\n", virt_to_phys(kern_cmdline));
- k_len = 0;
- debug("original command line: \"%s\"\n", orig_cmdline);
- debug("kernel command line at %#lx\n", virt_to_phys(kern_cmdline));
-
- start = orig_cmdline;
- while (*start == ' ')
- start++;
- while (*start) {
- end = strchr(start, ' ');
- if (!end)
- end = start + strlen(start);
- sep = strchr(start, '=');
- if (!sep || sep > end)
- sep = end;
- len = sep - start;
- if (len >= sizeof(name))
- len = sizeof(name) - 1;
- memcpy(name, start, len);
- name[len] = 0;
-
- if (*sep == '=') {
- val = sep + 1;
- len = end - val;
- } else {
- val = 0;
- len = 0;
- }
+ start = orig_cmdline;
+ while (*start == ' ')
+ start++;
+ while (*start) {
+ end = strchr(start, ' ');
+ if (!end)
+ end = start + strlen(start);
+ sep = strchr(start, '=');
+ if (!sep || sep > end)
+ sep = end;
+ len = sep - start;
+ if (len >= sizeof(name))
+ len = sizeof(name) - 1;
+ memcpy(name, start, len);
+ name[len] = 0;
+
+ if (*sep == '=') {
+ val = sep + 1;
+ len = end - val;
+ } else {
+ val = 0;
+ len = 0;
+ }
- /* Only initrd= and mem= are handled here. vga= is not,
- * which I believe is a paramter to the realmode part of Linux,
- * which we don't execute. */
- if (strcmp(name, "initrd") == 0) {
- if (!val) {
- printf("Missing filename to initrd parameter\n");
- } else {
- initrd = malloc(len + 1);
- memcpy(initrd, val, len);
- initrd[len] = 0;
- debug("initrd=%s\n", initrd);
- }
- /* Don't pass this to kernel */
- to_kern = 0;
- } else if (strcmp(name, "mem") == 0) {
- if (!val) {
- printf("Missing value for mem parameter\n");
- } else {
- forced_memsize = strtoull_with_suffix(val, (char**)&val, 0);
- if (forced_memsize == 0)
- printf("Invalid mem option, ignored\n");
- if (val != end) {
- printf("Garbage after mem=<size>, ignored\n");
- forced_memsize = 0;
+ /* Only initrd= and mem= are handled here. vga= is not,
+ * which I believe is a paramter to the realmode part of Linux,
+ * which we don't execute.
+ */
+ if (strcmp(name, "initrd") == 0) {
+ if (!val) {
+ printf
+ ("Missing filename to initrd parameter\n");
+ } else {
+ initrd = malloc(len + 1);
+ memcpy(initrd, val, len);
+ initrd[len] = 0;
+ debug("initrd=%s\n", initrd);
+ }
+ /* Don't pass this to kernel */
+ to_kern = 0;
+ } else if (strcmp(name, "mem") == 0) {
+ if (!val) {
+ printf
+ ("Missing value for mem parameter\n");
+ } else {
+ forced_memsize =
+ strtoull_with_suffix(val,
+ (char **) &val,
+ 0);
+ if (forced_memsize == 0)
+ printf
+ ("Invalid mem option, ignored\n");
+ if (val != end) {
+ printf
+ ("Garbage after mem=<size>, ignored\n");
+ forced_memsize = 0;
+ }
+ debug("mem=%Lu\n", forced_memsize);
+ }
+ /* mem= is for both loader and kernel */
+ to_kern = 1;
+ } else {
+ to_kern = 1;
}
- debug("mem=%Lu\n", forced_memsize);
- }
- /* mem= is for both loader and kernel */
- to_kern = 1;
- } else
- to_kern = 1;
-
- if (to_kern) {
- /* Copy to kernel command line buffer */
- if (k_len != 0)
- kern_cmdline[k_len++] = ' '; /* put separator */
- len = end - start;
- if (k_len + len >= COMMAND_LINE_SIZE) {
- len = COMMAND_LINE_SIZE - k_len - 1;
- if (!toolong) {
- printf("Kernel command line is too long; truncated to "
- "%d bytes\n", COMMAND_LINE_SIZE-1);
- toolong = 1;
+
+ if (to_kern) {
+ /* Copy to kernel command line buffer */
+ if (k_len != 0)
+ kern_cmdline[k_len++] = ' '; /* put separator */
+ len = end - start;
+ if (k_len + len >= COMMAND_LINE_SIZE) {
+ len = COMMAND_LINE_SIZE - k_len - 1;
+ if (!toolong) {
+ printf
+ ("Kernel command line is too long; truncated to "
+ "%d bytes\n",
+ COMMAND_LINE_SIZE - 1);
+ toolong = 1;
+ }
+ }
+ memcpy(kern_cmdline + k_len, start, len);
+ k_len += len;
}
- }
- memcpy(kern_cmdline + k_len, start, len);
- k_len += len;
- }
- start = end;
- while (*start == ' ')
- start++;
- }
- kern_cmdline[k_len] = 0;
- debug("kernel command line (%d bytes): \"%s\"\n", k_len, kern_cmdline);
+ start = end;
+ while (*start == ' ')
+ start++;
+ }
+ kern_cmdline[k_len] = 0;
+ debug("kernel command line (%d bytes): \"%s\"\n", k_len,
+ kern_cmdline);
- return initrd;
+ return initrd;
}
/* Set command line location */
static void set_command_line_loc(struct linux_params *params,
- struct linux_header *hdr)
+ struct linux_header *hdr)
{
- if (hdr->protocol_version >= 0x202) {
- /* new style */
- params->cmd_line_ptr = COMMAND_LINE_LOC;
- } else {
- /* old style */
- params->cl_magic = CL_MAGIC_VALUE;
- params->cl_offset = COMMAND_LINE_LOC - LINUX_PARAM_LOC;
- }
+ if (hdr->protocol_version >= 0x202) {
+ /* new style */
+ params->cmd_line_ptr = COMMAND_LINE_LOC;
+ } else {
+ /* old style */
+ params->cl_magic = CL_MAGIC_VALUE;
+ params->cl_offset = COMMAND_LINE_LOC - LINUX_PARAM_LOC;
+ }
}
/* Load 32-bit part of kernel */
static int load_linux_kernel(struct linux_header *hdr, u32 kern_addr)
{
- u32 kern_offset, kern_size;
+ u32 kern_offset, kern_size;
- if (hdr->setup_sects == 0)
- hdr->setup_sects = 4;
- kern_offset = (hdr->setup_sects + 1) * 512;
- file_seek(kern_offset);
- kern_size = file_size() - kern_offset;
- debug("offset=%#x addr=%#x size=%#x\n", kern_offset, kern_addr, kern_size);
-
- if (using_devsize) {
- printf("Attempt to load up to end of device as kernel; "
- "specify the image size\n");
- return 0;
- }
+ if (hdr->setup_sects == 0)
+ hdr->setup_sects = 4;
+ kern_offset = (hdr->setup_sects + 1) * 512;
+ file_seek(kern_offset);
+ kern_size = file_size() - kern_offset;
+ debug("offset=%#x addr=%#x size=%#x\n", kern_offset, kern_addr,
+ kern_size);
+
+ if (using_devsize) {
+ printf("Attempt to load up to end of device as kernel; "
+ "specify the image size\n");
+ return 0;
+ }
- printf("Loading kernel... ");
- if (file_read(phys_to_virt(kern_addr), kern_size) != kern_size) {
- printf("Can't read kernel\n");
- return 0;
- }
- printf("ok\n");
+ printf("Loading kernel... ");
+ if (file_read(phys_to_virt(kern_addr), kern_size) != kern_size) {
+ printf("Can't read kernel\n");
+ return 0;
+ }
+ printf("ok\n");
- return kern_size;
+ return kern_size;
}
-static int load_initrd(struct linux_header *hdr,
- u32 kern_end, struct linux_params *params, const char *initrd_file)
+static int load_initrd(struct linux_header *hdr,
+ u32 kern_end, struct linux_params *params,
+ const char *initrd_file)
{
- u32 max;
- u32 start, end, size;
- uint64_t forced;
- extern char _start[];
+ u32 max;
+ u32 start, end, size;
+ uint64_t forced;
+ extern char _start[];
#if 0
- extern char _end[];
+ extern char _end[];
#endif
- if (!file_open(initrd_file)) {
- printf("Can't open initrd: %s\n", initrd_file);
- return -1;
- }
- if (using_devsize) {
- printf("Attempt to load up to end of device as initrd; "
- "specify the image size\n");
- return -1;
- }
- size = file_size();
-
-
- /* Find out the kernel's restriction on how high the initrd can be
- * placed */
- if (hdr->protocol_version >= 0x203)
- max = hdr->initrd_addr_max;
- else
- max = 0x38000000; /* Hardcoded value for older kernels */
-
- /* FILO itself is at the top of RAM. (relocated)
- * So, try putting initrd just below us. */
- end = virt_to_phys(_start);
- if (end > max)
- end = max;
-
- /* If "mem=" option is given, we have to put the initrd within
- * the specified range. */
- if (forced_memsize) {
- forced = forced_memsize;
- if (forced > max)
- forced = max;
- /* If the "mem=" is lower, it's easy */
- if (forced <= end)
- end = forced;
-#if 0
- else {
- /* Otherwise, see if we can put it above us.
- *
- * This would be a good idea if we could easily find out
- * where the memory hole lives.
- *
- * There's nothing wrong with the initrd living below
- * FILO. (stepan)
- *
- * The problems is even a 64bit kernel will live in
- * 32bit address space, so if you have a lot of memory
- * and specify mem=xG with x>4, the maximum allowed
- * initrd address (2.6.x sets this to 0xffffffff) will
- * be used for the high limit. (offset 22c in vmlinuz)
- *
- * you might want to enable this if you limit memory with
- * mem=yG with y<4.
- */
- if (virt_to_phys(_end) + size <= forced)
- end = forced; /* Ok */
+ if (!file_open(initrd_file)) {
+ printf("Can't open initrd: %s\n", initrd_file);
+ return -1;
+ }
+ if (using_devsize) {
+ printf("Attempt to load up to end of device as initrd; "
+ "specify the image size\n");
+ return -1;
}
+ size = file_size();
+
+
+ /* Find out the kernel's restriction on how high the initrd can be
+ * placed */
+ if (hdr->protocol_version >= 0x203)
+ max = hdr->initrd_addr_max;
+ else
+ max = 0x38000000; /* Hardcoded value for older kernels */
+
+ /* FILO itself is at the top of RAM. (relocated)
+ * So, try putting initrd just below us. */
+ end = virt_to_phys(_start);
+ if (end > max)
+ end = max;
+
+ /* If "mem=" option is given, we have to put the initrd within
+ * the specified range. */
+ if (forced_memsize) {
+ forced = forced_memsize;
+ if (forced > max)
+ forced = max;
+ /* If the "mem=" is lower, it's easy */
+ if (forced <= end)
+ end = forced;
+#if 0
+ else {
+ /* Otherwise, see if we can put it above us.
+ *
+ * This would be a good idea if we could easily find
+ * out where the memory hole lives.
+ *
+ * There's nothing wrong with the initrd living below
+ * FILO. (stepan)
+ *
+ * The problems is even a 64bit kernel will live in
+ * 32bit address space, so if you have a lot of
+ * memory and specify mem=xG with x>4, the maximum
+ * allowed initrd address (2.6.x sets this to
+ * 0xffffffff) will be used for the high limit.
+ * (offset 22c in vmlinuz)
+ *
+ * you might want to enable this if you limit memory
+ * with mem=yG with y<4.
+ */
+ if (virt_to_phys(_end) + size <= forced)
+ end = forced; /* Ok */
+ }
#endif
- }
+ }
+
+ start = end - size;
+ start &= ~0xfff; /* page align */
+ end = start + size;
+
+ debug("start=%#x end=%#x\n", start, end);
+
+ if (start < kern_end) {
+ printf("Initrd is too big to fit in memory\n");
+ return -1;
+ }
- start = end - size;
- start &= ~0xfff; /* page align */
- end = start + size;
-
- debug("start=%#x end=%#x\n", start, end);
-
- if (start < kern_end) {
- printf("Initrd is too big to fit in memory\n");
- return -1;
- }
-
- printf("Loading initrd... ");
- if (file_read(phys_to_virt(start), size) != size) {
- printf("Can't read initrd\n");
- return -1;
- }
- printf("ok\n");
+ printf("Loading initrd... ");
+ if (file_read(phys_to_virt(start), size) != size) {
+ printf("Can't read initrd\n");
+ return -1;
+ }
+ printf("ok\n");
- params->initrd_start = start;
- params->initrd_size = size;
+ params->initrd_start = start;
+ params->initrd_size = size;
- return 0;
+ return 0;
}
static void hardware_setup(void)
{
- /* Disable nmi */
- outb(0x80, 0x70);
+ /* Disable nmi */
+ outb(0x80, 0x70);
- /* Make sure any coprocessor is properly reset.. */
- outb(0, 0xf0);
- outb(0, 0xf1);
-
- /* we're getting screwed again and again by this problem of the 8259.
- * so we're going to leave this lying around for inclusion into
- * crt0.S on an as-needed basis.
- *
- * well, that went ok, I hope. Now we have to reprogram the interrupts :-(
- * we put them right after the intel-reserved hardware interrupts, at
- * int 0x20-0x2F. There they won't mess up anything. Sadly IBM really
- * messed this up with the original PC, and they haven't been able to
- * rectify it afterwards. Thus the bios puts interrupts at 0x08-0x0f,
- * which is used for the internal hardware interrupts as well. We just
- * have to reprogram the 8259's, and it isn't fun.
- */
-
- outb(0x11, 0x20); /* initialization sequence to 8259A-1 */
- outb(0x11, 0xA0); /* and to 8259A-2 */
-
- outb(0x20, 0x21); /* start of hardware int's (0x20) */
- outb(0x28, 0xA1); /* start of hardware int's 2 (0x28) */
+ /* Make sure any coprocessor is properly reset.. */
+ outb(0, 0xf0);
+ outb(0, 0xf1);
+
+ /* we're getting screwed again and again by this problem of the 8259.
+ * so we're going to leave this lying around for inclusion into crt0.S
+ * on an as-needed basis.
+ *
+ * well, that went ok, I hope. Now we have to reprogram the interrupts
+ * :-(
+ * we put them right after the intel-reserved hardware interrupts, at
+ * int 0x20-0x2F. There they won't mess up anything. Sadly IBM really
+ * messed this up with the original PC, and they haven't been able to
+ * rectify it afterwards. Thus the bios puts interrupts at 0x08-0x0f,
+ * which is used for the internal hardware interrupts as well. We just
+ * have to reprogram the 8259's, and it isn't fun.
+ */
+
+ outb(0x11, 0x20); /* initialization sequence to 8259A-1 */
+ outb(0x11, 0xA0); /* and to 8259A-2 */
+
+ outb(0x20, 0x21); /* start of hardware int's (0x20) */
+ outb(0x28, 0xA1); /* start of hardware int's 2 (0x28) */
- outb(0x04, 0x21); /* 8259-1 is master */
- outb(0x02, 0xA1); /* 8259-2 is slave */
+ outb(0x04, 0x21); /* 8259-1 is master */
+ outb(0x02, 0xA1); /* 8259-2 is slave */
- outb(0x01, 0x21); /* 8086 mode for both */
- outb(0x01, 0xA1);
+ outb(0x01, 0x21); /* 8086 mode for both */
+ outb(0x01, 0xA1);
- outb(0xFF, 0xA1); /* mask off all interrupts for now */
- outb(0xFB, 0x21); /* mask all irq's but irq2 which is cascaded */
+ outb(0xFF, 0xA1); /* mask off all interrupts for now */
+ outb(0xFB, 0x21); /* mask all irq's but irq2 which is cascaded */
}
/* Start Linux */
static int start_linux(u32 kern_addr, struct linux_params *params)
{
- struct segment_desc *linux_gdt;
- struct context *ctx;
+ struct segment_desc *linux_gdt;
+ struct context *ctx;
#ifdef CONFIG_VGA_VIDEO_CONSOLE
- unsigned int cursor_x, cursor_y, cursor_en;
+ unsigned int cursor_x, cursor_y, cursor_en;
#endif
#ifdef CONFIG_PCMCIA_CF
- unsigned char *cf_bar;
- int i;
+ unsigned char *cf_bar;
+ int i;
#endif
- ctx = init_context(phys_to_virt(STACK_LOC), 4096, 0);
+ ctx = init_context(phys_to_virt(STACK_LOC), 4096, 0);
- /* Linux expects GDT being in low memory */
- linux_gdt = phys_to_virt(GDT_LOC);
- memset(linux_gdt, 0, 13*sizeof(struct segment_desc));
- /* Normal kernel code/data segments */
- linux_gdt[2] = gdt[FLAT_CODE];
- linux_gdt[3] = gdt[FLAT_DATA];
- /* 2.6 kernel uses 12 and 13, but head.S uses backward-compatible
- * segments (2 and 3), so it SHOULD not be a problem.
- * However, some distro kernels (eg. RH9) with backported threading
- * patch use 12 and 13 also when booting... */
- linux_gdt[12] = gdt[FLAT_CODE];
- linux_gdt[13] = gdt[FLAT_DATA];
- ctx->gdt_base = GDT_LOC;
- ctx->gdt_limit = 14*8-1;
- ctx->cs = 0x10;
- ctx->ds = 0x18;
- ctx->es = 0x18;
- ctx->fs = 0x18;
- ctx->gs = 0x18;
- ctx->ss = 0x18;
+ /* Linux expects GDT being in low memory */
+ linux_gdt = phys_to_virt(GDT_LOC);
+ memset(linux_gdt, 0, 13 * sizeof(struct segment_desc));
+ /* Normal kernel code/data segments */
+ linux_gdt[2] = gdt[FLAT_CODE];
+ linux_gdt[3] = gdt[FLAT_DATA];
+ /* 2.6 kernel uses 12 and 13, but head.S uses backward-compatible
+ * segments (2 and 3), so it SHOULD not be a problem.
+ * However, some distro kernels (eg. RH9) with backported threading
+ * patch use 12 and 13 also when booting... */
+ linux_gdt[12] = gdt[FLAT_CODE];
+ linux_gdt[13] = gdt[FLAT_DATA];
+ ctx->gdt_base = GDT_LOC;
+ ctx->gdt_limit = 14 * 8 - 1;
+ ctx->cs = 0x10;
+ ctx->ds = 0x18;
+ ctx->es = 0x18;
+ ctx->fs = 0x18;
+ ctx->gs = 0x18;
+ ctx->ss = 0x18;
- /* Parameter location */
- ctx->esi = virt_to_phys(params);
+ /* Parameter location */
+ ctx->esi = virt_to_phys(params);
- /* Entry point */
- ctx->eip = kern_addr;
+ /* Entry point */
+ ctx->eip = kern_addr;
- debug("eip=%#x\n", kern_addr);
- printf("Jumping to entry point...\n");
+ debug("EIP=%#x\n", kern_addr);
+ printf("Jumping to entry point...\n");
#ifdef CONFIG_VGA_VIDEO_CONSOLE
- /* Update VGA cursor position.
- * This must be here because the printf changes the value! */
- video_console_get_cursor(&cursor_x, &cursor_y, &cursor_en);
- params->orig_x = cursor_x;
- params->orig_y = cursor_y;
+ /* Update VGA cursor position.
+ * This must be here because the printf changes the value! */
+ video_console_get_cursor(&cursor_x, &cursor_y, &cursor_en);
+ params->orig_x = cursor_x;
+ params->orig_y = cursor_y;
#endif
+
#ifdef CONFIG_PCMCIA_CF
- cf_bar = phys_to_virt(pci_read_config32(PCI_DEV(0, 0xa, 1), 0x10));
- for( i = 0x836 ; i < 0x840 ; i++){
- cf_bar[i] = 0;
- }
+ cf_bar = phys_to_virt(pci_read_config32(PCI_DEV(0, 0xa, 1), 0x10));
+ for (i = 0x836; i < 0x840; i++) {
+ cf_bar[i] = 0;
+ }
#endif
- /* Go... */
- ctx = switch_to(ctx);
+ /* Go... */
+ ctx = switch_to(ctx);
- /* It's impossible but... */
- printf("Returned with eax=%#x\n", ctx->eax);
+ /* It's impossible but... */
+ printf("Returned with EAX=%#x\n", ctx->eax);
- return ctx->eax;
+ return ctx->eax;
}
int linux_load(const char *file, const char *cmdline)
{
- struct linux_header hdr;
- struct linux_params *params;
- u32 kern_addr, kern_size;
- char *initrd_file = 0;
-
- if (!file_open(file))
- return -1;
-
- kern_addr = load_linux_header(&hdr);
- if (kern_addr == 0) {
- file_close();
- return LOADER_NOT_SUPPORT;
- }
-
- params = phys_to_virt(LINUX_PARAM_LOC);
- init_linux_params(params, &hdr);
- set_memory_size(params);
- set_video_mode(params);
- initrd_file = parse_command_line(cmdline, phys_to_virt(COMMAND_LINE_LOC));
- set_command_line_loc(params, &hdr);
-
- kern_size = load_linux_kernel(&hdr, kern_addr);
- if (kern_size == 0) {
- if (initrd_file)
- free(initrd_file);
- file_close();
- return -1;
- }
+ struct linux_header hdr;
+ struct linux_params *params;
+ u32 kern_addr, kern_size;
+ char *initrd_file = 0;
+
+ if (!file_open(file))
+ return -1;
+
+ kern_addr = load_linux_header(&hdr);
+ if (kern_addr == 0) {
+ file_close();
+ return LOADER_NOT_SUPPORT;
+ }
+
+ params = phys_to_virt(LINUX_PARAM_LOC);
+ init_linux_params(params, &hdr);
+ set_memory_size(params);
+ set_video_mode(params);
+ initrd_file =
+ parse_command_line(cmdline, phys_to_virt(COMMAND_LINE_LOC));
+ set_command_line_loc(params, &hdr);
+
+ kern_size = load_linux_kernel(&hdr, kern_addr);
+ if (kern_size == 0) {
+ if (initrd_file)
+ free(initrd_file);
+ file_close();
+ return -1;
+ }
+
+ if (initrd_file) {
+ if (load_initrd(&hdr, kern_addr + kern_size,
+ params, initrd_file) != 0) {
+ free(initrd_file);
+ file_close();
+ return -1;
+ }
+ free(initrd_file);
+ }
- if (initrd_file) {
- if (load_initrd(&hdr, kern_addr+kern_size, params, initrd_file)
- != 0) {
- free(initrd_file);
- file_close();
- return -1;
- }
- free(initrd_file);
- }
-
- file_close();
+ file_close();
- hardware_setup();
+ hardware_setup();
- start_linux(kern_addr, params);
- return 0;
+ start_linux(kern_addr, params);
+ return 0;
}
Modified: trunk/filo/i386/segment.c
==============================================================================
--- trunk/filo/i386/segment.c Wed Apr 21 14:55:47 2010 (r130)
+++ trunk/filo/i386/segment.c Wed May 19 18:31:36 2010 (r131)
@@ -31,9 +31,9 @@
/* i386 lgdt argument */
struct gdtarg {
- unsigned short limit;
- unsigned int base;
-} __attribute__((packed));
+ unsigned short limit;
+ unsigned int base;
+} __attribute__ ((packed));
/* How far the virtual address (used in C) is different from physical
* address. Since we start in flat mode, the initial value is zero. */
@@ -41,95 +41,95 @@
/* GDT, the global descriptor table */
struct segment_desc gdt[NUM_SEG] = {
- /* 0x00: null segment */
- {0, 0, 0, 0, 0, 0},
- /* 0x08: flat code segment */
- {0xffff, 0, 0, 0x9f, 0xcf, 0},
- /* 0x10: flat data segment */
- {0xffff, 0, 0, 0x93, 0xcf, 0},
- /* 0x18: code segment for relocated execution */
- {0xffff, 0, 0, 0x9f, 0xcf, 0},
- /* 0x20: data segment for relocated execution */
- {0xffff, 0, 0, 0x93, 0xcf, 0},
+ /* 0x00: null segment */
+ {0, 0, 0, 0, 0, 0},
+ /* 0x08: flat code segment */
+ {0xffff, 0, 0, 0x9f, 0xcf, 0},
+ /* 0x10: flat data segment */
+ {0xffff, 0, 0, 0x93, 0xcf, 0},
+ /* 0x18: code segment for relocated execution */
+ {0xffff, 0, 0, 0x9f, 0xcf, 0},
+ /* 0x20: data segment for relocated execution */
+ {0xffff, 0, 0, 0x93, 0xcf, 0},
};
extern char _start[], _end[];
void relocate(void)
{
- int i;
- unsigned long prog_addr;
- unsigned long prog_size;
- unsigned long addr, new_base;
- unsigned long long segsize;
- unsigned long new_offset;
- unsigned d0, d1, d2;
- struct gdtarg gdtarg;
- struct sysinfo_t *info = &lib_sysinfo;
+ int i;
+ unsigned long prog_addr;
+ unsigned long prog_size;
+ unsigned long addr, new_base;
+ unsigned long long segsize;
+ unsigned long new_offset;
+ unsigned d0, d1, d2;
+ struct gdtarg gdtarg;
+ struct sysinfo_t *info = &lib_sysinfo;
#define ALIGNMENT 0x1000
- prog_addr = virt_to_phys(&_start);
- prog_size = virt_to_phys(&_end) - virt_to_phys(&_start);
- debug("Current location: %#lx-%#lx\n", prog_addr, prog_addr+prog_size-1);
-
- new_base = 0;
- for (i = 0; i < info->n_memranges; i++) {
- if (info->memrange[i].type != CB_MEM_RAM)
- continue;
- if (info->memrange[i].base >= 1ULL<<32)
- continue;
- segsize = info->memrange[i].size;
- if (info->memrange[i].base + segsize > 1ULL<<32)
- segsize = (1ULL<<32) - info->memrange[i].base;
- if (segsize < prog_size+ALIGNMENT)
- continue;
- addr = info->memrange[i].base + segsize - prog_size;
- addr &= ~(ALIGNMENT-1);
- if (addr >= prog_addr && addr < prog_addr + prog_size)
- continue;
- if (prog_addr >= addr && prog_addr < addr + prog_size)
- continue;
- if (addr > new_base)
- new_base = addr;
- }
- if (new_base == 0) {
- printf("Can't find address to relocate\n");
- return;
- }
-
- debug("Relocating to %#lx-%#lx... ",
- new_base, new_base + prog_size - 1);
-
- /* New virtual address offset */
- new_offset = new_base - (unsigned long) &_start;
-
- /* Tweak the GDT */
- gdt[RELOC_CODE].base_0 = (unsigned short) new_offset;
- gdt[RELOC_CODE].base_16 = (unsigned char) (new_offset>>16);
- gdt[RELOC_CODE].base_24 = (unsigned char) (new_offset>>24);
- gdt[RELOC_DATA].base_0 = (unsigned short) new_offset;
- gdt[RELOC_DATA].base_16 = (unsigned char) (new_offset>>16);
- gdt[RELOC_DATA].base_24 = (unsigned char) (new_offset>>24);
-
- /* Load new GDT and reload segments */
- gdtarg.base = new_offset + (unsigned long) gdt;
- gdtarg.limit = GDT_LIMIT;
- __asm__ __volatile__ (
- "rep; movsb\n\t" /* copy everything */
- "lgdt %3\n\t"
- "ljmp %4, $1f\n1:\t"
- "movw %5, %%ds\n\t"
- "movw %5, %%es\n\t"
- "movw %5, %%fs\n\t"
- "movw %5, %%gs\n\t"
- "movw %5, %%ss\n"
- : "=&S" (d0), "=&D" (d1), "=&c" (d2)
- : "m" (gdtarg), "n" (RELOC_CS), "q" ((unsigned short) RELOC_DS),
- "0" (&_start), "1" (new_base), "2" (prog_size));
+ prog_addr = virt_to_phys(&_start);
+ prog_size = virt_to_phys(&_end) - virt_to_phys(&_start);
+ debug("Current location: %#lx-%#lx\n", prog_addr,
+ prog_addr + prog_size - 1);
+
+ new_base = 0;
+ for (i = 0; i < info->n_memranges; i++) {
+ if (info->memrange[i].type != CB_MEM_RAM)
+ continue;
+ if (info->memrange[i].base >= 1ULL << 32)
+ continue;
+ segsize = info->memrange[i].size;
+ if (info->memrange[i].base + segsize > 1ULL << 32)
+ segsize = (1ULL << 32) - info->memrange[i].base;
+ if (segsize < prog_size + ALIGNMENT)
+ continue;
+ addr = info->memrange[i].base + segsize - prog_size;
+ addr &= ~(ALIGNMENT - 1);
+ if (addr >= prog_addr && addr < prog_addr + prog_size)
+ continue;
+ if (prog_addr >= addr && prog_addr < addr + prog_size)
+ continue;
+ if (addr > new_base)
+ new_base = addr;
+ }
+ if (new_base == 0) {
+ printf("Can't find address to relocate\n");
+ return;
+ }
+
+ debug("Relocating to %#lx-%#lx... ",
+ new_base, new_base + prog_size - 1);
+
+ /* New virtual address offset */
+ new_offset = new_base - (unsigned long) &_start;
+
+ /* Tweak the GDT */
+ gdt[RELOC_CODE].base_0 = (unsigned short) new_offset;
+ gdt[RELOC_CODE].base_16 = (unsigned char) (new_offset >> 16);
+ gdt[RELOC_CODE].base_24 = (unsigned char) (new_offset >> 24);
+ gdt[RELOC_DATA].base_0 = (unsigned short) new_offset;
+ gdt[RELOC_DATA].base_16 = (unsigned char) (new_offset >> 16);
+ gdt[RELOC_DATA].base_24 = (unsigned char) (new_offset >> 24);
+
+ /* Load new GDT and reload segments */
+ gdtarg.base = new_offset + (unsigned long) gdt;
+ gdtarg.limit = GDT_LIMIT;
+ __asm__ __volatile__("rep; movsb\n\t" /* copy everything */
+ "lgdt %3\n\t"
+ "ljmp %4, $1f\n1:\t"
+ "movw %5, %%ds\n\t"
+ "movw %5, %%es\n\t"
+ "movw %5, %%fs\n\t"
+ "movw %5, %%gs\n\t"
+ "movw %5, %%ss\n":"=&S"(d0), "=&D"(d1),
+ "=&c"(d2)
+ :"m"(gdtarg), "n"(RELOC_CS),
+ "q"((unsigned short) RELOC_DS), "0"(&_start),
+ "1"(new_base), "2"(prog_size));
- virt_offset = new_offset; // for FILO
- virtual_offset = new_offset; // for libpayload
+ virt_offset = new_offset; // for FILO
+ virtual_offset = new_offset; // for libpayload
- debug("ok\n");
+ debug("ok\n");
}
-
Modified: trunk/filo/i386/segment.h
==============================================================================
--- trunk/filo/i386/segment.h Wed Apr 21 14:55:47 2010 (r130)
+++ trunk/filo/i386/segment.h Wed May 19 18:31:36 2010 (r131)
@@ -18,12 +18,12 @@
/* Segment indexes. Must match the gdt definition in segment.c. */
enum {
- NULL_SEG,
- FLAT_CODE,
- FLAT_DATA,
- RELOC_CODE,
- RELOC_DATA,
- NUM_SEG,
+ NULL_SEG,
+ FLAT_CODE,
+ FLAT_DATA,
+ RELOC_CODE,
+ RELOC_DATA,
+ NUM_SEG,
};
/* Values for segment selector register */
@@ -34,12 +34,12 @@
/* i386 segment descriptor */
struct segment_desc {
- unsigned short limit_0;
- unsigned short base_0;
- unsigned char base_16;
- unsigned char types;
- unsigned char flags;
- unsigned char base_24;
+ unsigned short limit_0;
+ unsigned short base_0;
+ unsigned char base_16;
+ unsigned char types;
+ unsigned char flags;
+ unsigned char base_24;
};
extern struct segment_desc gdt[NUM_SEG];
Modified: trunk/filo/i386/sys_info.c
==============================================================================
--- trunk/filo/i386/sys_info.c Wed Apr 21 14:55:47 2010 (r130)
+++ trunk/filo/i386/sys_info.c Wed May 19 18:31:36 2010 (r131)
@@ -24,11 +24,11 @@
void collect_sys_info(struct sys_info *info)
{
- /* Pick up paramters given by bootloader to us */
- info->boot_type = boot_ctx->eax;
- info->boot_data = boot_ctx->ebx;
- info->boot_arg = boot_ctx->param[0];
- debug("boot eax = %#lx\n", info->boot_type);
- debug("boot ebx = %#lx\n", info->boot_data);
- debug("boot arg = %#lx\n", info->boot_arg);
+ /* Pick up paramters given by bootloader to us */
+ info->boot_type = boot_ctx->eax;
+ info->boot_data = boot_ctx->ebx;
+ info->boot_arg = boot_ctx->param[0];
+ debug("boot EAX = %#lx\n", info->boot_type);
+ debug("boot EBX = %#lx\n", info->boot_data);
+ debug("boot arg = %#lx\n", info->boot_arg);
}
More information about the coreboot
mailing list