瀏覽代碼

[i386] Free allocated base memory on exit, if possible

Code paths that automatically allocate memory from the FBMS at 40:13
should also free it, if possible.

Freeing this memory will not be possible if either

  1. The FBMS has been modified since our allocation, or

  2. We have not been able to unhook one or more BIOS interrupt vectors.
tags/v0.9.6
Michael Brown 16 年之前
父節點
當前提交
0a8a17e669

+ 14
- 1
src/arch/i386/include/biosint.h 查看文件

@@ -6,9 +6,22 @@
6 6
  *
7 7
  */
8 8
 
9
+#include <realmode.h>
10
+
9 11
 struct segoff;
10 12
 
11
-extern int hooked_bios_interrupts;
13
+/**
14
+ * Hooked interrupt count
15
+ *
16
+ * At exit, after unhooking all possible interrupts, this counter
17
+ * should be examined.  If it is non-zero, it means that we failed to
18
+ * unhook at least one interrupt vector, and so must not free up the
19
+ * memory we are using.  (Note that this also implies that we should
20
+ * re-hook INT 15 in order to hide ourselves from the memory map).
21
+ */
22
+extern uint16_t __text16 ( hooked_bios_interrupts );
23
+#define hooked_bios_interrupts __use_text16 ( hooked_bios_interrupts )
24
+
12 25
 extern void hook_bios_interrupt ( unsigned int interrupt, unsigned int handler,
13 26
 				  struct segoff *chain_vector );
