x86 32bit entry point support...
RFC PATCH 1/1 x86 32bit entry point support...
Currently the linux kernel has no supported 32bit entry point, and no supported way to skip the 16bit x86 BIOS calls. This patch is a first step in towards getting a supported and useful 32bit entry point.
This patch removes all assumptions about which values are passed in the general purpose registers from the assembly code, and moves the responsibility of handling the complexities into setup_arch.
Additionally it has become the responsibility of whoever loads the global descriptor table to also load all of the segment registers. As the code only needs unlimited 32bit descriptors, and not specific descriptor values this allows more flexibility in the code. And it allows the kernel and future bootloaders to get out of sync in which descriptors they use.
I had 2.4.18 handy when I developed this patch, so it is against 2.4.18. The next version will be against 2.5.latest.
The supported 32bit entry point will then be:
if (bzImage)
0x100000
else
if (zImage)
0x1000
else
if (elf)
Ehdr->e_entryvmlinux now correctly exports it's requirements for being loaded.
How parameters should be passed to the 32bit entry point is still a question. I check for the current style of parameters from setup.S
by testing for %ebp == 0x53726448 (HdrS). The kernel is still free
to change the layout of these parameters at any time.
In doing this I was able to remove a lot of conditional logic from arch/i386/kernel/head.S. Making it more readable.
Comments and ideas for improvements are wanted.
Eric
Makefile +1 -1
@@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 4 SUBLEVEL = 18 -EXTRAVERSION = +EXTRAVERSION = .32bit_entry KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
arch/i386/Makefile +1 -1
@@ -18,7 +18,7 @@ LD=$(CROSS_COMPILE)ld -m elf_i386 OBJCOPY=$(CROSS_COMPILE)objcopy -O binary -R .note -R .comment -S -LDFLAGS=-e stext +LDFLAGS= LINKFLAGS =-T $(TOPDIR)/arch/i386/vmlinux.lds $(LDFLAGS) CFLAGS += -pipe
arch/i386/boot/compressed/head.S +66 -26
134 lines not on this page · raw message
arch/i386/boot/compressed/misc.c +55 -28
142 lines not on this page · raw message
arch/i386/boot/setup.S +13 -0
@@ -54,6 +54,8 @@ #include <asm/boot.h> #include <asm/e820.h> #include <asm/page.h> + +#define BZMAGIC 0x53726448 /* Signature words to ensure LILO loaded us right */ #define SIG1 0xAA55
@@ -163,6 +165,7 @@ trampoline: call start_of_setup .space 1024 + . = 0x550 # Leave enough room for all parameters. # End of setup header ##################################################### start_of_setup:
@@ -800,6 +803,16 @@ movw %cs, %si subw $DELTA_INITSEG, %si shll $4, %esi # Convert to 32-bit pointer + movl $BZMAGIC, %ebp # Magic to indicate bzImage + +# Setup the data segments + movw $(__KERNEL_DS), %ax + movw %ax, %ds + movw %ax, %es + movw %ax, %fs + movw %ax, %gs + movw %ax, %ss + # NOTE: For high loaded big kernels we need a # jmpi 0x100000,__KERNEL_CS #
arch/i386/kernel/head.S +99 -102
265 lines not on this page · raw message
arch/i386/kernel/setup.c +102 -25
183 lines not on this page · raw message
arch/i386/kernel/trampoline.S +5 -9
@@ -12,10 +12,6 @@ * In fact we don't actually need a stack so we don't * set one up. * - * We jump into the boot/compressed/head.S code. So you'd - * better be running a compressed kernel image or you - * won't get very far. - * * On entry to trampoline_data, the processor is in real mode * with 16-bit addressing and 16-bit data. CS has some value * and IP is zero. Thus, data addresses need to be absolute
@@ -23,7 +19,7 @@ * * If you work on this file, check the object module with objdump * --full-contents --reloc to make sure there are no relocation - * entries except for the gdt one.. + * entries except for gdt & secondary_startup_32.. */ #include <linux/linkage.h>
@@ -42,7 +38,6 @@ mov %cs, %ax # Code and data in the same place mov %ax, %ds - mov $1, %bx # Flag an SMP trampoline cli # We should be safe anyway movl $0xA5A5A5A5, trampoline_data - r_base
@@ -56,8 +51,9 @@ lmsw %ax # into protected mode jmp flush_instr flush_instr: - ljmpl $__KERNEL_CS, $0x00100000 - # jump to startup_32 in arch/i386/kernel/head.S + # jump to secondary_startup_32 in arch/i386/kernel/head.S + ljmpl $__KERNEL_CS, $(SYMBOL_NAME(secondary_startup_32) - __PAGE_OFFSET) + idt_48: .word 0 # idt limit = 0
@@ -65,7 +61,7 @@ gdt_48: .word 0x0800 # gdt limit = 2048, 256 GDT entries - .long gdt_table-__PAGE_OFFSET # gdt base = gdt (first SMP CPU) + .long SYMBOL_NAME(gdt_table)-__PAGE_OFFSET # gdt base = gdt (first SMP CPU) .globl SYMBOL_NAME(trampoline_end) SYMBOL_NAME_LABEL(trampoline_end)
arch/i386/vmlinux.lds +8 -2
@@ -3,7 +3,13 @@ */ OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386") OUTPUT_ARCH(i386) -ENTRY(_start) +physical_startup_32 = startup_32 - 0xC0000000; +ENTRY(physical_startup_32) +PHDRS +{ + text PT_LOAD AT(0x100000); + +} SECTIONS { . = 0xC0000000 + 0x100000;
@@ -12,7 +18,7 @@ *(.text) *(.fixup) *(.gnu.warning) - } = 0x9090 + } :text = 0x9090 _etext = .; /* End of text section */