mirror of https://gitee.com/openkylin/linux.git
Merge branch 'x86-efi-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 EFI fixes from Peter Anvin: "This is a collection of fixes for the EFI support. The controversial bit here is a set of patches which bumps the boot protocol version as part of fixing some serious problems with the EFI handover protocol, used when booting under EFI using a bootloader as opposed to directly from EFI. These changes should also make it a lot saner to support cross-mode 32/64-bit EFI booting in the future. Getting these changes into 3.8 means we avoid presenting an inconsistent ABI to bootloaders. Other changes are display detection and fixing efivarfs." * 'x86-efi-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86, efi: remove attribute check from setup_efi_pci x86, build: Dynamically find entry points in compressed startup code x86, efi: Fix PCI ROM handing in EFI boot stub, in 32-bit mode x86, efi: Fix 32-bit EFI handover protocol entry point x86, efi: Fix display detection in EFI boot stub x86, boot: Define the 2.12 bzImage boot protocol x86/boot: Fix minor fd leakage in tools/relocs.c x86, efi: Set runtime_version to the EFI spec revision x86, efi: fix 32-bit warnings in setup_efi_pci() efivarfs: Delete dentry from dcache in efivarfs_file_write() efivarfs: Never return ENOENT from firmware efi, x86: Pass a proper identity mapping in efi_call_phys_prelog efivarfs: Drop link count of the right inode
This commit is contained in:
commit
04c2eee5b9
|
@ -57,6 +57,10 @@ Protocol 2.10: (Kernel 2.6.31) Added a protocol for relaxed alignment
|
|||
Protocol 2.11: (Kernel 3.6) Added a field for offset of EFI handover
|
||||
protocol entry point.
|
||||
|
||||
Protocol 2.12: (Kernel 3.9) Added the xloadflags field and extension fields
|
||||
to struct boot_params for for loading bzImage and ramdisk
|
||||
above 4G in 64bit.
|
||||
|
||||
**** MEMORY LAYOUT
|
||||
|
||||
The traditional memory map for the kernel loader, used for Image or
|
||||
|
@ -182,7 +186,7 @@ Offset Proto Name Meaning
|
|||
0230/4 2.05+ kernel_alignment Physical addr alignment required for kernel
|
||||
0234/1 2.05+ relocatable_kernel Whether kernel is relocatable or not
|
||||
0235/1 2.10+ min_alignment Minimum alignment, as a power of two
|
||||
0236/2 N/A pad3 Unused
|
||||
0236/2 2.12+ xloadflags Boot protocol option flags
|
||||
0238/4 2.06+ cmdline_size Maximum size of the kernel command line
|
||||
023C/4 2.07+ hardware_subarch Hardware subarchitecture
|
||||
0240/8 2.07+ hardware_subarch_data Subarchitecture-specific data
|
||||
|
@ -582,6 +586,27 @@ Protocol: 2.10+
|
|||
misaligned kernel. Therefore, a loader should typically try each
|
||||
power-of-two alignment from kernel_alignment down to this alignment.
|
||||
|
||||
Field name: xloadflags
|
||||
Type: read
|
||||
Offset/size: 0x236/2
|
||||
Protocol: 2.12+
|
||||
|
||||
This field is a bitmask.
|
||||
|
||||
Bit 0 (read): XLF_KERNEL_64
|
||||
- If 1, this kernel has the legacy 64-bit entry point at 0x200.
|
||||
|
||||
Bit 1 (read): XLF_CAN_BE_LOADED_ABOVE_4G
|
||||
- If 1, kernel/boot_params/cmdline/ramdisk can be above 4G.
|
||||
|
||||
Bit 2 (read): XLF_EFI_HANDOVER_32
|
||||
- If 1, the kernel supports the 32-bit EFI handoff entry point
|
||||
given at handover_offset.
|
||||
|
||||
Bit 3 (read): XLF_EFI_HANDOVER_64
|
||||
- If 1, the kernel supports the 64-bit EFI handoff entry point
|
||||
given at handover_offset + 0x200.
|
||||
|
||||
Field name: cmdline_size
|
||||
Type: read
|
||||
Offset/size: 0x238/4
|
||||
|
|
|
@ -19,6 +19,9 @@ Offset Proto Name Meaning
|
|||
090/010 ALL hd1_info hd1 disk parameter, OBSOLETE!!
|
||||
0A0/010 ALL sys_desc_table System description table (struct sys_desc_table)
|
||||
0B0/010 ALL olpc_ofw_header OLPC's OpenFirmware CIF and friends
|
||||
0C0/004 ALL ext_ramdisk_image ramdisk_image high 32bits
|
||||
0C4/004 ALL ext_ramdisk_size ramdisk_size high 32bits
|
||||
0C8/004 ALL ext_cmd_line_ptr cmd_line_ptr high 32bits
|
||||
140/080 ALL edid_info Video mode setup (struct edid_info)
|
||||
1C0/020 ALL efi_info EFI 32 information (struct efi_info)
|
||||
1E0/004 ALL alk_mem_k Alternative mem check, in KB
|
||||
|
@ -27,6 +30,7 @@ Offset Proto Name Meaning
|
|||
1E9/001 ALL eddbuf_entries Number of entries in eddbuf (below)
|
||||
1EA/001 ALL edd_mbr_sig_buf_entries Number of entries in edd_mbr_sig_buffer
|
||||
(below)
|
||||
1EF/001 ALL sentinel Used to detect broken bootloaders
|
||||
290/040 ALL edd_mbr_sig_buffer EDD MBR signatures
|
||||
2D0/A00 ALL e820_map E820 memory map table
|
||||
(array of struct e820entry)
|
||||
|
|
|
@ -71,7 +71,7 @@ GCOV_PROFILE := n
|
|||
$(obj)/bzImage: asflags-y := $(SVGA_MODE)
|
||||
|
||||
quiet_cmd_image = BUILD $@
|
||||
cmd_image = $(obj)/tools/build $(obj)/setup.bin $(obj)/vmlinux.bin > $@
|
||||
cmd_image = $(obj)/tools/build $(obj)/setup.bin $(obj)/vmlinux.bin $(obj)/zoffset.h > $@
|
||||
|
||||
$(obj)/bzImage: $(obj)/setup.bin $(obj)/vmlinux.bin $(obj)/tools/build FORCE
|
||||
$(call if_changed,image)
|
||||
|
@ -92,7 +92,7 @@ targets += voffset.h
|
|||
$(obj)/voffset.h: vmlinux FORCE
|
||||
$(call if_changed,voffset)
|
||||
|
||||
sed-zoffset := -e 's/^\([0-9a-fA-F]*\) . \(startup_32\|input_data\|_end\|z_.*\)$$/\#define ZO_\2 0x\1/p'
|
||||
sed-zoffset := -e 's/^\([0-9a-fA-F]*\) . \(startup_32\|startup_64\|efi_pe_entry\|efi_stub_entry\|input_data\|_end\|z_.*\)$$/\#define ZO_\2 0x\1/p'
|
||||
|
||||
quiet_cmd_zoffset = ZOFFSET $@
|
||||
cmd_zoffset = $(NM) $< | sed -n $(sed-zoffset) > $@
|
||||
|
|
|
@ -256,10 +256,10 @@ static efi_status_t setup_efi_pci(struct boot_params *params)
|
|||
int i;
|
||||
struct setup_data *data;
|
||||
|
||||
data = (struct setup_data *)params->hdr.setup_data;
|
||||
data = (struct setup_data *)(unsigned long)params->hdr.setup_data;
|
||||
|
||||
while (data && data->next)
|
||||
data = (struct setup_data *)data->next;
|
||||
data = (struct setup_data *)(unsigned long)data->next;
|
||||
|
||||
status = efi_call_phys5(sys_table->boottime->locate_handle,
|
||||
EFI_LOCATE_BY_PROTOCOL, &pci_proto,
|
||||
|
@ -295,16 +295,18 @@ static efi_status_t setup_efi_pci(struct boot_params *params)
|
|||
if (!pci)
|
||||
continue;
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
status = efi_call_phys4(pci->attributes, pci,
|
||||
EfiPciIoAttributeOperationGet, 0,
|
||||
&attributes);
|
||||
|
||||
#else
|
||||
status = efi_call_phys5(pci->attributes, pci,
|
||||
EfiPciIoAttributeOperationGet, 0, 0,
|
||||
&attributes);
|
||||
#endif
|
||||
if (status != EFI_SUCCESS)
|
||||
continue;
|
||||
|
||||
if (!(attributes & EFI_PCI_IO_ATTRIBUTE_EMBEDDED_ROM))
|
||||
continue;
|
||||
|
||||
if (!pci->romimage || !pci->romsize)
|
||||
continue;
|
||||
|
||||
|
@ -345,9 +347,9 @@ static efi_status_t setup_efi_pci(struct boot_params *params)
|
|||
memcpy(rom->romdata, pci->romimage, pci->romsize);
|
||||
|
||||
if (data)
|
||||
data->next = (uint64_t)rom;
|
||||
data->next = (unsigned long)rom;
|
||||
else
|
||||
params->hdr.setup_data = (uint64_t)rom;
|
||||
params->hdr.setup_data = (unsigned long)rom;
|
||||
|
||||
data = (struct setup_data *)rom;
|
||||
|
||||
|
@ -432,10 +434,9 @@ static efi_status_t setup_gop(struct screen_info *si, efi_guid_t *proto,
|
|||
* Once we've found a GOP supporting ConOut,
|
||||
* don't bother looking any further.
|
||||
*/
|
||||
first_gop = gop;
|
||||
if (conout_found)
|
||||
break;
|
||||
|
||||
first_gop = gop;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -35,11 +35,11 @@ ENTRY(startup_32)
|
|||
#ifdef CONFIG_EFI_STUB
|
||||
jmp preferred_addr
|
||||
|
||||
.balign 0x10
|
||||
/*
|
||||
* We don't need the return address, so set up the stack so
|
||||
* efi_main() can find its arugments.
|
||||
* efi_main() can find its arguments.
|
||||
*/
|
||||
ENTRY(efi_pe_entry)
|
||||
add $0x4, %esp
|
||||
|
||||
call make_boot_params
|
||||
|
@ -50,8 +50,10 @@ ENTRY(startup_32)
|
|||
pushl %eax
|
||||
pushl %esi
|
||||
pushl %ecx
|
||||
sub $0x4, %esp
|
||||
|
||||
.org 0x30,0x90
|
||||
ENTRY(efi_stub_entry)
|
||||
add $0x4, %esp
|
||||
call efi_main
|
||||
cmpl $0, %eax
|
||||
movl %eax, %esi
|
||||
|
|
|
@ -201,12 +201,12 @@ ENTRY(startup_64)
|
|||
*/
|
||||
#ifdef CONFIG_EFI_STUB
|
||||
/*
|
||||
* The entry point for the PE/COFF executable is 0x210, so only
|
||||
* legacy boot loaders will execute this jmp.
|
||||
* The entry point for the PE/COFF executable is efi_pe_entry, so
|
||||
* only legacy boot loaders will execute this jmp.
|
||||
*/
|
||||
jmp preferred_addr
|
||||
|
||||
.org 0x210
|
||||
ENTRY(efi_pe_entry)
|
||||
mov %rcx, %rdi
|
||||
mov %rdx, %rsi
|
||||
pushq %rdi
|
||||
|
@ -218,7 +218,7 @@ ENTRY(startup_64)
|
|||
popq %rsi
|
||||
popq %rdi
|
||||
|
||||
.org 0x230,0x90
|
||||
ENTRY(efi_stub_entry)
|
||||
call efi_main
|
||||
movq %rax,%rsi
|
||||
cmpq $0,%rax
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include <asm/e820.h>
|
||||
#include <asm/page_types.h>
|
||||
#include <asm/setup.h>
|
||||
#include <asm/bootparam.h>
|
||||
#include "boot.h"
|
||||
#include "voffset.h"
|
||||
#include "zoffset.h"
|
||||
|
@ -255,6 +256,9 @@ section_table:
|
|||
# header, from the old boot sector.
|
||||
|
||||
.section ".header", "a"
|
||||
.globl sentinel
|
||||
sentinel: .byte 0xff, 0xff /* Used to detect broken loaders */
|
||||
|
||||
.globl hdr
|
||||
hdr:
|
||||
setup_sects: .byte 0 /* Filled in by build.c */
|
||||
|
@ -279,7 +283,7 @@ _start:
|
|||
# Part 2 of the header, from the old setup.S
|
||||
|
||||
.ascii "HdrS" # header signature
|
||||
.word 0x020b # header version number (>= 0x0105)
|
||||
.word 0x020c # header version number (>= 0x0105)
|
||||
# or else old loadlin-1.5 will fail)
|
||||
.globl realmode_swtch
|
||||
realmode_swtch: .word 0, 0 # default_switch, SETUPSEG
|
||||
|
@ -297,13 +301,7 @@ type_of_loader: .byte 0 # 0 means ancient bootloader, newer
|
|||
|
||||
# flags, unused bits must be zero (RFU) bit within loadflags
|
||||
loadflags:
|
||||
LOADED_HIGH = 1 # If set, the kernel is loaded high
|
||||
CAN_USE_HEAP = 0x80 # If set, the loader also has set
|
||||
# heap_end_ptr to tell how much
|
||||
# space behind setup.S can be used for
|
||||
# heap purposes.
|
||||
# Only the loader knows what is free
|
||||
.byte LOADED_HIGH
|
||||
.byte LOADED_HIGH # The kernel is to be loaded high
|
||||
|
||||
setup_move_size: .word 0x8000 # size to move, when setup is not
|
||||
# loaded at 0x90000. We will move setup
|
||||
|
@ -369,7 +367,23 @@ relocatable_kernel: .byte 1
|
|||
relocatable_kernel: .byte 0
|
||||
#endif
|
||||
min_alignment: .byte MIN_KERNEL_ALIGN_LG2 # minimum alignment
|
||||
pad3: .word 0
|
||||
|
||||
xloadflags:
|
||||
#ifdef CONFIG_X86_64
|
||||
# define XLF0 XLF_KERNEL_64 /* 64-bit kernel */
|
||||
#else
|
||||
# define XLF0 0
|
||||
#endif
|
||||
#ifdef CONFIG_EFI_STUB
|
||||
# ifdef CONFIG_X86_64
|
||||
# define XLF23 XLF_EFI_HANDOVER_64 /* 64-bit EFI handover ok */
|
||||
# else
|
||||
# define XLF23 XLF_EFI_HANDOVER_32 /* 32-bit EFI handover ok */
|
||||
# endif
|
||||
#else
|
||||
# define XLF23 0
|
||||
#endif
|
||||
.word XLF0 | XLF23
|
||||
|
||||
cmdline_size: .long COMMAND_LINE_SIZE-1 #length of the command line,
|
||||
#added with boot protocol
|
||||
|
@ -397,8 +411,13 @@ pref_address: .quad LOAD_PHYSICAL_ADDR # preferred load addr
|
|||
#define INIT_SIZE VO_INIT_SIZE
|
||||
#endif
|
||||
init_size: .long INIT_SIZE # kernel initialization size
|
||||
handover_offset: .long 0x30 # offset to the handover
|
||||
handover_offset:
|
||||
#ifdef CONFIG_EFI_STUB
|
||||
.long 0x30 # offset to the handover
|
||||
# protocol entry point
|
||||
#else
|
||||
.long 0
|
||||
#endif
|
||||
|
||||
# End of setup header #####################################################
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ SECTIONS
|
|||
.bstext : { *(.bstext) }
|
||||
.bsdata : { *(.bsdata) }
|
||||
|
||||
. = 497;
|
||||
. = 495;
|
||||
.header : { *(.header) }
|
||||
.entrytext : { *(.entrytext) }
|
||||
.inittext : { *(.inittext) }
|
||||
|
|
|
@ -52,6 +52,10 @@ int is_big_kernel;
|
|||
|
||||
#define PECOFF_RELOC_RESERVE 0x20
|
||||
|
||||
unsigned long efi_stub_entry;
|
||||
unsigned long efi_pe_entry;
|
||||
unsigned long startup_64;
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
static const u32 crctab32[] = {
|
||||
|
@ -132,7 +136,7 @@ static void die(const char * str, ...)
|
|||
|
||||
static void usage(void)
|
||||
{
|
||||
die("Usage: build setup system [> image]");
|
||||
die("Usage: build setup system [zoffset.h] [> image]");
|
||||
}
|
||||
|
||||
#ifdef CONFIG_EFI_STUB
|
||||
|
@ -206,30 +210,54 @@ static void update_pecoff_text(unsigned int text_start, unsigned int file_sz)
|
|||
*/
|
||||
put_unaligned_le32(file_sz - 512, &buf[pe_header + 0x1c]);
|
||||
|
||||
#ifdef CONFIG_X86_32
|
||||
/*
|
||||
* Address of entry point.
|
||||
*
|
||||
* The EFI stub entry point is +16 bytes from the start of
|
||||
* the .text section.
|
||||
* Address of entry point for PE/COFF executable
|
||||
*/
|
||||
put_unaligned_le32(text_start + 16, &buf[pe_header + 0x28]);
|
||||
#else
|
||||
/*
|
||||
* Address of entry point. startup_32 is at the beginning and
|
||||
* the 64-bit entry point (startup_64) is always 512 bytes
|
||||
* after. The EFI stub entry point is 16 bytes after that, as
|
||||
* the first instruction allows legacy loaders to jump over
|
||||
* the EFI stub initialisation
|
||||
*/
|
||||
put_unaligned_le32(text_start + 528, &buf[pe_header + 0x28]);
|
||||
#endif /* CONFIG_X86_32 */
|
||||
put_unaligned_le32(text_start + efi_pe_entry, &buf[pe_header + 0x28]);
|
||||
|
||||
update_pecoff_section_header(".text", text_start, text_sz);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_EFI_STUB */
|
||||
|
||||
|
||||
/*
|
||||
* Parse zoffset.h and find the entry points. We could just #include zoffset.h
|
||||
* but that would mean tools/build would have to be rebuilt every time. It's
|
||||
* not as if parsing it is hard...
|
||||
*/
|
||||
#define PARSE_ZOFS(p, sym) do { \
|
||||
if (!strncmp(p, "#define ZO_" #sym " ", 11+sizeof(#sym))) \
|
||||
sym = strtoul(p + 11 + sizeof(#sym), NULL, 16); \
|
||||
} while (0)
|
||||
|
||||
static void parse_zoffset(char *fname)
|
||||
{
|
||||
FILE *file;
|
||||
char *p;
|
||||
int c;
|
||||
|
||||
file = fopen(fname, "r");
|
||||
if (!file)
|
||||
die("Unable to open `%s': %m", fname);
|
||||
c = fread(buf, 1, sizeof(buf) - 1, file);
|
||||
if (ferror(file))
|
||||
die("read-error on `zoffset.h'");
|
||||
buf[c] = 0;
|
||||
|
||||
p = (char *)buf;
|
||||
|
||||
while (p && *p) {
|
||||
PARSE_ZOFS(p, efi_stub_entry);
|
||||
PARSE_ZOFS(p, efi_pe_entry);
|
||||
PARSE_ZOFS(p, startup_64);
|
||||
|
||||
p = strchr(p, '\n');
|
||||
while (p && (*p == '\r' || *p == '\n'))
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char ** argv)
|
||||
{
|
||||
unsigned int i, sz, setup_sectors;
|
||||
|
@ -241,7 +269,19 @@ int main(int argc, char ** argv)
|
|||
void *kernel;
|
||||
u32 crc = 0xffffffffUL;
|
||||
|
||||
if (argc != 3)
|
||||
/* Defaults for old kernel */
|
||||
#ifdef CONFIG_X86_32
|
||||
efi_pe_entry = 0x10;
|
||||
efi_stub_entry = 0x30;
|
||||
#else
|
||||
efi_pe_entry = 0x210;
|
||||
efi_stub_entry = 0x230;
|
||||
startup_64 = 0x200;
|
||||
#endif
|
||||
|
||||
if (argc == 4)
|
||||
parse_zoffset(argv[3]);
|
||||
else if (argc != 3)
|
||||
usage();
|
||||
|
||||
/* Copy the setup code */
|
||||
|
@ -299,6 +339,11 @@ int main(int argc, char ** argv)
|
|||
|
||||
#ifdef CONFIG_EFI_STUB
|
||||
update_pecoff_text(setup_sectors * 512, sz + i + ((sys_size * 16) - sz));
|
||||
|
||||
#ifdef CONFIG_X86_64 /* Yes, this is really how we defined it :( */
|
||||
efi_stub_entry -= 0x200;
|
||||
#endif
|
||||
put_unaligned_le32(efi_stub_entry, &buf[0x264]);
|
||||
#endif
|
||||
|
||||
crc = partial_crc32(buf, i, crc);
|
||||
|
|
|
@ -1,6 +1,31 @@
|
|||
#ifndef _ASM_X86_BOOTPARAM_H
|
||||
#define _ASM_X86_BOOTPARAM_H
|
||||
|
||||
/* setup_data types */
|
||||
#define SETUP_NONE 0
|
||||
#define SETUP_E820_EXT 1
|
||||
#define SETUP_DTB 2
|
||||
#define SETUP_PCI 3
|
||||
|
||||
/* ram_size flags */
|
||||
#define RAMDISK_IMAGE_START_MASK 0x07FF
|
||||
#define RAMDISK_PROMPT_FLAG 0x8000
|
||||
#define RAMDISK_LOAD_FLAG 0x4000
|
||||
|
||||
/* loadflags */
|
||||
#define LOADED_HIGH (1<<0)
|
||||
#define QUIET_FLAG (1<<5)
|
||||
#define KEEP_SEGMENTS (1<<6)
|
||||
#define CAN_USE_HEAP (1<<7)
|
||||
|
||||
/* xloadflags */
|
||||
#define XLF_KERNEL_64 (1<<0)
|
||||
#define XLF_CAN_BE_LOADED_ABOVE_4G (1<<1)
|
||||
#define XLF_EFI_HANDOVER_32 (1<<2)
|
||||
#define XLF_EFI_HANDOVER_64 (1<<3)
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/screen_info.h>
|
||||
#include <linux/apm_bios.h>
|
||||
|
@ -9,12 +34,6 @@
|
|||
#include <asm/ist.h>
|
||||
#include <video/edid.h>
|
||||
|
||||
/* setup data types */
|
||||
#define SETUP_NONE 0
|
||||
#define SETUP_E820_EXT 1
|
||||
#define SETUP_DTB 2
|
||||
#define SETUP_PCI 3
|
||||
|
||||
/* extensible setup data list node */
|
||||
struct setup_data {
|
||||
__u64 next;
|
||||
|
@ -28,9 +47,6 @@ struct setup_header {
|
|||
__u16 root_flags;
|
||||
__u32 syssize;
|
||||
__u16 ram_size;
|
||||
#define RAMDISK_IMAGE_START_MASK 0x07FF
|
||||
#define RAMDISK_PROMPT_FLAG 0x8000
|
||||
#define RAMDISK_LOAD_FLAG 0x4000
|
||||
__u16 vid_mode;
|
||||
__u16 root_dev;
|
||||
__u16 boot_flag;
|
||||
|
@ -42,10 +58,6 @@ struct setup_header {
|
|||
__u16 kernel_version;
|
||||
__u8 type_of_loader;
|
||||
__u8 loadflags;
|
||||
#define LOADED_HIGH (1<<0)
|
||||
#define QUIET_FLAG (1<<5)
|
||||
#define KEEP_SEGMENTS (1<<6)
|
||||
#define CAN_USE_HEAP (1<<7)
|
||||
__u16 setup_move_size;
|
||||
__u32 code32_start;
|
||||
__u32 ramdisk_image;
|
||||
|
@ -58,7 +70,8 @@ struct setup_header {
|
|||
__u32 initrd_addr_max;
|
||||
__u32 kernel_alignment;
|
||||
__u8 relocatable_kernel;
|
||||
__u8 _pad2[3];
|
||||
__u8 min_alignment;
|
||||
__u16 xloadflags;
|
||||
__u32 cmdline_size;
|
||||
__u32 hardware_subarch;
|
||||
__u64 hardware_subarch_data;
|
||||
|
@ -106,7 +119,10 @@ struct boot_params {
|
|||
__u8 hd1_info[16]; /* obsolete! */ /* 0x090 */
|
||||
struct sys_desc_table sys_desc_table; /* 0x0a0 */
|
||||
struct olpc_ofw_header olpc_ofw_header; /* 0x0b0 */
|
||||
__u8 _pad4[128]; /* 0x0c0 */
|
||||
__u32 ext_ramdisk_image; /* 0x0c0 */
|
||||
__u32 ext_ramdisk_size; /* 0x0c4 */
|
||||
__u32 ext_cmd_line_ptr; /* 0x0c8 */
|
||||
__u8 _pad4[116]; /* 0x0cc */
|
||||
struct edid_info edid_info; /* 0x140 */
|
||||
struct efi_info efi_info; /* 0x1c0 */
|
||||
__u32 alt_mem_k; /* 0x1e0 */
|
||||
|
@ -115,7 +131,20 @@ struct boot_params {
|
|||
__u8 eddbuf_entries; /* 0x1e9 */
|
||||
__u8 edd_mbr_sig_buf_entries; /* 0x1ea */
|
||||
__u8 kbd_status; /* 0x1eb */
|
||||
__u8 _pad6[5]; /* 0x1ec */
|
||||
__u8 _pad5[3]; /* 0x1ec */
|
||||
/*
|
||||
* The sentinel is set to a nonzero value (0xff) in header.S.
|
||||
*
|
||||
* A bootloader is supposed to only take setup_header and put
|
||||
* it into a clean boot_params buffer. If it turns out that
|
||||
* it is clumsy or too generous with the buffer, it most
|
||||
* probably will pick up the sentinel variable too. The fact
|
||||
* that this variable then is still 0xff will let kernel
|
||||
* know that some variables in boot_params are invalid and
|
||||
* kernel should zero out certain portions of boot_params.
|
||||
*/
|
||||
__u8 sentinel; /* 0x1ef */
|
||||
__u8 _pad6[1]; /* 0x1f0 */
|
||||
struct setup_header hdr; /* setup header */ /* 0x1f1 */
|
||||
__u8 _pad7[0x290-0x1f1-sizeof(struct setup_header)];
|
||||
__u32 edd_mbr_sig_buffer[EDD_MBR_SIG_MAX]; /* 0x290 */
|
||||
|
@ -134,6 +163,6 @@ enum {
|
|||
X86_NR_SUBARCHS,
|
||||
};
|
||||
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
#endif /* _ASM_X86_BOOTPARAM_H */
|
||||
|
|
|
@ -949,7 +949,7 @@ void __init efi_enter_virtual_mode(void)
|
|||
*
|
||||
* Call EFI services through wrapper functions.
|
||||
*/
|
||||
efi.runtime_version = efi_systab.fw_revision;
|
||||
efi.runtime_version = efi_systab.hdr.revision;
|
||||
efi.get_time = virt_efi_get_time;
|
||||
efi.set_time = virt_efi_set_time;
|
||||
efi.get_wakeup_time = virt_efi_get_wakeup_time;
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
#include <asm/cacheflush.h>
|
||||
#include <asm/fixmap.h>
|
||||
|
||||
static pgd_t save_pgd __initdata;
|
||||
static pgd_t *save_pgd __initdata;
|
||||
static unsigned long efi_flags __initdata;
|
||||
|
||||
static void __init early_code_mapping_set_exec(int executable)
|
||||
|
@ -61,12 +61,20 @@ static void __init early_code_mapping_set_exec(int executable)
|
|||
void __init efi_call_phys_prelog(void)
|
||||
{
|
||||
unsigned long vaddress;
|
||||
int pgd;
|
||||
int n_pgds;
|
||||
|
||||
early_code_mapping_set_exec(1);
|
||||
local_irq_save(efi_flags);
|
||||
vaddress = (unsigned long)__va(0x0UL);
|
||||
save_pgd = *pgd_offset_k(0x0UL);
|
||||
set_pgd(pgd_offset_k(0x0UL), *pgd_offset_k(vaddress));
|
||||
|
||||
n_pgds = DIV_ROUND_UP((max_pfn << PAGE_SHIFT), PGDIR_SIZE);
|
||||
save_pgd = kmalloc(n_pgds * sizeof(pgd_t), GFP_KERNEL);
|
||||
|
||||
for (pgd = 0; pgd < n_pgds; pgd++) {
|
||||
save_pgd[pgd] = *pgd_offset_k(pgd * PGDIR_SIZE);
|
||||
vaddress = (unsigned long)__va(pgd * PGDIR_SIZE);
|
||||
set_pgd(pgd_offset_k(pgd * PGDIR_SIZE), *pgd_offset_k(vaddress));
|
||||
}
|
||||
__flush_tlb_all();
|
||||
}
|
||||
|
||||
|
@ -75,7 +83,11 @@ void __init efi_call_phys_epilog(void)
|
|||
/*
|
||||
* After the lock is released, the original page table is restored.
|
||||
*/
|
||||
set_pgd(pgd_offset_k(0x0UL), save_pgd);
|
||||
int pgd;
|
||||
int n_pgds = DIV_ROUND_UP((max_pfn << PAGE_SHIFT) , PGDIR_SIZE);
|
||||
for (pgd = 0; pgd < n_pgds; pgd++)
|
||||
set_pgd(pgd_offset_k(pgd * PGDIR_SIZE), save_pgd[pgd]);
|
||||
kfree(save_pgd);
|
||||
__flush_tlb_all();
|
||||
local_irq_restore(efi_flags);
|
||||
early_code_mapping_set_exec(0);
|
||||
|
|
|
@ -814,12 +814,14 @@ int main(int argc, char **argv)
|
|||
read_relocs(fp);
|
||||
if (show_absolute_syms) {
|
||||
print_absolute_symbols();
|
||||
return 0;
|
||||
goto out;
|
||||
}
|
||||
if (show_absolute_relocs) {
|
||||
print_absolute_relocs();
|
||||
return 0;
|
||||
goto out;
|
||||
}
|
||||
emit_relocs(as_text, use_real_mode);
|
||||
out:
|
||||
fclose(fp);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -674,7 +674,7 @@ static int efi_status_to_err(efi_status_t status)
|
|||
err = -EACCES;
|
||||
break;
|
||||
case EFI_NOT_FOUND:
|
||||
err = -ENOENT;
|
||||
err = -EIO;
|
||||
break;
|
||||
default:
|
||||
err = -EINVAL;
|
||||
|
@ -793,6 +793,7 @@ static ssize_t efivarfs_file_write(struct file *file,
|
|||
spin_unlock(&efivars->lock);
|
||||
efivar_unregister(var);
|
||||
drop_nlink(inode);
|
||||
d_delete(file->f_dentry);
|
||||
dput(file->f_dentry);
|
||||
|
||||
} else {
|
||||
|
@ -994,7 +995,7 @@ static int efivarfs_unlink(struct inode *dir, struct dentry *dentry)
|
|||
list_del(&var->list);
|
||||
spin_unlock(&efivars->lock);
|
||||
efivar_unregister(var);
|
||||
drop_nlink(dir);
|
||||
drop_nlink(dentry->d_inode);
|
||||
dput(dentry);
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue