Magellan Linux

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 532 - (hide annotations) (download)
Sat Sep 1 22:45:15 2007 UTC (16 years, 8 months ago) by niro
File size: 3992 byte(s)
-import if magellan mkinitrd; it is a fork of redhats mkinitrd-5.0.8 with all magellan patches and features; deprecates magellan-src/mkinitrd

1 niro 532 ;; $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)