Magellan Linux

Contents of /trunk/mkinitrd-magellan/isolinux/highmem.inc

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1133 - (show annotations) (download)
Thu Aug 19 09:50:43 2010 UTC (13 years, 8 months ago) by niro
File size: 3938 byte(s)
-updated to isolinux-3.86
1 ;; -----------------------------------------------------------------------
2 ;;
3 ;; Copyright 1994-2008 H. Peter Anvin - All Rights Reserved
4 ;;
5 ;; This program is free software; you can redistribute it and/or modify
6 ;; it under the terms of the GNU General Public License as published by
7 ;; the Free Software Foundation, Inc., 53 Temple Place Ste 330,
8 ;; Boston MA 02111-1307, USA; either version 2 of the License, or
9 ;; (at your option) any later version; incorporated herein by reference.
10 ;;
11 ;; -----------------------------------------------------------------------
12
13 ;;
14 ;; highmem.inc
15 ;;
16 ;; Probe for the size of high memory. This can be overridden by a
17 ;; mem= command on the command line while booting a new kernel.
18 ;;
19
20 section .text
21
22 ;
23 ; This is set up as a subroutine; it will set up the global variable
24 ; HighMemSize. All registers are preserved.
25 ;
26 highmemsize:
27 push es
28 pushfd
29 pushad
30
31 push cs
32 pop es
33
34 ;
35 ; First, try INT 15:E820 (get BIOS memory map)
36 ;
37 ; Note: we may have to scan this multiple times, because some (daft) BIOSes
38 ; report main memory as multiple contiguous ranges...
39 ;
40 get_e820:
41 mov dword [E820Max],-(1 << 20) ; Max amount of high memory
42 mov dword [E820Mem],(1 << 20) ; End of detected high memory
43 .start_over:
44 mov di,E820Buf
45 xor ax,ax
46 mov cx,10
47 rep stosw ; Clear buffer
48 xor ebx,ebx ; Start with first record
49 jmp short .do_e820 ; Skip "at end" check first time!
50 .int_loop: and ebx,ebx ; If we're back at beginning...
51 jz .e820_done ; ... we're done
52 .do_e820: mov eax,0000E820h
53 mov edx,534D4150h ; "SMAP" backwards
54 xor ecx,ecx
55 mov cl,20 ; ECX <- 20 (size of buffer)
56 mov di,E820Buf
57 int 15h
58 jnc .no_carry
59 ; If carry, ebx == 0 means error, ebx != 0 means we're done
60 and ebx,ebx
61 jnz .e820_done
62 jmp no_e820
63 .no_carry:
64 cmp eax,534D4150h
65 jne no_e820
66 cmp cx,20
67 jb no_e820
68
69 ;
70 ; Look for a memory block starting at <= 1 MB and continuing upward
71 ;
72 cmp dword [E820Buf+4], byte 0
73 ja .int_loop ; Start >= 4 GB?
74 mov eax, [E820Buf]
75 cmp dword [E820Buf+16],1
76 je .is_ram ; Is it memory?
77 ;
78 ; Non-memory range. Remember this as a limit; some BIOSes get the length
79 ; of primary RAM incorrect!
80 ;
81 .not_ram:
82 cmp eax, (1 << 20)
83 jb .int_loop ; Starts in lowmem region
84 cmp eax,[E820Max]
85 jae .int_loop ; Already above limit
86 mov [E820Max],eax ; Set limit
87 jmp .int_loop
88
89 .is_ram:
90 cmp eax,[E820Mem]
91 ja .int_loop ; Not contiguous with our starting point
92 add eax,[E820Buf+8]
93 jc .overflow
94 cmp dword [E820Buf+12],0
95 je .nooverflow
96 .overflow:
97 or eax,-1
98 .nooverflow:
99 cmp eax,[E820Mem]
100 jbe .int_loop ; All is below our baseline
101 mov [E820Mem],eax
102 jmp .start_over ; Start over in case we find an adjacent range
103
104 .e820_done:
105 mov eax,[E820Mem]
106 cmp eax,[E820Max]
107 jna .not_limited
108 mov eax,[E820Max]
109 .not_limited:
110 cmp eax,(1 << 20)
111 ja got_highmem ; Did we actually find memory?
112 ; otherwise fall through
113
114 ;
115 ; INT 15:E820 failed. Try INT 15:E801.
116 ;
117 no_e820:
118 mov ax,0e801h ; Query high memory (semi-recent)
119 int 15h
120 jc no_e801
121 cmp ax,3c00h
122 ja no_e801 ; > 3C00h something's wrong with this call
123 jb e801_hole ; If memory hole we can only use low part
124
125 mov ax,bx
126 shl eax,16 ; 64K chunks
127 add eax,(16 << 20) ; Add first 16M
128 jmp short got_highmem
129
130 ;
131 ; INT 15:E801 failed. Try INT 15:88.
132 ;
133 no_e801:
134 mov ah,88h ; Query high memory (oldest)
135 int 15h
136 cmp ax,14*1024 ; Don't trust memory >15M
137 jna e801_hole
138 mov ax,14*1024
139 e801_hole:
140 and eax,0ffffh
141 shl eax,10 ; Convert from kilobytes
142 add eax,(1 << 20) ; First megabyte
143 got_highmem:
144 %if HIGHMEM_SLOP != 0
145 sub eax,HIGHMEM_SLOP
146 %endif
147 mov [HighMemSize],eax
148 popad
149 popfd
150 pop es
151 ret ; Done!
152
153 section .bss
154 alignb 4
155 E820Buf resd 5 ; INT 15:E820 data buffer
156 E820Mem resd 1 ; Memory detected by E820
157 E820Max resd 1 ; Is E820 memory capped?
158 HighMemSize resd 1 ; End of memory pointer (bytes)