Contents of /tags/mkinitrd-6_2_3/isolinux/highmem.inc
Parent Directory | Revision Log
Revision 1054 -
(show annotations)
(download)
Mon May 31 20:54:44 2010 UTC (14 years, 4 months ago) by niro
File size: 3992 byte(s)
Mon May 31 20:54:44 2010 UTC (14 years, 4 months ago) by niro
File size: 3992 byte(s)
tagged 'mkinitrd-6_2_3'
1 | ;; $Id: highmem.inc,v 1.1 2007-09-01 22:44:04 niro Exp $ |
2 | ;; ----------------------------------------------------------------------- |
3 | ;; |
4 | ;; Copyright 1994-2004 H. Peter Anvin - All Rights Reserved |
5 | ;; |
6 | ;; This program is free software; you can redistribute it and/or modify |
7 | ;; it under the terms of the GNU General Public License as published by |
8 | ;; the Free Software Foundation, Inc., 53 Temple Place Ste 330, |
9 | ;; Boston MA 02111-1307, USA; either version 2 of the License, or |
10 | ;; (at your option) any later version; incorporated herein by reference. |
11 | ;; |
12 | ;; ----------------------------------------------------------------------- |
13 | |
14 | ;; |
15 | ;; highmem.inc |
16 | ;; |
17 | ;; Probe for the size of high memory. This can be overridden by a |
18 | ;; mem= command on the command line while booting a new kernel. |
19 | ;; |
20 | |
21 | section .text |
22 | |
23 | ; |
24 | ; This is set up as a subroutine; it will set up the global variable |
25 | ; HighMemSize. All registers are preserved. Assumes DS == CS. |
26 | ; |
27 | highmemsize: |
28 | push es |
29 | pushad |
30 | |
31 | ; |
32 | ; First, try INT 15:E820 (get BIOS memory map) |
33 | ; |
34 | get_e820: |
35 | xor ebx,ebx ; Start with first record |
36 | mov dword [E820Max],-(1 << 20) ; Max amount of high memory |
37 | mov dword [E820Mem],ebx ; Detected amount of high memory |
38 | mov es,bx ; Need ES = DS = 0 for now |
39 | jmp short .do_e820 ; Skip "at end" check first time! |
40 | .int_loop: and ebx,ebx ; If we're back at beginning... |
41 | jz .e820_done ; ... we're done |
42 | .do_e820: mov eax,0000E820h |
43 | mov edx,534D4150h ; "SMAP" backwards |
44 | xor ecx,ecx |
45 | mov cl,20 ; ECX <- 20 |
46 | mov di,E820Buf |
47 | int 15h |
48 | jnc .no_carry |
49 | ; If carry, ebx == 0 means error, ebx != 0 means we're done |
50 | and ebx,ebx |
51 | jnz .e820_done |
52 | jmp no_e820 |
53 | .no_carry: |
54 | cmp eax,534D4150h |
55 | jne no_e820 |
56 | ; |
57 | ; Look for a memory block starting at <= 1 MB and continuing upward |
58 | ; |
59 | cmp dword [E820Buf+4], byte 0 |
60 | ja .int_loop ; Start >= 4 GB? |
61 | mov edx, (1 << 20) |
62 | sub edx, [E820Buf] |
63 | jnb .ram_range ; Start >= 1 MB? |
64 | ; If we get here, it starts > 1 MB but < 4 GB; if this is a |
65 | ; *non*-memory range, remember this as unusable; some BIOSes |
66 | ; get the length of primary RAM wrong! |
67 | cmp dword [E820Buf+16], byte 1 |
68 | je .int_loop ; If it's memory, don't worry about it |
69 | neg edx ; This means what for memory limit? |
70 | cmp edx,[E820Max] ; Better or worse |
71 | jnb .int_loop |
72 | mov [E820Max],edx |
73 | jmp .int_loop |
74 | |
75 | .ram_range: |
76 | stc |
77 | sbb eax,eax ; eax <- 0xFFFFFFFF |
78 | cmp dword [E820Buf+12], byte 0 |
79 | ja .huge ; Size >= 4 GB |
80 | mov eax, [E820Buf+8] |
81 | .huge: sub eax, edx ; Adjust size to start at 1 MB |
82 | jbe .int_loop ; Completely below 1 MB? |
83 | |
84 | ; Now EAX contains the size of memory 1 MB...up |
85 | cmp dword [E820Buf+16], byte 1 |
86 | jne .int_loop ; High memory isn't usable memory!!!! |
87 | |
88 | ; We're good! |
89 | mov [E820Mem],eax |
90 | jmp .int_loop ; Still need to add low 1 MB |
91 | |
92 | .e820_done: |
93 | mov eax,[E820Mem] |
94 | and eax,eax |
95 | jz no_e820 ; Nothing found by E820? |
96 | cmp eax,[E820Max] ; Make sure we're not limited |
97 | jna got_highmem_add1mb |
98 | mov eax,[E820Max] |
99 | jmp got_highmem_add1mb |
100 | |
101 | ; |
102 | ; INT 15:E820 failed. Try INT 15:E801. |
103 | ; |
104 | no_e820: |
105 | mov ax,0e801h ; Query high memory (semi-recent) |
106 | int 15h |
107 | jc no_e801 |
108 | cmp ax,3c00h |
109 | ja no_e801 ; > 3C00h something's wrong with this call |
110 | jb e801_hole ; If memory hole we can only use low part |
111 | |
112 | mov ax,bx |
113 | shl eax,16 ; 64K chunks |
114 | add eax,(16 << 20) ; Add first 16M |
115 | jmp short got_highmem |
116 | |
117 | ; |
118 | ; INT 15:E801 failed. Try INT 15:88. |
119 | ; |
120 | no_e801: |
121 | mov ah,88h ; Query high memory (oldest) |
122 | int 15h |
123 | cmp ax,14*1024 ; Don't trust memory >15M |
124 | jna e801_hole |
125 | mov ax,14*1024 |
126 | e801_hole: |
127 | and eax,0ffffh |
128 | shl eax,10 ; Convert from kilobytes |
129 | got_highmem_add1mb: |
130 | add eax,(1 << 20) ; First megabyte |
131 | got_highmem: |
132 | %if HIGHMEM_SLOP != 0 |
133 | sub eax,HIGHMEM_SLOP |
134 | %endif |
135 | mov [HighMemSize],eax |
136 | popad |
137 | pop es |
138 | ret ; Done! |
139 | |
140 | section .bss |
141 | alignb 4 |
142 | E820Buf resd 5 ; INT 15:E820 data buffer |
143 | E820Mem resd 1 ; Memory detected by E820 |
144 | E820Max resd 1 ; Is E820 memory capped? |
145 | HighMemSize resd 1 ; End of memory pointer (bytes) |