|
@@ -0,0 +1,64 @@
|
|
1
|
+#include "limits.h"
|
|
2
|
+#include "io.h"
|
|
3
|
+#include "memsizes.h"
|
|
4
|
+#include "init.h"
|
|
5
|
+#include "buffer.h"
|
|
6
|
+
|
|
7
|
+/*
|
|
8
|
+ * Initialise a buffer in an unused portion of memory, to be used for
|
|
9
|
+ * loading an image
|
|
10
|
+ *
|
|
11
|
+ */
|
|
12
|
+
|
|
13
|
+/* Under KEEP_IT_REAL, always use 07c0:0000 as the buffer. Otherwise,
|
|
14
|
+ * use a reset_fn that finds the largest available block of RAM.
|
|
15
|
+ */
|
|
16
|
+struct buffer load_buffer = {
|
|
17
|
+ .start = 0x7c00,
|
|
18
|
+ .end = 0xa0000,
|
|
19
|
+};
|
|
20
|
+
|
|
21
|
+#ifndef KEEP_IT_REAL
|
|
22
|
+
|
|
23
|
+extern char _text[];
|
|
24
|
+
|
|
25
|
+static void init_load_buffer ( void ) {
|
|
26
|
+ unsigned int i;
|
|
27
|
+ unsigned long size = 0;
|
|
28
|
+
|
|
29
|
+ load_buffer.start = 0;
|
|
30
|
+ load_buffer.end = 0;
|
|
31
|
+
|
|
32
|
+ /* Find the largest usable segment in memory */
|
|
33
|
+ for ( i = 0 ; i < meminfo.map_count ; i++ ) {
|
|
34
|
+ unsigned long r_start, r_end;
|
|
35
|
+
|
|
36
|
+ if ( meminfo.map[i].type != E820_RAM )
|
|
37
|
+ continue;
|
|
38
|
+
|
|
39
|
+ if ( meminfo.map[i].addr + meminfo.map[i].size > ULONG_MAX )
|
|
40
|
+ continue;
|
|
41
|
+
|
|
42
|
+ r_start = meminfo.map[i].addr;
|
|
43
|
+ r_end = meminfo.map[i].size;
|
|
44
|
+
|
|
45
|
+ /* Avoid overlap with Etherboot. Etherboot will be
|
|
46
|
+ * located towards the top of a segment, so we need
|
|
47
|
+ * only consider one-sided truncation.
|
|
48
|
+ */
|
|
49
|
+ if ( ( r_start <= virt_to_phys ( _text ) ) &&
|
|
50
|
+ ( virt_to_phys ( _text ) < r_end ) ) {
|
|
51
|
+ r_end = virt_to_phys ( _text );
|
|
52
|
+ }
|
|
53
|
+
|
|
54
|
+ if ( r_end - r_start > size ) {
|
|
55
|
+ size = r_end - r_start;
|
|
56
|
+ load_buffer.start = r_start;
|
|
57
|
+ load_buffer.end = r_end;
|
|
58
|
+ }
|
|
59
|
+ }
|
|
60
|
+}
|
|
61
|
+
|
|
62
|
+INIT_FN ( INIT_HEAP, init_load_buffer, init_load_buffer, NULL );
|
|
63
|
+
|
|
64
|
+#endif
|