Browse Source

Towards making KEEP_IT_REAL work again.

Fix bug that caused over-allocation of .text16 and .data16 memory areas
by a factor of 16.
tags/v0.9.3
Michael Brown 18 years ago
parent
commit
6abfaa153b

+ 9
- 0
src/arch/i386/include/libkir.h View File

213
 #define BASEMEM_PARAMETER_INIT BASEMEM_PARAMETER_INIT_LIBKIR
213
 #define BASEMEM_PARAMETER_INIT BASEMEM_PARAMETER_INIT_LIBKIR
214
 #define BASEMEM_PARAMETER_DONE BASEMEM_PARAMETER_DONE_LIBKIR
214
 #define BASEMEM_PARAMETER_DONE BASEMEM_PARAMETER_DONE_LIBKIR
215
 
215
 
216
+/* TEXT16_CODE: declare a fragment of code that resides in .text16 */
217
+#define TEXT16_CODE( asm_code_str )			\
218
+	".section \".text16\", \"ax\", @progbits\n\t"	\
219
+	".code16\n\t"					\
220
+	".arch i386\n\t"				\
221
+	asm_code_str "\n\t"				\
222
+	".code16gcc\n\t"				\
223
+	".previous\n\t"
224
+
216
 /* REAL_CODE: declare a fragment of code that executes in real mode */
225
 /* REAL_CODE: declare a fragment of code that executes in real mode */
217
 #define REAL_CODE( asm_code_str )	\
226
 #define REAL_CODE( asm_code_str )	\
218
 	".code16\n\t"			\
227
 	".code16\n\t"			\

+ 12
- 7
src/arch/i386/include/librm.h View File

177
 #define BASEMEM_PARAMETER_INIT BASEMEM_PARAMETER_INIT_LIBRM
177
 #define BASEMEM_PARAMETER_INIT BASEMEM_PARAMETER_INIT_LIBRM
178
 #define BASEMEM_PARAMETER_DONE BASEMEM_PARAMETER_DONE_LIBRM
178
 #define BASEMEM_PARAMETER_DONE BASEMEM_PARAMETER_DONE_LIBRM
179
 
179
 
180
-/* REAL_CODE: declare a fragment of code that executes in real mode */
181
-#define REAL_CODE( asm_code_str )			\
182
-	"pushl $1f\n\t"					\
183
-	"call real_call\n\t"				\
184
-	"addl $4, %%esp\n\t"				\
180
+/* TEXT16_CODE: declare a fragment of code that resides in .text16 */
181
+#define TEXT16_CODE( asm_code_str )			\
185
 	".section \".text16\", \"ax\", @progbits\n\t"	\
182
 	".section \".text16\", \"ax\", @progbits\n\t"	\
186
 	".code16\n\t"					\
183
 	".code16\n\t"					\
187
 	".arch i386\n\t"				\
184
 	".arch i386\n\t"				\
188
-	"\n1:\n\t"					\
189
 	asm_code_str "\n\t"				\
185
 	asm_code_str "\n\t"				\
190
-	"ret\n\t"					\
191
 	".code32\n\t"					\
186
 	".code32\n\t"					\
192
 	".previous\n\t"
187
 	".previous\n\t"
193
 
188
 
189
+/* REAL_CODE: declare a fragment of code that executes in real mode */
190
+#define REAL_CODE( asm_code_str )			\
191
+	"pushl $1f\n\t"					\
192
+	"call real_call\n\t"				\
193
+	"addl $4, %%esp\n\t"				\
194
+	TEXT16_CODE ( "\n1:\n\t"			\
195
+		      asm_code_str			\
196
+		      "\n\t"				\
197
+		      "ret\n\t" )
198
+
194
 #endif /* ASSEMBLY */
199
 #endif /* ASSEMBLY */
195
 
200
 
196
 #endif /* LIBRM_H */
201
 #endif /* LIBRM_H */

+ 2
- 5
src/arch/i386/kir-Makefile View File

21
 #
21
 #
22
 CFLAGS		+= -DKEEP_IT_REAL -include kir.h
22
 CFLAGS		+= -DKEEP_IT_REAL -include kir.h
23
 
23
 
24
-# Link with _data_link_addr = 0; data symbols are relative to the data
25
-# segment.
26
-#
27
-LDFLAGS		+= --defsym _data_link_addr=0
28
-
29
 include Makefile
