summaryrefslogtreecommitdiffstats
path: root/reloc/reloc_linux.c
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2008-01-04 12:51:01 -0800
committerH. Peter Anvin <hpa@zytor.com>2008-01-04 12:51:01 -0800
commit0686e9cf48dc49ee7ffc9d6ee3256fc9cede65b4 (patch)
tree4e49f1503f0bac81a9b5d2cd17df6d57641fd323 /reloc/reloc_linux.c
parentb3e7732cf39938575a287cd55907216c318d940c (diff)
downloadwraplinux-0686e9cf48dc49ee7ffc9d6ee3256fc9cede65b4.tar.gz
wraplinux-0686e9cf48dc49ee7ffc9d6ee3256fc9cede65b4.tar.xz
wraplinux-0686e9cf48dc49ee7ffc9d6ee3256fc9cede65b4.zip
Cleaner memory map; avoid < 64K; handle older kernels
Clean up the memory map by making the startup info part of the reloc segment; this also allows it to be easily prepopulated. Avoid using < 64K by putting the reloc between the setup and cmdline, with proper guarding for overflow. Handle older kernel protocols, and zImage kernels.
Diffstat (limited to 'reloc/reloc_linux.c')
-rw-r--r--reloc/reloc_linux.c28
1 files changed, 17 insertions, 11 deletions
diff --git a/reloc/reloc_linux.c b/reloc/reloc_linux.c
index 5849c54..79655c1 100644
--- a/reloc/reloc_linux.c
+++ b/reloc/reloc_linux.c
@@ -158,30 +158,36 @@ static int place_initrd(void)
return probe_memory_88();
}
+extern char _end[];
+/* This structure is hacked by the installer */
+static const struct startup_info startup_info
+__attribute__((section(".startupinfo"))) =
+{
+ .reloc_size = (uint32_t)&_end,
+};
+
int main(void)
{
- extern struct startup_info _start[]; /* Cute hack, eh? */
- struct startup_info *info = _start - 1;
- struct setup_header *hdr = (void *)(info->setup_addr + 0x1f1);
+ struct setup_header *hdr = (void *)(startup_info.setup_addr + 0x1f1);
- if (info->rd_len) {
- initrd_len = info->rd_len;
- max_addr = info->rd_maxaddr;
+ if (startup_info.rd_len) {
+ initrd_len = startup_info.rd_len;
+ max_addr = startup_info.rd_maxaddr;
if (place_initrd())
return -1;
/* Move the initrd into place */
printf("Moving initrd: 0x%08x -> 0x%08x (0x%08x bytes)\n",
- info->rd_addr, initrd_addr, info->rd_len);
+ startup_info.rd_addr, initrd_addr, startup_info.rd_len);
- memmove((void *)initrd_addr, (void *)info->rd_addr,
- info->rd_len);
+ memmove((void *)initrd_addr, (void *)startup_info.rd_addr,
+ startup_info.rd_len);
hdr->ramdisk_image = initrd_addr;
}
- jump_to_kernel(info->setup_addr >> 4,
- info->cmdline_addr - info->setup_addr);
+ jump_to_kernel(startup_info.setup_addr >> 4,
+ startup_info.cmdline_addr - startup_info.setup_addr);
return -1; /* Shouldn't return... */
}