14 27
 extern int unhook_bios_interrupt ( unsigned int interrupt,

+ 0
- 11
src/arch/i386/interface/pcbios/biosint.c 查看文件

@@ -7,17 +7,6 @@
7 7
  *
8 8
  */
9 9
 
10
-/**
11
- * Hooked interrupt count
12
- *
13
- * At exit, after unhooking all possible interrupts, this counter
14
- * should be examined.  If it is non-zero, it means that we failed to
15
- * unhook at least one interrupt vector, and so must not free up the
16
- * memory we are using.  (Note that this also implies that we should
17
- * re-hook INT 15 in order to hide ourselves from the memory map).
18
- */
19
-int hooked_bios_interrupts = 0;
20
-
21 10
 /**
22 11
  * Hook INT vector
23 12
  *

+ 5
- 1
src/arch/i386/prefix/dskprefix.S 查看文件

@@ -353,6 +353,7 @@ msg1end:
353 353
 	.word 0xAA55
354 354
 
355 355
 start_runtime:
356
+	/* Install gPXE */
356 357
 	call	install
357 358
 
358 359
 	/* Set up real-mode stack */
@@ -368,7 +369,10 @@ start_runtime:
368 369
 	pushl	$main
369 370
 	pushw	%cs
370 371
 	call	prot_call
371
-	popl	%eax /* discard */
372
+	popl	%ecx /* discard */
373
+
374
+	/* Uninstall gPXE */
375
+	call	uninstall
372 376
 
373 377
 	/* Boot next device */
374 378
 	int $0x18

+ 5
- 1
src/arch/i386/prefix/hdprefix.S 查看文件

@@ -82,6 +82,7 @@ load_failed:
82 82
 	.byte 0x55, 0xaa
83 83
 
84 84
 start_image:
85
+	/* Install gPXE */
85 86
 	call	install
86 87
 
87 88
 	/* Set up real-mode stack */
@@ -97,7 +98,10 @@ start_image:
97 98
 	pushl	$main
98 99
 	pushw	%cs
99 100
 	call	prot_call
100
-	popl	%eax /* discard */
101
+	popl	%ecx /* discard */
102
+
103
+	/* Uninstall gPXE */
104
+	call	uninstall
101 105
 
102 106
 	/* Boot next device */
103 107
 	int $0x18

+ 86
- 5
src/arch/i386/prefix/libprefix.S 查看文件

@@ -537,17 +537,20 @@ install_block:
537 537
 	.code16
538 538
 	.globl	alloc_basemem
539 539
 alloc_basemem:
540
+	/* Preserve registers */
541
+	pushw	%fs
542
+
540 543
 	/* FBMS => %ax as segment address */
541
-	movw	$0x40, %ax
542
-	movw	%ax, %fs
544
+	pushw	$0x40
545
+	popw	%fs
543 546
 	movw	%fs:0x13, %ax
544 547
 	shlw	$6, %ax
545 548
 
546
-	/* .data16 segment address */
549
+	/* Calculate .data16 segment address */
547 550
 	subw	$_data16_memsz_pgh, %ax
548 551
 	pushw	%ax
549 552
 
550
-	/* .text16 segment address */
553
+	/* Calculate .text16 segment address */
551 554
 	subw	$_text16_memsz_pgh, %ax
552 555
 	pushw	%ax
553 556
 
@@ -555,12 +558,67 @@ alloc_basemem:
555 558
 	shrw	$6, %ax
556 559
 	movw	%ax, %fs:0x13
557 560
 
558
-	/* Return */
561
+	/* Retrieve .text16 and .data16 segment addresses */
559 562
 	popw	%ax
560 563
 	popw	%bx
564
+
565
+	/* Restore registers and return */
566
+	popw	%fs
561 567
 	ret
562 568
 	.size alloc_basemem, . - alloc_basemem
563 569
 
570
+/****************************************************************************
571
+ * free_basemem (real-mode near call)
572
+ *
573
+ * Free space allocated with alloc_basemem.
574
+ *
575
+ * Parameters:
576
+ *   %ax : .text16 segment address
577
+ *   %bx : .data16 segment address
578
+ * Returns:
579
+ *   %ax : 0 if successfully freed
580
+ * Corrupts:
581
+ *   none
582
+ ****************************************************************************
583
+ */
584
+	.section ".text16"
585
+	.code16
586
+	.globl	free_basemem
587
+free_basemem:
588
+	/* Preserve registers */
589
+	pushw	%fs
590
+
591
+	/* Check FBMS counter */
592
+	pushw	%ax
593
+	shrw	$6, %ax
594
+	pushw	$0x40
595
+	popw	%fs
596
+	cmpw	%ax, %fs:0x13
597
+	popw	%ax
598
+	jne	1f
599
+
600
+	/* Check hooked interrupt count */
601
+	cmpw	$0, %cs:hooked_bios_interrupts
602
+	jne	1f
603
+
604
+	/* OK to free memory */
605
+	addw	$_text16_memsz_pgh, %ax
606
+	addw	$_data16_memsz_pgh, %ax
607
+	shrw	$6, %ax
608
+	movw	%ax, %fs:0x13
609
+	xorw	%ax, %ax
610
+
611
+1:	/* Restore registers and return */
612
+	popw	%fs
613
+	ret
614
+	.size free_basemem, . - free_basemem
615
+
616
+	.section ".text16.data"
617
+	.globl	hooked_bios_interrupts
618
+hooked_bios_interrupts:
619
+	.word	0
620
+	.size	hooked_bios_interrupts, . - hooked_bios_interrupts
621
+
564 622
 /****************************************************************************
565 623
  * install (real-mode near call)
566 624
  *
@@ -709,6 +767,29 @@ prot_call_vector:
709 767
 	.size prot_call_vector, . - prot_call_vector
710 768
 #endif
711 769
 
770
+/****************************************************************************
771
+ * uninstall (real-mode near call)
772
+ *
773
+ * Uninstall all text and data segments.
774
+ *
775
+ * Parameters:
776
+ *   %ax  : .text16 segment address
777
+ *   %bx  : .data16 segment address
778
+ * Returns:
779
+ *   none
780
+ * Corrupts:
781
+ *   none
782
+ ****************************************************************************
783
+ */
784
+	.section ".text16"
785
+	.code16
786
+	.globl uninstall
787
+uninstall:
788
+	call	free_basemem
789
+	ret
790
+	.size uninstall, . - uninstall
791
+
792
+
712 793
 
713 794
 	/* File split information for the compressor */
714 795
 #if COMPRESS

+ 5
- 1
src/arch/i386/prefix/lkrnprefix.S 查看文件

@@ -189,6 +189,7 @@ run_gpxe:
189 189
 	movw	%ax, %ss
190 190
 	movw	$0x7c00, %sp
191 191
 
192
+	/* Install gPXE */
192 193
 	call	install
193 194
 
194 195
 	/* Set up real-mode stack */
@@ -204,7 +205,10 @@ run_gpxe:
204 205
 	pushl	$main
205 206
 	pushw	%cs
206 207
 	call	prot_call
207
-	popl	%eax /* discard */
208
+	popl	%ecx /* discard */
209
+
210
+	/* Uninstall gPXE */
211
+	call	uninstall
208 212
 
209 213
 	/* Boot next device */
210 214
 	int $0x18

+ 5
- 2
src/arch/i386/prefix/nbiprefix.S 查看文件

@@ -52,7 +52,7 @@ memlen:	.long	_filesz - 512
52 52
  *****************************************************************************
53 53
  */
54 54
 entry:
55
-	/* Install low and high memory regions */
55
+	/* Install gPXE */
56 56
 	call	install
57 57
 
58 58
 	/* Jump to .text16 segment */
@@ -64,7 +64,10 @@ entry:
64 64
 	pushl	$main
65 65
 	pushw	%cs
66 66
 	call	prot_call
67
-	popl	%eax /* discard */
67
+	popl	%ecx /* discard */
68
+
69
+	/* Uninstall gPXE */
70
+	call	uninstall
68 71
 
69 72
 	/* Reboot system */
70 73
 	int $0x19

+ 8
- 5
src/arch/i386/prefix/pxeprefix.S 查看文件

@@ -318,7 +318,7 @@ print_free_basemem:
318 318
  *****************************************************************************
319 319
  */	
320 320
 finished:
321
-	jmp	run_etherboot
321
+	jmp	run_gpxe
322 322
 
323 323
 /*****************************************************************************
324 324
  * Subroutine: print segment:offset address
@@ -554,11 +554,11 @@ flags:			.word UNDI_FL_STARTED
554 554
 	.equ undi_device_size, ( . - undi_device )
555 555
 
556 556
 /*****************************************************************************
557
- * Run Etherboot main code
557
+ * Run gPXE main code
558 558
  *****************************************************************************
559 559
  */	
560
-run_etherboot:
561
-	/* Install Etherboot */
560
+run_gpxe:
561
+	/* Install gPXE */
562 562
 	call	install
563 563
 
564 564
 	/* Set up real-mode stack */
@@ -585,7 +585,10 @@ run_etherboot:
585 585
 	pushl	$main
586 586
 	pushw	%cs
587 587
 	call	prot_call
588
-	popl	%eax /* discard */
588
+	popl	%ecx /* discard */
589
+
590
+	/* Uninstall gPXE */
591
+	call	uninstall
589 592
 
590 593
 	/* Boot next device */
591 594
 	int	$0x18

+ 5
- 2
src/arch/i386/prefix/romprefix.S 查看文件

@@ -591,8 +591,11 @@ exec:	/* Set %ds = %cs */
591 591
 	pushl	$main
592 592
 	pushw	%cs
593 593
 	call	prot_call
594
-	/* No need to clean up stack; we are about to reload %ss:sp */
595
-	
594
+	popl	%ecx /* discard */
595
+
596
+	/* Uninstall gPXE */
597
+	call	uninstall
598
+
596 599
 	/* Restore BIOS stack */
597 600
 	movw	%dx, %ss
598 601
 	movw	%bp, %sp

Loading…
取消
儲存