24
 include Makefile
25
+
26
+LDSCRIPT	= arch/i386/scripts/i386-kir.lds

+ 16
- 4
src/arch/i386/prefix/libprefix.S View File

99
 	shlw	$6, %ax
99
 	shlw	$6, %ax
100
 
100
 
101
 	/* .data16 segment address */
101
 	/* .data16 segment address */
102
-	subw	$_data16_size, %ax
102
+	subw	$_data16_size_pgh, %ax
103
 	pushw	%ax
103
 	pushw	%ax
104
 
104
 
105
 	/* .text16 segment address */
105
 	/* .text16 segment address */
106
-	subw	$_text16_size, %ax
106
+	subw	$_text16_size_pgh, %ax
107
 	pushw	%ax
107
 	pushw	%ax
108
 
108
 
109
 	/* Update FBMS */
109
 	/* Update FBMS */
322
 	/* Install .text16 and .data16 */
322
 	/* Install .text16 and .data16 */
323
 	call	install_basemem
323
 	call	install_basemem
324
 
324
 
325
-#ifndef KEEP_IT_REAL
325
+#ifdef KEEP_IT_REAL
326
+	/* Preserve %ds, call init_libkir, restore registers */
327
+	pushw	%ds
328
+	movw	%bx, %ds
329
+	movw	%ax, (init_libkir_vector+2)
330
+	lcall	*init_libkir_vector
331
+	popw	%ds
332
+#else
326
 	/* Preserve registers and interrupt status, and disable interrupts */
333
 	/* Preserve registers and interrupt status, and disable interrupts */
327
 	pushfw
334
 	pushfw
328
 	pushw	%ds
335
 	pushw	%ds
379
 	ret
386
 	ret
380
 	.size install_prealloc, . - install_prealloc
387
 	.size install_prealloc, . - install_prealloc
381
 
388
 
382
-#ifndef KEEP_IT_REAL
383
 	/* Vectors for far calls to .text16 functions */
389
 	/* Vectors for far calls to .text16 functions */
384
 	.section ".data16"
390
 	.section ".data16"
391
+#ifdef KEEP_IT_REAL
392
+init_libkir_vector:
393
+	.word init_libkir
394
+	.word 0
395
+	.size init_libkir_vector, . - init_libkir_vector
396
+#else
385
 init_librm_vector:
397
 init_librm_vector:
386
 	.word init_librm
398
 	.word init_librm
387
 	.word 0
399
 	.word 0

+ 192
- 0
src/arch/i386/scripts/i386-kir.lds View File

