diff options
author | Jarkko Sakkinen <jarkko.sakkinen@intel.com> | 2012-05-08 14:22:40 -0400 |
---|---|---|
committer | H. Peter Anvin <hpa@linux.intel.com> | 2012-05-08 14:48:11 -0400 |
commit | 8e029fcdd8702719c9179317cae9ef84ebe7027e (patch) | |
tree | 12140b7331764ff0e0cd4e0d7bd290453d51110f /arch/x86/realmode | |
parent | 6feb592dceaed1a6cf26c9747b1180958d5156cd (diff) |
x86, realmode: fix 64-bit wakeup sequence
There were number of issues in wakeup sequence:
- Wakeup stack was placed in hardcoded address.
- NX bit in EFER was not enabled.
- Initialization incorrectly set physical address
of secondary_startup_64.
- Some alignment issues.
This patch fixes these issues and in addition:
- Unifies coding conventions in .S files.
- Sets alignments of code and data right.
Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@intel.com>
Link: http://lkml.kernel.org/r/1336501366-28617-18-git-send-email-jarkko.sakkinen@intel.com
Originally-by: H. Peter Anvin <hpa@linux.intel.com>
Cc: Rafael J. Wysocki <rjw@sisk.pl>
Cc: Len Brown <len.brown@intel.com>
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
Diffstat (limited to 'arch/x86/realmode')
-rw-r--r-- | arch/x86/realmode/rm/Makefile | 1 | ||||
-rw-r--r-- | arch/x86/realmode/rm/header.S | 2 | ||||
-rw-r--r-- | arch/x86/realmode/rm/reboot_32.S | 18 | ||||
-rw-r--r-- | arch/x86/realmode/rm/stack.S | 19 | ||||
-rw-r--r-- | arch/x86/realmode/rm/trampoline_32.S | 29 | ||||
-rw-r--r-- | arch/x86/realmode/rm/trampoline_64.S | 67 | ||||
-rw-r--r-- | arch/x86/realmode/rm/wakeup/wakeup_asm.S | 75 | ||||
-rw-r--r-- | arch/x86/realmode/rmpiggy.S | 4 |
8 files changed, 109 insertions, 106 deletions
diff --git a/arch/x86/realmode/rm/Makefile b/arch/x86/realmode/rm/Makefile index 2423142b4da4..c2c27a41ab8f 100644 --- a/arch/x86/realmode/rm/Makefile +++ b/arch/x86/realmode/rm/Makefile | |||
@@ -13,6 +13,7 @@ always := realmode.bin | |||
13 | 13 | ||
14 | realmode-y += header.o | 14 | realmode-y += header.o |
15 | realmode-y += trampoline_$(BITS).o | 15 | realmode-y += trampoline_$(BITS).o |
16 | realmode-y += stack.o | ||
16 | realmode-$(CONFIG_X86_32) += reboot_32.o | 17 | realmode-$(CONFIG_X86_32) += reboot_32.o |
17 | realmode-$(CONFIG_ACPI_SLEEP) += wakeup/wakeup.o | 18 | realmode-$(CONFIG_ACPI_SLEEP) += wakeup/wakeup.o |
18 | 19 | ||
diff --git a/arch/x86/realmode/rm/header.S b/arch/x86/realmode/rm/header.S index 730b1316c099..a91ec8f6b15f 100644 --- a/arch/x86/realmode/rm/header.S +++ b/arch/x86/realmode/rm/header.S | |||
@@ -9,7 +9,7 @@ | |||
9 | 9 | ||
10 | .section ".header", "a" | 10 | .section ".header", "a" |
11 | 11 | ||
12 | ENTRY(real_mode_header) | 12 | GLOBAL(real_mode_header) |
13 | .long pa_text_start | 13 | .long pa_text_start |
14 | .long pa_ro_end | 14 | .long pa_ro_end |
15 | .long pa_end | 15 | .long pa_end |
diff --git a/arch/x86/realmode/rm/reboot_32.S b/arch/x86/realmode/rm/reboot_32.S index 50ba994ba921..8d9bfd13a93e 100644 --- a/arch/x86/realmode/rm/reboot_32.S +++ b/arch/x86/realmode/rm/reboot_32.S | |||
@@ -16,10 +16,9 @@ | |||
16 | */ | 16 | */ |
17 | .section ".text32", "ax" | 17 | .section ".text32", "ax" |
18 | .code32 | 18 | .code32 |
19 | .globl machine_real_restart_asm | ||
20 | 19 | ||
21 | .balign 16 | 20 | .balign 16 |
22 | machine_real_restart_asm: | 21 | ENTRY(machine_real_restart_asm) |
23 | /* Set up the IDT for real mode. */ | 22 | /* Set up the IDT for real mode. */ |
24 | lidtl pa_machine_real_restart_idt | 23 | lidtl pa_machine_real_restart_idt |
25 | 24 | ||
@@ -67,7 +66,7 @@ machine_real_restart_asm: | |||
67 | .text | 66 | .text |
68 | .code16 | 67 | .code16 |
69 | 68 | ||
70 | .balign 16 | 69 | .balign 16 |
71 | machine_real_restart_asm16: | 70 | machine_real_restart_asm16: |
72 | 1: | 71 | 1: |
73 | xorl %ecx, %ecx | 72 | xorl %ecx, %ecx |
@@ -102,15 +101,15 @@ bios: | |||
102 | ljmpw $0xf000, $0xfff0 | 101 | ljmpw $0xf000, $0xfff0 |
103 | 102 | ||
104 | .section ".rodata", "a" | 103 | .section ".rodata", "a" |
105 | .globl machine_real_restart_idt, machine_real_restart_gdt | ||
106 | 104 | ||
107 | .balign 16 | 105 | .balign 16 |
108 | machine_real_restart_idt: | 106 | GLOBAL(machine_real_restart_idt) |
109 | .word 0xffff /* Length - real mode default value */ | 107 | .word 0xffff /* Length - real mode default value */ |
110 | .long 0 /* Base - real mode default value */ | 108 | .long 0 /* Base - real mode default value */ |
109 | END(machine_real_restart_idt) | ||
111 | 110 | ||
112 | .balign 16 | 111 | .balign 16 |
113 | machine_real_restart_gdt: | 112 | GLOBAL(machine_real_restart_gdt) |
114 | /* Self-pointer */ | 113 | /* Self-pointer */ |
115 | .word 0xffff /* Length - real mode default value */ | 114 | .word 0xffff /* Length - real mode default value */ |
116 | .long pa_machine_real_restart_gdt | 115 | .long pa_machine_real_restart_gdt |
@@ -130,3 +129,4 @@ machine_real_restart_gdt: | |||
130 | * semantics we don't have to reload the segments once CR0.PE = 0. | 129 | * semantics we don't have to reload the segments once CR0.PE = 0. |
131 | */ | 130 | */ |
132 | .quad GDT_ENTRY(0x0093, 0x100, 0xffff) | 131 | .quad GDT_ENTRY(0x0093, 0x100, 0xffff) |
132 | END(machine_real_restart_gdt) | ||
diff --git a/arch/x86/realmode/rm/stack.S b/arch/x86/realmode/rm/stack.S new file mode 100644 index 000000000000..867ae87adfae --- /dev/null +++ b/arch/x86/realmode/rm/stack.S | |||
@@ -0,0 +1,19 @@ | |||
1 | /* | ||
2 | * Common heap and stack allocations | ||
3 | */ | ||
4 | |||
5 | #include <linux/linkage.h> | ||
6 | |||
7 | .data | ||
8 | GLOBAL(HEAP) | ||
9 | .long rm_heap | ||
10 | GLOBAL(heap_end) | ||
11 | .long rm_stack | ||
12 | |||
13 | .bss | ||
14 | .balign 16 | ||
15 | GLOBAL(rm_heap) | ||
16 | .space 2048 | ||
17 | GLOBAL(rm_stack) | ||
18 | .space 2048 | ||
19 | GLOBAL(rm_stack_end) | ||
diff --git a/arch/x86/realmode/rm/trampoline_32.S b/arch/x86/realmode/rm/trampoline_32.S index 279f82ef7a9e..1ecdbb59191b 100644 --- a/arch/x86/realmode/rm/trampoline_32.S +++ b/arch/x86/realmode/rm/trampoline_32.S | |||
@@ -33,10 +33,9 @@ | |||
33 | 33 | ||
34 | .text | 34 | .text |
35 | .code16 | 35 | .code16 |
36 | .globl trampoline_data | ||
37 | 36 | ||
38 | .balign PAGE_SIZE | 37 | .balign PAGE_SIZE |
39 | trampoline_data: | 38 | ENTRY(trampoline_data) |
40 | wbinvd # Needed for NUMA-Q should be harmless for others | 39 | wbinvd # Needed for NUMA-Q should be harmless for others |
41 | 40 | ||
42 | LJMPW_RM(1f) | 41 | LJMPW_RM(1f) |
@@ -70,20 +69,22 @@ trampoline_data: | |||
70 | ENTRY(startup_32) # note: also used from wakeup_asm.S | 69 | ENTRY(startup_32) # note: also used from wakeup_asm.S |
71 | jmp *%eax | 70 | jmp *%eax |
72 | 71 | ||
73 | .data | 72 | .section ".rodata","a" |
74 | .globl startup_32_smp, boot_gdt, trampoline_status | ||
75 | .balign 4 | ||
76 | boot_gdt_descr: | ||
77 | .word __BOOT_DS + 7 # gdt limit | ||
78 | boot_gdt: | ||
79 | .long 0 # gdt base | ||
80 | 73 | ||
74 | .balign 4 | ||
81 | boot_idt_descr: | 75 | boot_idt_descr: |
82 | .word 0 # idt limit = 0 | 76 | .word 0 # idt limit = 0 |
83 | .long 0 # idt base = 0L | 77 | .long 0 # idt base = 0L |
84 | 78 | ||
85 | trampoline_status: | 79 | .data |
86 | .long 0 | ||
87 | 80 | ||
88 | startup_32_smp: | 81 | boot_gdt_descr: |
89 | .long 0 | 82 | .word __BOOT_DS + 7 # gdt limit |
83 | GLOBAL(boot_gdt) | ||
84 | .long 0 # gdt base | ||
85 | |||
86 | .bss | ||
87 | |||
88 | .balign 4 | ||
89 | GLOBAL(trampoline_status) .space 4 | ||
90 | GLOBAL(startup_32_smp) .space 4 | ||
diff --git a/arch/x86/realmode/rm/trampoline_64.S b/arch/x86/realmode/rm/trampoline_64.S index 7459c52f0c25..f71ea0800d3d 100644 --- a/arch/x86/realmode/rm/trampoline_64.S +++ b/arch/x86/realmode/rm/trampoline_64.S | |||
@@ -52,7 +52,7 @@ ENTRY(trampoline_data) | |||
52 | # write marker for master knows we're running | 52 | # write marker for master knows we're running |
53 | 53 | ||
54 | # Setup stack | 54 | # Setup stack |
55 | movw $trampoline_stack_end, %sp | 55 | movl $rm_stack_end, %esp |
56 | 56 | ||
57 | call verify_cpu # Verify the cpu supports long mode | 57 | call verify_cpu # Verify the cpu supports long mode |
58 | testl %eax, %eax # Check for return code | 58 | testl %eax, %eax # Check for return code |
@@ -68,8 +68,11 @@ ENTRY(trampoline_data) | |||
68 | lidtl tidt # load idt with 0, 0 | 68 | lidtl tidt # load idt with 0, 0 |
69 | lgdtl tgdt # load gdt with whatever is appropriate | 69 | lgdtl tgdt # load gdt with whatever is appropriate |
70 | 70 | ||
71 | mov $X86_CR0_PE, %ax # protected mode (PE) bit | 71 | movw $__KERNEL_DS, %dx # Data segment descriptor |
72 | lmsw %ax # into protected mode | 72 | |
73 | # Enable protected mode | ||
74 | movl $X86_CR0_PE, %eax # protected mode (PE) bit | ||
75 | movl %eax, %cr0 # into protected mode | ||
73 | 76 | ||
74 | # flush prefetch and jump to startup_32 | 77 | # flush prefetch and jump to startup_32 |
75 | ljmpl $__KERNEL32_CS, $pa_startup_32 | 78 | ljmpl $__KERNEL32_CS, $pa_startup_32 |
@@ -83,27 +86,27 @@ no_longmode: | |||
83 | .code32 | 86 | .code32 |
84 | .balign 4 | 87 | .balign 4 |
85 | ENTRY(startup_32) | 88 | ENTRY(startup_32) |
86 | movl $__KERNEL_DS, %eax # Initialize the %ds segment register | 89 | movl %edx, %ss |
87 | movl %eax, %ds | 90 | addl $pa_real_mode_base, %esp |
91 | movl %edx, %ds | ||
92 | movl %edx, %es | ||
93 | movl %edx, %fs | ||
94 | movl %edx, %gs | ||
88 | 95 | ||
89 | movl $X86_CR4_PAE, %eax | 96 | movl $X86_CR4_PAE, %eax |
90 | movl %eax, %cr4 # Enable PAE mode | 97 | movl %eax, %cr4 # Enable PAE mode |
91 | 98 | ||
92 | movl pa_startup_64_smp, %esi | 99 | # Setup trampoline 4 level pagetables |
93 | movl pa_startup_64_smp_high, %edi | 100 | movl $pa_level3_ident_pgt, %eax |
94 | |||
95 | # Setup trampoline 4 level pagetables | ||
96 | leal pa_trampoline_level4_pgt, %eax | ||
97 | movl %eax, %cr3 | 101 | movl %eax, %cr3 |
98 | 102 | ||
99 | movl $MSR_EFER, %ecx | 103 | movl $MSR_EFER, %ecx |
100 | movl $(1 << _EFER_LME), %eax # Enable Long Mode | 104 | movl $((1 << _EFER_LME) | (1 << _EFER_NX)), %eax # Enable Long Mode |
101 | xorl %edx, %edx | 105 | xorl %edx, %edx |
102 | wrmsr | 106 | wrmsr |
103 | 107 | ||
104 | # Enable paging and in turn activate Long Mode | 108 | # Enable paging and in turn activate Long Mode |
105 | # Enable protected mode | 109 | movl $(X86_CR0_PG | X86_CR0_WP | X86_CR0_PE), %eax |
106 | movl $(X86_CR0_PG | X86_CR0_PE), %eax | ||
107 | movl %eax, %cr0 | 110 | movl %eax, %cr0 |
108 | 111 | ||
109 | /* | 112 | /* |
@@ -119,10 +122,7 @@ ENTRY(startup_32) | |||
119 | .balign 4 | 122 | .balign 4 |
120 | ENTRY(startup_64) | 123 | ENTRY(startup_64) |
121 | # Now jump into the kernel using virtual addresses | 124 | # Now jump into the kernel using virtual addresses |
122 | movl %edi, %eax | 125 | jmpq *startup_64_smp(%rip) |
123 | shlq $32, %rax | ||
124 | addl %esi, %eax | ||
125 | jmp *%rax | ||
126 | 126 | ||
127 | .section ".rodata","a" | 127 | .section ".rodata","a" |
128 | .balign 16 | 128 | .balign 16 |
@@ -132,10 +132,10 @@ tidt: | |||
132 | 132 | ||
133 | # Duplicate the global descriptor table | 133 | # Duplicate the global descriptor table |
134 | # so the kernel can live anywhere | 134 | # so the kernel can live anywhere |
135 | .balign 4 | 135 | .balign 16 |
136 | .globl tgdt | 136 | .globl tgdt |
137 | tgdt: | 137 | tgdt: |
138 | .short tgdt_end - tgdt # gdt limit | 138 | .short tgdt_end - tgdt - 1 # gdt limit |
139 | .long pa_tgdt | 139 | .long pa_tgdt |
140 | .short 0 | 140 | .short 0 |
141 | .quad 0x00cf9b000000ffff # __KERNEL32_CS | 141 | .quad 0x00cf9b000000ffff # __KERNEL32_CS |
@@ -143,23 +143,12 @@ tgdt: | |||
143 | .quad 0x00cf93000000ffff # __KERNEL_DS | 143 | .quad 0x00cf93000000ffff # __KERNEL_DS |
144 | tgdt_end: | 144 | tgdt_end: |
145 | 145 | ||
146 | .data | 146 | .bss |
147 | .balign 4 | 147 | |
148 | GLOBAL(trampoline_status) | 148 | .balign PAGE_SIZE |
149 | .long 0 | 149 | GLOBAL(level3_ident_pgt) .space 511*8 |
150 | 150 | GLOBAL(level3_kernel_pgt) .space 8 | |
151 | trampoline_stack: | 151 | |
152 | .org 0x1000 | 152 | .balign 8 |
153 | trampoline_stack_end: | 153 | GLOBAL(startup_64_smp) .space 8 |
154 | 154 | GLOBAL(trampoline_status) .space 4 | |
155 | .globl level3_ident_pgt | ||
156 | .globl level3_kernel_pgt | ||
157 | GLOBAL(trampoline_level4_pgt) | ||
158 | level3_ident_pgt: .quad 0 | ||
159 | .fill 510,8,0 | ||
160 | level3_kernel_pgt: .quad 0 | ||
161 | |||
162 | .globl startup_64_smp | ||
163 | .globl startup_64_smp_high | ||
164 | startup_64_smp: .long 0 | ||
165 | startup_64_smp_high: .long 0 | ||
diff --git a/arch/x86/realmode/rm/wakeup/wakeup_asm.S b/arch/x86/realmode/rm/wakeup/wakeup_asm.S index 8064e1c3591b..f81c1cd99eaf 100644 --- a/arch/x86/realmode/rm/wakeup/wakeup_asm.S +++ b/arch/x86/realmode/rm/wakeup/wakeup_asm.S | |||
@@ -1,6 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * ACPI wakeup real mode startup stub | 2 | * ACPI wakeup real mode startup stub |
3 | */ | 3 | */ |
4 | #include <linux/linkage.h> | ||
4 | #include <asm/segment.h> | 5 | #include <asm/segment.h> |
5 | #include <asm/msr-index.h> | 6 | #include <asm/msr-index.h> |
6 | #include <asm/page_types.h> | 7 | #include <asm/page_types.h> |
@@ -9,31 +10,33 @@ | |||
9 | #include "../realmode.h" | 10 | #include "../realmode.h" |
10 | #include "wakeup.h" | 11 | #include "wakeup.h" |
11 | 12 | ||
12 | .code16 | 13 | .code16 |
13 | 14 | ||
14 | /* This should match the structure in wakeup.h */ | 15 | /* This should match the structure in wakeup.h */ |
15 | .section ".data", "aw" | 16 | .section ".data", "aw" |
16 | .globl wakeup_header | 17 | |
17 | wakeup_header: | 18 | .balign 16 |
18 | video_mode: .short 0 /* Video mode number */ | 19 | GLOBAL(wakeup_header) |
19 | pmode_entry: .long 0 | 20 | video_mode: .short 0 /* Video mode number */ |
20 | pmode_cs: .short __KERNEL_CS | 21 | pmode_entry: .long 0 |
21 | pmode_cr0: .long 0 /* Saved %cr0 */ | 22 | pmode_cs: .short __KERNEL_CS |
22 | pmode_cr3: .long 0 /* Saved %cr3 */ | 23 | pmode_cr0: .long 0 /* Saved %cr0 */ |
23 | pmode_cr4: .long 0 /* Saved %cr4 */ | 24 | pmode_cr3: .long 0 /* Saved %cr3 */ |
24 | pmode_efer: .quad 0 /* Saved EFER */ | 25 | pmode_cr4: .long 0 /* Saved %cr4 */ |
25 | pmode_gdt: .quad 0 | 26 | pmode_efer: .quad 0 /* Saved EFER */ |
26 | pmode_misc_en: .quad 0 /* Saved MISC_ENABLE MSR */ | 27 | pmode_gdt: .quad 0 |
27 | pmode_behavior: .long 0 /* Wakeup behavior flags */ | 28 | pmode_misc_en: .quad 0 /* Saved MISC_ENABLE MSR */ |
28 | realmode_flags: .long 0 | 29 | pmode_behavior: .long 0 /* Wakeup behavior flags */ |
29 | real_magic: .long 0 | 30 | realmode_flags: .long 0 |
30 | signature: .long WAKEUP_HEADER_SIGNATURE | 31 | real_magic: .long 0 |
31 | .size wakeup_header, .-wakeup_header | 32 | signature: .long WAKEUP_HEADER_SIGNATURE |
33 | END(wakeup_header) | ||
32 | 34 | ||
33 | .text | 35 | .text |
34 | .code16 | 36 | .code16 |
35 | .globl wakeup_start | 37 | |
36 | wakeup_start: | 38 | .balign 16 |
39 | ENTRY(wakeup_start) | ||
37 | cli | 40 | cli |
38 | cld | 41 | cld |
39 | 42 | ||
@@ -62,12 +65,14 @@ wakeup_start: | |||
62 | 3: | 65 | 3: |
63 | /* Set up segments */ | 66 | /* Set up segments */ |
64 | movw %cs, %ax | 67 | movw %cs, %ax |
68 | movw %ax, %ss | ||
69 | movl $rm_stack_end, %esp | ||
65 | movw %ax, %ds | 70 | movw %ax, %ds |
66 | movw %ax, %es | 71 | movw %ax, %es |
67 | movw %ax, %ss | 72 | movw %ax, %fs |
68 | lidtl wakeup_idt | 73 | movw %ax, %gs |
69 | 74 | ||
70 | movl $wakeup_stack_end, %esp | 75 | lidtl wakeup_idt |
71 | 76 | ||
72 | /* Clear the EFLAGS */ | 77 | /* Clear the EFLAGS */ |
73 | pushl $0 | 78 | pushl $0 |
@@ -145,9 +150,8 @@ bogus_real_magic: | |||
145 | * be the case for other laptops or integrated video devices. | 150 | * be the case for other laptops or integrated video devices. |
146 | */ | 151 | */ |
147 | 152 | ||
148 | .globl wakeup_gdt | ||
149 | .balign 16 | 153 | .balign 16 |
150 | wakeup_gdt: | 154 | GLOBAL(wakeup_gdt) |
151 | .word 3*8-1 /* Self-descriptor */ | 155 | .word 3*8-1 /* Self-descriptor */ |
152 | .long pa_wakeup_gdt | 156 | .long pa_wakeup_gdt |
153 | .word 0 | 157 | .word 0 |
@@ -159,29 +163,18 @@ wakeup_gdt: | |||
159 | .word 0xffff /* 16-bit data segment @ real_mode_base */ | 163 | .word 0xffff /* 16-bit data segment @ real_mode_base */ |
160 | .long 0x93000000 + pa_real_mode_base | 164 | .long 0x93000000 + pa_real_mode_base |
161 | .word 0x008f /* big real mode */ | 165 | .word 0x008f /* big real mode */ |
162 | .size wakeup_gdt, .-wakeup_gdt | 166 | END(wakeup_gdt) |
163 | 167 | ||
164 | .data | 168 | .section ".rodata","a" |
165 | .balign 8 | 169 | .balign 8 |
166 | 170 | ||
167 | /* This is the standard real-mode IDT */ | 171 | /* This is the standard real-mode IDT */ |
168 | wakeup_idt: | 172 | .balign 16 |
173 | GLOBAL(wakeup_idt) | ||
169 | .word 0xffff /* limit */ | 174 | .word 0xffff /* limit */ |
170 | .long 0 /* address */ | 175 | .long 0 /* address */ |
171 | .word 0 | 176 | .word 0 |
172 | 177 | END(wakeup_idt) | |
173 | .globl HEAP, heap_end | ||
174 | HEAP: | ||
175 | .long wakeup_heap | ||
176 | heap_end: | ||
177 | .long wakeup_stack | ||
178 | |||
179 | .bss | ||
180 | wakeup_heap: | ||
181 | .space 2048 | ||
182 | wakeup_stack: | ||
183 | .space 2048 | ||
184 | wakeup_stack_end: | ||
185 | 178 | ||
186 | .section ".signature","a" | 179 | .section ".signature","a" |
187 | end_signature: | 180 | end_signature: |
diff --git a/arch/x86/realmode/rmpiggy.S b/arch/x86/realmode/rmpiggy.S index 6047d7f604cf..fd72a99d12ae 100644 --- a/arch/x86/realmode/rmpiggy.S +++ b/arch/x86/realmode/rmpiggy.S | |||
@@ -9,10 +9,10 @@ | |||
9 | 9 | ||
10 | .balign PAGE_SIZE | 10 | .balign PAGE_SIZE |
11 | 11 | ||
12 | ENTRY(real_mode_blob) | 12 | GLOBAL(real_mode_blob) |
13 | .incbin "arch/x86/realmode/rm/realmode.bin" | 13 | .incbin "arch/x86/realmode/rm/realmode.bin" |
14 | END(real_mode_blob) | 14 | END(real_mode_blob) |
15 | 15 | ||
16 | ENTRY(real_mode_relocs) | 16 | GLOBAL(real_mode_relocs) |
17 | .incbin "arch/x86/realmode/rm/realmode.relocs" | 17 | .incbin "arch/x86/realmode/rm/realmode.relocs" |
18 | END(real_mode_relocs) | 18 | END(real_mode_relocs) |