Magellan Linux

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1133 - (hide annotations) (download)
Thu Aug 19 09:50:43 2010 UTC (13 years, 9 months ago) by niro
File size: 3938 byte(s)
-updated to isolinux-3.86
1 niro 532 ;; -----------------------------------------------------------------------
2     ;;
3 niro 1133 ;; Copyright 1994-2008 H. Peter Anvin - All Rights Reserved
4     ;;
5 niro 532 ;; 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 niro 1133 ;;
16 niro 532 ;; 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 niro 1133 ; HighMemSize. All registers are preserved.
25 niro 532 ;
26     highmemsize:
27     push es
28 niro 1133 pushfd
29 niro 532 pushad
30    
31 niro 1133 push cs
32     pop es
33    
34 niro 532 ;
35     ; First, try INT 15:E820 (get BIOS memory map)
36     ;
37 niro 1133 ; Note: we may have to scan this multiple times, because some (daft) BIOSes
38     ; report main memory as multiple contiguous ranges...
39     ;
40 niro 532 get_e820:
41 niro 1133 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 niro 532 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 niro 1133 mov cl,20 ; ECX <- 20 (size of buffer)
56 niro 532 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 niro 1133 cmp cx,20
67     jb no_e820
68    
69 niro 532 ;
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 niro 1133 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 niro 532 jmp .int_loop
88    
89 niro 1133 .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 niro 532 mov [E820Mem],eax
102 niro 1133 jmp .start_over ; Start over in case we find an adjacent range
103 niro 532
104     .e820_done:
105     mov eax,[E820Mem]
106 niro 1133 cmp eax,[E820Max]
107     jna .not_limited
108 niro 532 mov eax,[E820Max]
109 niro 1133 .not_limited:
110     cmp eax,(1 << 20)
111     ja got_highmem ; Did we actually find memory?
112     ; otherwise fall through
113 niro 532
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 niro 1133 jmp short got_highmem
129 niro 532
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 niro 1133 popfd
150 niro 532 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)