1
+/* -*- sh -*- */
2
+
3
+/*
4
+ * Linker script for i386 images
5
+ *
6
+ */
7
+
8
+OUTPUT_FORMAT ( "elf32-i386", "elf32-i386", "elf32-i386" )
9
+OUTPUT_ARCH ( i386 )
10
+ENTRY ( _entry )
11
+
12
+SECTIONS {
13
+
14
+    /* All sections in the resulting file have consecutive load
15
+     * addresses, but may have individual link addresses depending on
16
+     * the memory model being used.
17
+     *
18
+     * The linker symbols _prefix_link_addr, load_addr, and
19
+     * _max_align may be specified explicitly.  If not specified, they
20
+     * will default to:
21
+     *
22
+     *   _prefix_link_addr	= 0
23
+     *   _load_addr		= 0
24
+     *   _max_align		= 16
25
+     * 
26
+     * We guarantee alignment of virtual addresses to any alignment
27
+     * specified by the constituent object files (e.g. via
28
+     * __attribute__((aligned(x)))).  Load addresses are guaranteed
29
+     * only up to _max_align.  Provided that all loader and relocation
30
+     * code honours _max_align, this means that physical addresses are
31
+     * also guaranteed up to _max_align.
32
+     *
33
+     * Note that when using -DKEEP_IT_REAL, the UNDI segments are only
34
+     * guaranteed to be loaded on a paragraph boundary (i.e. 16-byte
35
+     * alignment).  Using _max_align>16 will therefore not guarantee
36
+     * >16-byte alignment of physical addresses when -DKEEP_IT_REAL is
37
+     * used (though virtual addresses will still be fully aligned).
38
+     *
39
+     */
40
+
41
+    /*
42
+     * The prefix
43
+     */
44
+
45
+    _prefix_link_addr = DEFINED ( _prefix_link_addr ) ? _prefix_link_addr : 0;
46
+    . = _prefix_link_addr;
47
+    _prefix = .;
48
+
49
+    .prefix : AT ( _prefix_load_offset + __prefix ) {
50
+	__prefix = .;
51
+	_entry = .;
52
+	*(.prefix)
53
+	*(.prefix.*)
54
+	_eprefix_progbits = .;
55
+    }
56
+    
57
+    _eprefix = .;
58
+
59
+    /*
60
+     * The 16-bit sections
61
+     */
62
+
63
+    _text16_link_addr = 0;
64
+    . = _text16_link_addr;
65
+    _text16 = .;
66
+
67
+    .text16 : AT ( _text16_load_offset + __text16 ) {
68
+	__text16 = .;
69
+	*(.text.null_trap)
70
+	*(.text16)
71
+	*(.text16.*)
72
+	*(.text)
73
+	*(.text.*)
74
+	_etext16_progbits = .;
75
+    } = 0x9090
76
+
77
+    _etext16 = .;
78
+
79
+    _data16_link_addr = 0;
80
+    . = _data16_link_addr;
81
+    _data16 = .;
82
+
83
+    .rodata16 : AT ( _data16_load_offset + __rodata16 ) {
84
+	__rodata16 = .;
85
+	*(.rodata16)
86
+	*(.rodata16.*)
87
+	*(.rodata)
88
+	*(.rodata.*)
89
+    }
90
+    .data16 : AT ( _data16_load_offset + __data16 ) {
91
+	__data16 = .;
92
+	*(.data16)
93
+	*(.data16.*)
94
+	*(.data)
95
+	*(.data.*)
96
+	*(SORT(.tbl.*))		/* Various tables.  See include/tables.h */
97
+	_edata16_progbits = .;
98
+    }
99
+    .bss16 : AT ( _data16_load_offset + __bss16 ) {
100
+	__bss16 = .;
101
+	_bss16 = .;
102
+	*(.bss16)
103
+	*(.bss16.*)
104
+	*(.bss)
105
+	*(.bss.*)
106
+	*(COMMON)
107
+	_ebss16 = .;
108
+    }
109
+    .stack16 : AT ( _data16_load_offset + __stack16 ) {
110
+	__stack16 = .;
111
+	*(.stack16)
112
+	*(.stack16.*)
113
+	*(.stack)
114
+	*(.stack.*)
115
+    }
116
+
117
+    _edata16 = .;
118
+
119
+    _end = .;
120
+
121
+    /*
122
+     * Dispose of the comment and note sections to make the link map
123
+     * easier to read
124
+     */
125
+
126
+    /DISCARD/ : {
127
+	*(.comment)
128
+	*(.note)
129
+    }
130
+
131
+    /*
132
+     * Load address calculations.  The slightly obscure nature of the
133
+     * calculations is because ALIGN(x) can only operate on the
134
+     * location counter.
135
+     */
136
+
137
+    _max_align		    = DEFINED ( _max_align ) ? _max_align : 16;
138
+    _load_addr		    = DEFINED ( _load_addr ) ? _load_addr : 0;
139
+
140
+    .			    = _load_addr;
141
+
142
+    .			   -= _prefix_link_addr;
143
+    _prefix_load_offset	    = ALIGN ( _max_align );
144
+    _prefix_load_addr	    = _prefix_link_addr + _prefix_load_offset;
145
+    _prefix_size	    = _eprefix - _prefix;
146
+    _prefix_progbits_size   = _eprefix_progbits - _prefix;
147
+    .			    = _prefix_load_addr + _prefix_progbits_size;
148
+
149
+    .			   -= _text16_link_addr;
150
+    _text16_load_offset	    = ALIGN ( _max_align );
151
+    _text16_load_addr	    = _text16_link_addr + _text16_load_offset;
152
+    _text16_size	    = _etext16 - _text16;
153
+    _text16_progbits_size   = _etext16_progbits - _text16;
154
+    .			    = _text16_load_addr + _text16_progbits_size;
155
+
156
+    .			   -= _data16_link_addr;
157
+    _data16_load_offset	    = ALIGN ( _max_align );
158
+    _data16_load_addr	    = _data16_link_addr + _data16_load_offset;
159
+    _data16_size	    = _edata16 - _data16;
160
+    _data16_progbits_size   = _edata16_progbits - _data16;
161
+    .			    = _data16_load_addr + _data16_progbits_size;
162
+
163
+    .			    = ALIGN ( _max_align );
164
+
165
+    _load_size		    = . - _load_addr;
166
+
167
+    /*
168
+     * Alignment checks.  ALIGN() can only operate on the location
169
+     * counter, so we set the location counter to each value we want
170
+     * to check.
171
+     */
172
+
173
+    . = _prefix_load_addr - _prefix_link_addr;
174
+    _assert = ASSERT ( ( . == ALIGN ( _max_align ) ),
175
+		       "_prefix is badly aligned" );
176
+
177
+    . = _text16_load_addr - _text16_link_addr;
178
+    _assert = ASSERT ( ( . == ALIGN ( _max_align ) ),
179
+		       "_text16 is badly aligned" );
180
+
181
+    . = _data16_load_addr - _data16_link_addr;
182
+    _assert = ASSERT ( ( . == ALIGN ( _max_align ) ),
183
+		       "_data16 is badly aligned" );
184
+
185
+    /*
186
+     * Values calculated to save code from doing it
187
+     */
188
+    _text16_size_pgh	= ( ( _text16_size + 15 ) / 16 );
189
+    _data16_size_pgh	= ( ( _data16_size + 15 ) / 16 );
190
+    _load_size_pgh	= ( ( _load_size + 15 ) / 16 );
191
+    _rom_size		= ( ( _load_size + 511 ) / 512 );
192
+}

