arch/x86/realmode/rm/reboot.S

Source file repositories/reference/linux-study-clean/arch/x86/realmode/rm/reboot.S

File Facts

System
Linux kernel
Corpus path
arch/x86/realmode/rm/reboot.S
Extension
.S
Size
4322 bytes
Lines
159
Domain
Architecture Layer
Bucket
arch/x86
Inferred role
Architecture Layer: arch/x86
Status
atlas-only

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

#include <linux/linkage.h>
#include <asm/desc_defs.h>
#include <asm/segment.h>
#include <asm/page_types.h>
#include <asm/processor-flags.h>
#include <asm/msr-index.h>
#include "realmode.h"

/*
 * The following code and data reboots the machine by switching to real
 * mode and jumping to the BIOS reset entry point, as if the CPU has
 * really been reset.  The previous version asked the keyboard
 * controller to pulse the CPU reset line, which is more thorough, but
 * doesn't work with at least one type of 486 motherboard.  It is easy
 * to stop this code working; hence the copious comments.
 *
 * This code is called with the restart type (0 = BIOS, 1 = APM) in
 * the primary argument register (%eax for 32 bit, %edi for 64 bit).
 */
	.section ".text32", "ax"
	.code32
SYM_CODE_START(machine_real_restart_asm)

#ifdef CONFIG_X86_64
	/* Switch to trampoline GDT as it is guaranteed < 4 GiB */
	movl	$__KERNEL_DS, %eax
	movl	%eax, %ds
	lgdtl	pa_tr_gdt

	/* Disable paging to drop us out of long mode */
	movl	%cr0, %eax
	andl	$~X86_CR0_PG, %eax
	movl	%eax, %cr0
	ljmpl	$__KERNEL32_CS, $pa_machine_real_restart_paging_off

SYM_INNER_LABEL(machine_real_restart_paging_off, SYM_L_GLOBAL)
	xorl	%eax, %eax
	xorl	%edx, %edx
	movl	$MSR_EFER, %ecx
	wrmsr

	movl	%edi, %eax
	
#endif /* CONFIG_X86_64 */
	
	/* Set up the IDT for real mode. */
	lidtl	pa_machine_real_restart_idt

	/*
	 * Set up a GDT from which we can load segment descriptors for real
	 * mode.  The GDT is not used in real mode; it is just needed here to
	 * prepare the descriptors.
	 */
	lgdtl	pa_machine_real_restart_gdt

	/*
	 * Load the data segment registers with 16-bit compatible values
	 */
	movl	$16, %ecx
	movl	%ecx, %ds
	movl	%ecx, %es
	movl	%ecx, %fs
	movl	%ecx, %gs
	movl	%ecx, %ss
	ljmpw	$8, $1f
SYM_CODE_END(machine_real_restart_asm)

/*
 * This is 16-bit protected mode code to disable paging and the cache,
 * switch to real mode and jump to the BIOS reset code.

Annotation

Implementation Notes