From: "H. Peter Anvin" <hpa@zytor.com>
To: linux-kernel@vger.kernel.org, linux-arch@vger.kernel.org,
andi@firstfloor.org, akpm@linux-foundation.org
Cc: "H. Peter Anvin" <hpa@zytor.com>
Subject: [x86 setup 28/33] Code for actual protected-mode entry
Date: Mon, 9 Jul 2007 19:52:07 -0700 [thread overview]
Message-ID: <11840388782627-git-send-email-hpa@zytor.com> (raw)
Message-ID: <ae628cbaed0874c2c552ddbd77d61340438f9820.1184032749.git.hpa@zytor.com> (raw)
In-Reply-To: <11840387733386-git-send-email-hpa@zytor.com>
In-Reply-To: <2034f71d414def30de582fb59573295cadbdabb4.1184032748.git.hpa@zytor.com>
From: H. Peter Anvin <hpa@zytor.com>
This is the code which actually does the switch to protected mode,
including all preparation. It is also responsible for invoking the
boot loader hooks, if present.
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
---
arch/i386/boot/pm.c | 170 +++++++++++++++++++++++++++++++++++++++++++++++
arch/i386/boot/pmjump.S | 54 +++++++++++++++
2 files changed, 224 insertions(+), 0 deletions(-)
create mode 100644 arch/i386/boot/pm.c
create mode 100644 arch/i386/boot/pmjump.S
diff --git a/arch/i386/boot/pm.c b/arch/i386/boot/pm.c
new file mode 100644
index 0000000..4deb298
--- /dev/null
+++ b/arch/i386/boot/pm.c
@@ -0,0 +1,170 @@
+/* -*- linux-c -*- ------------------------------------------------------- *
+ *
+ * Copyright (C) 1991, 1992 Linus Torvalds
+ * Copyright 2007 rPath, Inc. - All Rights Reserved
+ *
+ * This file is part of the Linux kernel, and is made available under
+ * the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * arch/i386/boot/pm.c
+ *
+ * Prepare the machine for transition to protected mode.
+ */
+
+#include "boot.h"
+#include <asm/segment.h>
+
+/*
+ * Invoke the realmode switch hook if present; otherwise
+ * disable all interrupts.
+ */
+static void realmode_switch_hook(void)
+{
+ if (boot_params.hdr.realmode_swtch) {
+ asm volatile("lcallw *%0"
+ : : "m" (boot_params.hdr.realmode_swtch)
+ : "eax", "ebx", "ecx", "edx");
+ } else {
+ asm volatile("cli");
+ outb(0x80, 0x70); /* Disable NMI */
+ io_delay();
+ }
+}
+
+/*
+ * A zImage kernel is loaded at 0x10000 but wants to run at 0x1000.
+ * A bzImage kernel is loaded and runs at 0x100000.
+ */
+static void move_kernel_around(void)
+{
+ /* Note: rely on the compile-time option here rather than
+ the LOADED_HIGH flag. The Qemu kernel loader unconditionally
+ sets the loadflags to zero. */
+#ifndef __BIG_KERNEL__
+ u16 dst_seg, src_seg;
+ u32 syssize;
+
+ dst_seg = 0x1000 >> 4;
+ src_seg = 0x10000 >> 4;
+ syssize = boot_params.hdr.syssize; /* Size in 16-byte paragraps */
+
+ while (syssize) {
+ int paras = (syssize >= 0x1000) ? 0x1000 : syssize;
+ int dwords = paras << 2;
+
+ asm volatile("pushw %%es ; "
+ "pushw %%ds ; "
+ "movw %1,%%es ; "
+ "movw %2,%%ds ; "
+ "xorw %%di,%%di ; "
+ "xorw %%si,%%si ; "
+ "rep;movsl ; "
+ "popw %%ds ; "
+ "popw %%es"
+ : "+c" (dwords)
+ : "rm" (dst_seg), "rm" (src_seg)
+ : "esi", "edi");
+
+ syssize -= paras;
+ dst_seg += paras;
+ src_seg += paras;
+ }
+#endif
+}
+
+/*
+ * Disable all interrupts at the legacy PIC.
+ */
+static void mask_all_interrupts(void)
+{
+ outb(0xff, 0xa1); /* Mask all interrupts on the seconday PIC */
+ io_delay();
+ outb(0xfb, 0x21); /* Mask all but cascade on the primary PIC */
+ io_delay();
+}
+
+/*
+ * Reset IGNNE# if asserted in the FPU.
+ */
+static void reset_coprocessor(void)
+{
+ outb(0, 0xf0);
+ io_delay();
+ outb(0, 0xf1);
+ io_delay();
+}
+
+/*
+ * Set up the GDT
+ */
+#define GDT_ENTRY(flags,base,limit) \
+ (((u64)(base & 0xff000000) << 32) | \
+ ((u64)flags << 40) | \
+ ((u64)(limit & 0x00ff0000) << 32) | \
+ ((u64)(base & 0x00ffff00) << 16) | \
+ ((u64)(limit & 0x0000ffff)))
+
+struct gdt_ptr {
+ u16 len;
+ u32 ptr;
+} __attribute__((packed));
+
+static void setup_gdt(void)
+{
+ /* There are machines which are known to not boot with the GDT
+ being 8-byte unaligned. Intel recommends 16 byte alignment. */
+ static const u64 boot_gdt[] __attribute__((aligned(16))) = {
+ /* CS: code, read/execute, 4 GB, base 0 */
+ [GDT_ENTRY_BOOT_CS] = GDT_ENTRY(0xc09b, 0, 0xfffff),
+ /* DS: data, read/write, 4 GB, base 0 */
+ [GDT_ENTRY_BOOT_DS] = GDT_ENTRY(0xc093, 0, 0xfffff),
+ };
+ struct gdt_ptr gdt;
+
+ gdt.len = sizeof(boot_gdt)-1;
+ gdt.ptr = (u32)&boot_gdt + (ds() << 4);
+
+ asm volatile("lgdtl %0" : : "m" (gdt));
+}
+
+/*
+ * Set up the IDT
+ */
+static void setup_idt(void)
+{
+ static const struct gdt_ptr null_idt = {0, 0};
+ asm volatile("lidtl %0" : : "m" (null_idt));
+}
+
+/*
+ * Actual invocation sequence
+ */
+void go_to_protected_mode(void)
+{
+ /* Hook before leaving real mode, also disables interrupts */
+ realmode_switch_hook();
+
+ /* Move the kernel/setup to their final resting places */
+ move_kernel_around();
+
+ /* Enable the A20 gate */
+ if (enable_a20()) {
+ puts("A20 gate not responding, unable to boot...\n");
+ die();
+ }
+
+ /* Reset coprocessor (IGNNE#) */
+ reset_coprocessor();
+
+ /* Mask all interrupts in the PIC */
+ mask_all_interrupts();
+
+ /* Actual transition to protected mode... */
+ setup_idt();
+ setup_gdt();
+ protected_mode_jump(boot_params.hdr.code32_start,
+ (u32)&boot_params + (ds() << 4));
+}
diff --git a/arch/i386/boot/pmjump.S b/arch/i386/boot/pmjump.S
new file mode 100644
index 0000000..2e55923
--- /dev/null
+++ b/arch/i386/boot/pmjump.S
@@ -0,0 +1,54 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright (C) 1991, 1992 Linus Torvalds
+ * Copyright 2007 rPath, Inc. - All Rights Reserved
+ *
+ * This file is part of the Linux kernel, and is made available under
+ * the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * arch/i386/boot/pmjump.S
+ *
+ * The actual transition into protected mode
+ */
+
+#include <asm/boot.h>
+#include <asm/segment.h>
+
+ .text
+
+ .globl protected_mode_jump
+ .type protected_mode_jump, @function
+
+ .code16
+
+/*
+ * void protected_mode_jump(u32 entrypoint, u32 bootparams);
+ */
+protected_mode_jump:
+ xorl %ebx, %ebx # Flag to indicate this is a boot
+ movl %edx, %esi # Pointer to boot_params table
+ movl %eax, 2f # Patch ljmpl instruction
+ jmp 1f # Short jump to flush instruction q.
+
+1:
+ movw $__BOOT_DS, %cx
+
+ movl %cr0, %edx
+ orb $1, %dl # Protected mode (PE) bit
+ movl %edx, %cr0
+
+ movw %cx, %ds
+ movw %cx, %es
+ movw %cx, %fs
+ movw %cx, %gs
+ movw %cx, %ss
+
+ # Jump to the 32-bit entrypoint
+ .byte 0x66, 0xea # ljmpl opcode
+2: .long 0 # offset
+ .word __BOOT_CS # segment
+
+ .size protected_mode_jump, .-protected_mode_jump
--
1.5.2.2
next prev parent reply other threads:[~2007-07-10 3:48 UTC|newest]
Thread overview: 69+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-07-10 2:51 x86 setup code rewrite in C H. Peter Anvin
[not found] ` <2034f71d414def30de582fb59573295cadbdabb4.1184032748.git.hpa@zytor.com>
2007-07-10 2:51 ` [x86 setup 01/33] x86 setup: MAINTAINERS: formally take responsibility for the i386 boot code H. Peter Anvin
[not found] ` <de4df4ebeb6ec1bf47d4adf19f6a388035e2bfec.1184032748.git.hpa@zytor.com>
2007-07-10 2:51 ` [x86 setup 02/33] hd.c: remove BIOS/CMOS queries H. Peter Anvin
[not found] ` <38825725eb2e4aac1dd8e312460c5c239466b39a.1184032749.git.hpa@zytor.com>
2007-07-10 2:51 ` [x86 setup 03/33] include/asm-i386/boot.h: This is <asm/boot.h>, not <linux/boot.h> H. Peter Anvin
[not found] ` <62f9b07039d6bef798882977f3c8986fc2d2c6c6.1184032749.git.hpa@zytor.com>
2007-07-10 2:51 ` [x86 setup 04/33] Unify the CPU features vectors between i386 and x86-64 H. Peter Anvin
[not found] ` <8376b111bbf6bf6c8c884fabcb9c1844950737b0.1184032749.git.hpa@zytor.com>
2007-07-10 2:51 ` [x86 setup 05/33] Change CONFIG_X86_MINIMUM_CPU_MODEL to CONFIG_X86_MINIMUM_CPU_FAMILY H. Peter Anvin
[not found] ` <06a26dd135e1fc3b7f8b238c5b1bc8404d23acac.1184032749.git.hpa@zytor.com>
2007-07-10 2:51 ` [x86 setup 06/33] Clean up struct screen_info (<linux/screen_info.h>) H. Peter Anvin
[not found] ` <32e7eb05f31e6fbff33ecce6580ee4f7bdf38fef.1184032749.git.hpa@zytor.com>
2007-07-10 2:51 ` [x86 setup 07/33] Use a new CPU feature word to cover all Intel features that are spread around H. Peter Anvin
[not found] ` <a8e9d4bffc9fa216d32c930606475fd8d1df9405.1184032749.git.hpa@zytor.com>
2007-07-10 2:51 ` [x86 setup 08/33] Define zero-page offset 0x1e4 as a scratch field, and use it H. Peter Anvin
[not found] ` <0ff939788c542b0560ec39668550557dcc134afe.1184032749.git.hpa@zytor.com>
2007-07-10 2:51 ` [x86 setup 10/33] Make struct boot_params a real structure, and remove obsolete fields H. Peter Anvin
[not found] ` <bbeadd1995da049cf6880ab58794f84ec8785a08.1184032749.git.hpa@zytor.com>
2007-07-10 2:51 ` [x86 setup 11/33] x86-64: add CONFIG_PHYSICAL_ALIGN for consistency with i386 H. Peter Anvin
[not found] ` <e3ff2ad47d4610cdafbe24dcabadef42bb3166fb.1184032749.git.hpa@zytor.com>
2007-07-10 2:51 ` [x86 setup 12/33] x86-64: add symbolic constants for the boot segment selectors H. Peter Anvin
[not found] ` <96024b4c88d58a8473deb48a8038f6893b8b6b55.1184032749.git.hpa@zytor.com>
2007-07-10 2:51 ` [x86 setup 13/33] Header file to produce 16-bit code with gcc H. Peter Anvin
2007-07-10 14:16 ` Segher Boessenkool
2007-07-10 15:21 ` Andi Kleen
2007-07-10 15:48 ` H. Peter Anvin
2007-07-10 15:53 ` H. Peter Anvin
2007-07-10 20:08 ` Segher Boessenkool
2007-07-10 20:43 ` H. Peter Anvin
2007-07-10 21:08 ` Pawel Dziepak
2007-07-10 21:20 ` H. Peter Anvin
2007-07-11 0:26 ` Brian Gerst
2007-07-10 19:57 ` Segher Boessenkool
2007-07-10 20:42 ` H. Peter Anvin
2007-07-10 21:10 ` Segher Boessenkool
2007-07-10 21:40 ` H. Peter Anvin
2007-07-10 22:06 ` Segher Boessenkool
2007-07-10 21:43 ` Adrian Bunk
2007-07-10 21:46 ` H. Peter Anvin
2007-07-11 0:30 ` Brian Gerst
[not found] ` <a862328acf06a9587458c615848099f96fbab1ce.1184032749.git.hpa@zytor.com>
2007-07-10 2:51 ` [x86 setup 14/33] Top header file for new x86 setup code H. Peter Anvin
[not found] ` <899e4acb1fe3e4313dfdca5398431274808d71ef.1184032749.git.hpa@zytor.com>
2007-07-10 2:51 ` [x86 setup 15/33] Simple bitops for the " H. Peter Anvin
[not found] ` <d5bd30fc697149284a73e09efe54884ab178de7e.1184032749.git.hpa@zytor.com>
2007-07-10 2:51 ` [x86 setup 16/33] String-handling functions " H. Peter Anvin
2007-07-10 18:25 ` Jan Engelhardt
2007-07-10 18:35 ` H. Peter Anvin
2007-07-10 20:10 ` Segher Boessenkool
2007-07-10 20:44 ` H. Peter Anvin
2007-07-10 21:14 ` Segher Boessenkool
2007-07-11 12:46 ` Andi Kleen
[not found] ` <17db5b2c8a43cf36b2eb36afc142ce9ca0552282.1184032749.git.hpa@zytor.com>
2007-07-10 2:51 ` [x86 setup 17/33] A20 handling code H. Peter Anvin
2007-07-10 18:27 ` Jan Engelhardt
2007-07-10 18:33 ` H. Peter Anvin
2007-07-10 18:36 ` H. Peter Anvin
[not found] ` <c488ae7cd0ddd799b666f55652248be3c346a076.1184032749.git.hpa@zytor.com>
2007-07-10 2:51 ` [x86 setup 18/33] APM probing code H. Peter Anvin
[not found] ` <3726c75f36dc97c1fce93835e872bbc814857990.1184032749.git.hpa@zytor.com>
2007-07-10 2:51 ` [x86 setup 19/33] Command-line parsing code for the new x86 setup code H. Peter Anvin
[not found] ` <bf3e29f3d8c12230b38cae29ef5b476267d40cd1.1184032749.git.hpa@zytor.com>
2007-07-10 2:51 ` [x86 setup 20/33] Console-writing " H. Peter Anvin
2007-07-10 18:35 ` Jan Engelhardt
2007-07-10 18:48 ` H. Peter Anvin
[not found] ` <b4eed00df1889f94e8799ca6c0ce081bc5140688.1184032749.git.hpa@zytor.com>
2007-07-10 2:52 ` [x86 setup 21/33] Version string " H. Peter Anvin
[not found] ` <f1626ee0c265de9c41725f61eaee8a9017d8c8ff.1184032749.git.hpa@zytor.com>
2007-07-10 2:52 ` [x86 setup 22/33] CPU features verification " H. Peter Anvin
2007-07-10 7:37 ` Sébastien Dugué
[not found] ` <b577403d806edfbb1c17ecfec94971fc757a066c.1184032749.git.hpa@zytor.com>
2007-07-10 2:52 ` [x86 setup 23/33] EDD probing code " H. Peter Anvin
[not found] ` <77f7b2e92bb1de0f9d423b6537b8156296bcf931.1184032749.git.hpa@zytor.com>
2007-07-10 2:52 ` [x86 setup 24/33] MCA support for " H. Peter Anvin
[not found] ` <75642968817648a7816a4782f76138e4f608f1ab.1184032749.git.hpa@zytor.com>
2007-07-10 2:52 ` [x86 setup 25/33] Memory probing support for the " H. Peter Anvin
[not found] ` <dd2fade47882935c137f6d2a3c955eac1f6f8ecf.1184032749.git.hpa@zytor.com>
2007-07-10 2:52 ` [x86 setup 26/33] Voyager " H. Peter Anvin
[not found] ` <f8afa57a4934b75080449e8dd3a23d178be77a41.1184032749.git.hpa@zytor.com>
2007-07-10 2:52 ` [x86 setup 27/33] Video mode probing " H. Peter Anvin
[not found] ` <ae628cbaed0874c2c552ddbd77d61340438f9820.1184032749.git.hpa@zytor.com>
2007-07-10 2:52 ` H. Peter Anvin [this message]
[not found] ` <26d4ebeefed3e0b1593d4fa2357db6912ee944cb.1184032749.git.hpa@zytor.com>
2007-07-10 2:52 ` [x86 setup 29/33] Assembly header and main routine for " H. Peter Anvin
[not found] ` <fd5cf379a91de82890893de655876e39e78c1dc9.1184032749.git.hpa@zytor.com>
2007-07-10 2:52 ` [x86 setup 30/33] Linker script for the " H. Peter Anvin
[not found] ` <842bbe280e87886e7a1b187434841c7f7334244c.1184032749.git.hpa@zytor.com>
2007-07-10 2:52 ` [x86 setup 31/33] Use the new x86 setup code for i386 H. Peter Anvin
2007-07-10 7:55 ` Tilman Schmidt
[not found] ` <0daaab19675363b0c9126a9b98a8325883bbcfea.1184032749.git.hpa@zytor.com>
2007-07-10 2:52 ` [x86 setup 32/33] Use the new x86 setup code for x86-64; unify with i386 H. Peter Anvin
[not found] ` <51664bcb2a5a2f1fe130229d34128a642dc81a4c.1184032749.git.hpa@zytor.com>
2007-07-10 2:52 ` [x86 setup 33/33] Remove old i386 setup code H. Peter Anvin
[not found] ` <361d0a8b7b7ea9d41d0c25664b3e2b30fd99e329.1184032749.git.hpa@zytor.com>
2007-07-10 2:51 ` [x86 setup 09/33] Make definitions for struct e820entry and struct e820map consistent H. Peter Anvin
2007-07-10 11:48 ` Andi Kleen
2007-07-10 4:24 ` x86 setup code rewrite in C Yinghai Lu
2007-07-10 4:39 ` H. Peter Anvin
2007-07-10 5:25 ` Jeff Garzik
2007-07-10 16:24 ` Jeremy Fitzhardinge
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=11840388782627-git-send-email-hpa@zytor.com \
--to=hpa@zytor.com \
--cc=akpm@linux-foundation.org \
--cc=andi@firstfloor.org \
--cc=linux-arch@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).