+ 4
- 2
src/arch/i386/scripts/i386.lds View File

15
      * addresses, but may have individual link addresses depending on
15
      * addresses, but may have individual link addresses depending on
16
      * the memory model being used.
16
      * the memory model being used.
17
      *
17
      *
18
-     * The linker symbols {prefix,text}_link_addr, load_addr, and
18
+     * The linker symbols _{prefix,textdata}_link_addr, load_addr, and
19
      * _max_align may be specified explicitly.  If not specified, they
19
      * _max_align may be specified explicitly.  If not specified, they
20
      * will default to:
20
      * will default to:
21
      *
21
      *
236
     /*
236
     /*
237
      * Values calculated to save code from doing it
237
      * Values calculated to save code from doing it
238
      */
238
      */
239
-    _load_size_pgh	= ( _load_size / 16 );
239
+    _text16_size_pgh	= ( ( _text16_size + 15 ) / 16 );
240
+    _data16_size_pgh	= ( ( _data16_size + 15 ) / 16 );
241
+    _load_size_pgh	= ( ( _load_size + 15 ) / 16 );
240
     _rom_size		= ( ( _load_size + 511 ) / 512 );
242
     _rom_size		= ( ( _load_size + 511 ) / 512 );
241
 }
243
 }

+ 26
- 15
src/arch/i386/transitions/libkir.S View File

34
 	.section ".text16", "awx", @progbits
34
 	.section ".text16", "awx", @progbits
35
 	.code16
35
 	.code16
36
 	
36
 	
37
+/****************************************************************************
38
+ * init_libkir (real-mode or 16:xx protected-mode far call)
39
+ *
40
+ * Initialise libkir ready for transitions to the kir environment
41
+ *
42
+ * Parameters:
43
+ *   %cs : .text16 segment
44
+ *   %ds : .data16 segment
45
+ ****************************************************************************
46
+ */
47
+	.globl	init_libkir
48
+init_libkir:
49
+	/* Record segment registers */
50
+	pushw	%ds
51
+	popw	%cs:kir_ds
52
+	lret
53
+	
37
 /****************************************************************************
54
 /****************************************************************************
38
  * ext_to_kir (real-mode or 16:xx protected-mode near call)
55
  * ext_to_kir (real-mode or 16:xx protected-mode near call)
39
  *
56
  *
45
  * %cs:0000 must point to the start of the runtime image code segment
62
  * %cs:0000 must point to the start of the runtime image code segment
46
  * on entry.
63
  * on entry.
47
  *
64
  *
48
- * Note that this routine can be called *without* having first set up
49
- * a stored kir_ds and kir_sp.  If you do this, ext_to_kir will return
50
- * without altering the segment registers or stack pointer.
51
- *
52
  * Parameters: none
65
  * Parameters: none
53
  ****************************************************************************
66
  ****************************************************************************
54
  */
