Magellan Linux

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

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1132 by niro, Sat Sep 1 22:45:15 2007 UTC revision 1133 by niro, Thu Aug 19 09:50:43 2010 UTC
# Line 1  Line 1 
 ;; $Id: highmem.inc,v 1.1 2007-09-01 22:44:04 niro Exp $  
1  ;; -----------------------------------------------------------------------  ;; -----------------------------------------------------------------------
2  ;;    ;;
3  ;;   Copyright 1994-2004 H. Peter Anvin - All Rights Reserved  ;;   Copyright 1994-2008 H. Peter Anvin - All Rights Reserved
4  ;;  ;;
5  ;;   This program is free software; you can redistribute it and/or modify  ;;   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  ;;   it under the terms of the GNU General Public License as published by
# Line 13  Line 12 
12    
13  ;;  ;;
14  ;; highmem.inc  ;; highmem.inc
15  ;;  ;;
16  ;; Probe for the size of high memory.  This can be overridden by a  ;; 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.  ;; mem= command on the command line while booting a new kernel.
18  ;;  ;;
# Line 22  Line 21 
21    
22  ;  ;
23  ; This is set up as a subroutine; it will set up the global variable  ; This is set up as a subroutine; it will set up the global variable
24  ; HighMemSize.  All registers are preserved.  Assumes DS == CS.  ; HighMemSize.  All registers are preserved.
25  ;  ;
26  highmemsize:  highmemsize:
27   push es   push es
28     pushfd
29   pushad   pushad
30    
31     push cs
32     pop es
33    
34  ;  ;
35  ; First, try INT 15:E820 (get BIOS memory map)  ; 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:  get_e820:
  xor ebx,ebx ; Start with first record  
41   mov dword [E820Max],-(1 << 20) ; Max amount of high memory   mov dword [E820Max],-(1 << 20) ; Max amount of high memory
42   mov dword [E820Mem],ebx ; Detected amount of high memory   mov dword [E820Mem],(1 << 20) ; End of detected high memory
43   mov es,bx ; Need ES = DS = 0 for now  .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!   jmp short .do_e820 ; Skip "at end" check first time!
50  .int_loop: and ebx,ebx ; If we're back at beginning...  .int_loop: and ebx,ebx ; If we're back at beginning...
51   jz .e820_done ; ... we're done   jz .e820_done ; ... we're done
52  .do_e820: mov eax,0000E820h  .do_e820: mov eax,0000E820h
53   mov edx,534D4150h ; "SMAP" backwards   mov edx,534D4150h ; "SMAP" backwards
54   xor ecx,ecx   xor ecx,ecx
55   mov cl,20 ; ECX <- 20   mov cl,20 ; ECX <- 20 (size of buffer)
56   mov di,E820Buf   mov di,E820Buf
57   int 15h   int 15h
58   jnc .no_carry   jnc .no_carry
# Line 53  get_e820: Line 63  get_e820:
63  .no_carry:  .no_carry:
64   cmp eax,534D4150h   cmp eax,534D4150h
65   jne no_e820   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  ; Look for a memory block starting at <= 1 MB and continuing upward
71  ;  ;
72   cmp dword [E820Buf+4], byte 0   cmp dword [E820Buf+4], byte 0
73   ja .int_loop ; Start >= 4 GB?   ja .int_loop ; Start >= 4 GB?
74   mov edx, (1 << 20)   mov eax, [E820Buf]
75   sub edx, [E820Buf]   cmp dword [E820Buf+16],1
76   jnb .ram_range ; Start >= 1 MB?   je .is_ram ; Is it memory?
77   ; If we get here, it starts > 1 MB but < 4 GB; if this is a   ;
78   ; *non*-memory range, remember this as unusable; some BIOSes   ; Non-memory range.  Remember this as a limit; some BIOSes get the length
79   ; get the length of primary RAM wrong!   ; of primary RAM incorrect!
80   cmp dword [E820Buf+16], byte 1   ;
81   je .int_loop ; If it's memory, don't worry about it  .not_ram:
82   neg edx ; This means what for memory limit?   cmp eax, (1 << 20)
83   cmp edx,[E820Max] ; Better or worse   jb .int_loop ; Starts in lowmem region
84   jnb .int_loop   cmp eax,[E820Max]
85   mov [E820Max],edx   jae .int_loop ; Already above limit
86     mov [E820Max],eax ; Set limit
87   jmp .int_loop   jmp .int_loop
   
 .ram_range:  
  stc  
  sbb eax,eax ; eax <- 0xFFFFFFFF  
  cmp dword [E820Buf+12], byte 0  
  ja .huge ; Size >= 4 GB  
  mov eax, [E820Buf+8]  
 .huge: sub eax, edx ; Adjust size to start at 1 MB  
  jbe .int_loop ; Completely below 1 MB?  
   
  ; Now EAX contains the size of memory 1 MB...up  
  cmp dword [E820Buf+16], byte 1  
  jne .int_loop ; High memory isn't usable memory!!!!  
88    
89   ; We're good!  .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   mov [E820Mem],eax
102   jmp .int_loop ; Still need to add low 1 MB   jmp .start_over ; Start over in case we find an adjacent range
103    
104  .e820_done:  .e820_done:
105   mov eax,[E820Mem]   mov eax,[E820Mem]
106   and eax,eax   cmp eax,[E820Max]
107   jz no_e820 ; Nothing found by E820?   jna .not_limited
  cmp eax,[E820Max] ; Make sure we're not limited  
  jna got_highmem_add1mb  
108   mov eax,[E820Max]   mov eax,[E820Max]
109   jmp got_highmem_add1mb  .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.  ; INT 15:E820 failed.  Try INT 15:E801.
# Line 112  no_e820: Line 125  no_e820:
125   mov ax,bx   mov ax,bx
126   shl eax,16 ; 64K chunks   shl eax,16 ; 64K chunks
127   add eax,(16 << 20) ; Add first 16M   add eax,(16 << 20) ; Add first 16M
128   jmp short got_highmem   jmp short got_highmem
129    
130  ;  ;
131  ; INT 15:E801 failed.  Try INT 15:88.  ; INT 15:E801 failed.  Try INT 15:88.
# Line 126  no_e801: Line 139  no_e801:
139  e801_hole:  e801_hole:
140   and eax,0ffffh   and eax,0ffffh
141   shl eax,10 ; Convert from kilobytes   shl eax,10 ; Convert from kilobytes
 got_highmem_add1mb:  
142   add eax,(1 << 20) ; First megabyte   add eax,(1 << 20) ; First megabyte
143  got_highmem:  got_highmem:
144  %if HIGHMEM_SLOP != 0  %if HIGHMEM_SLOP != 0
# Line 134  got_highmem: Line 146  got_highmem:
146  %endif  %endif
147   mov [HighMemSize],eax   mov [HighMemSize],eax
148   popad   popad
149     popfd
150   pop es   pop es
151   ret ; Done!   ret ; Done!
152    

Legend:
Removed from v.1132  
changed lines
  Added in v.1133