67
  */
73
 	movw	%ss, %ds:ext_ss
86
 	movw	%ss, %ds:ext_ss
74
 	movl	%esp, %ds:ext_esp
87
 	movl	%esp, %ds:ext_esp
75
 
88
 
76
-	/* Load internal segment registers and stack pointer, if available */
89
+	/* Load internal segment registers and stack pointer */
77
 	movw	%ds:kir_ds, %ax
90
 	movw	%ds:kir_ds, %ax
78
-	testw	%ax, %ax
79
-	jz	1f
80
 	movw	%ax, %ss
91
 	movw	%ax, %ss
81
 	movzwl	%ds:kir_sp, %esp
92
 	movzwl	%ds:kir_sp, %esp
82
 	movw	%ax, %ds
93
 	movw	%ax, %ds
144
  * will also be preserved.
155
  * will also be preserved.
145
  *
156
  *
146
  * Parameters:
157
  * Parameters:
147
- *   function : (16-bit) virtual address of protected-mode function to call
158
+ *   function : (32-bit) virtual address of C function to call
148
  *
159
  *
149
  * Example usage:
160
  * Example usage:
150
- *	pushw	$pxe_api_call
161
+ *	pushl	$pxe_api_call
151
  *	lcall	$UNDI_CS, $kir_call
162
  *	lcall	$UNDI_CS, $kir_call
152
- *	addw	$2, %sp
163
+ *	addw	$4, %sp
153
  * to call in to the C function
164
  * to call in to the C function
154
  *      void pxe_api_call ( struct i386_all_regs *ix86 );
165
  *      void pxe_api_call ( struct i386_all_regs *ix86 );
155
  ****************************************************************************
166
  ****************************************************************************
157
 
168
 
158
 	.globl	kir_call
169
 	.globl	kir_call
159
 kir_call:
170
 kir_call:
160
-
161
 	/* Preserve flags.  Must do this before any operation that may
171
 	/* Preserve flags.  Must do this before any operation that may
162
 	 * affect flags.
172
 	 * affect flags.
163
 	 */
173
 	 */
174
 	 * either a 16-bit or a 32-bit stack segment.
184
 	 * either a 16-bit or a 32-bit stack segment.
175
 	 */
185
 	 */
176
 	popl	%cs:save_retaddr	/* Scratch location */
186
 	popl	%cs:save_retaddr	/* Scratch location */
177
-	popw	%cs:save_function
178
-	subl	$6, %esp		/* Restore %esp */
187
+	popl	%cs:save_function
188
+	subl	$8, %esp		/* Restore %esp */
179
 	
189
 	
180
 	/* Switch to internal stack.  Note that the external stack is
190
 	/* Switch to internal stack.  Note that the external stack is
181
 	 * inaccessible once we're running internally (since we have
191
 	 * inaccessible once we're running internally (since we have
191
 	pushl	%cs:ext_cs_and_ss
201
 	pushl	%cs:ext_cs_and_ss
192
 
202
 
193
 	/* Push &ix86 on stack and call function */
203
 	/* Push &ix86 on stack and call function */
204
+	sti
194
 	pushl	%esp
205
 	pushl	%esp
195
 	data32 call *%cs:save_function
206
 	data32 call *%cs:save_function
196
 	popl	%eax /* discard */
207
 	popl	%eax /* discard */
231
 		.globl kir_ds
242
 		.globl kir_ds
232
 kir_ds:		.word 0
243
 kir_ds:		.word 0
233
 		.globl kir_sp
244
 		.globl kir_sp
234
-kir_sp:		.word 0
245
+kir_sp:		.word _estack
235
 
246
 
236
 /****************************************************************************
247
 /****************************************************************************
237
  * Temporary variables
248
  * Temporary variables
238
  ****************************************************************************
249
  ****************************************************************************
239
  */
250
  */
240
 save_ax:	.word 0
251
 save_ax:	.word 0
241
-save_retaddr:	.word 0
252
+save_retaddr:	.long 0
242
 save_flags:	.long 0
253
 save_flags:	.long 0
243
 save_function:	.long 0
254
 save_function:	.long 0

Loading…
Cancel
Save