diff --git a/boot/boot.c b/boot/boot.c index e8f4fb0c4..2d919e04e 100644 --- a/boot/boot.c +++ b/boot/boot.c @@ -538,11 +538,30 @@ static void initialize(void) * done to get out of the way of Minix, and to put the data area * cleanly inside a 64K chunk if using BIOS I/O (no DMA problems). */ - u32_t oldaddr= caddr; - u32_t memend= mem[0].base + mem[0].size; - u32_t newaddr= (memend - runsize) & ~0x0000FL; + u32_t oldaddr; + u32_t memend; + u32_t newaddr; #if !DOS - u32_t dma64k= (memend - 1) & ~0x0FFFFL; + u32_t dma64k; +#endif + + if (mem_entries) { + int i, j; + j = 0; + for(i = 0; i < mem_entries ; i++) { + if (j < 3 && emem[i].type == 1) { + mem[j].base = emem[i].base_lo; + mem[j].size = emem[i].size_lo; + j++; + } + } + } + + oldaddr= caddr; + memend= mem[0].base + mem[0].size; + newaddr= (memend - runsize) & ~0x0000FL; +#if !DOS + dma64k= (memend - 1) & ~0x0FFFFL; /* Check if data segment crosses a 64K boundary. */ diff --git a/boot/boot.h b/boot/boot.h index bdda5e242..662835a12 100644 --- a/boot/boot.h +++ b/boot/boot.h @@ -67,7 +67,18 @@ typedef struct { /* One chunk of free memory. */ u32_t size; /* Number of bytes. */ } memory; +typedef struct { /* One chunk of free memory. */ + u32_t base_lo; /* Start byte. */ + u32_t base_hi; + u32_t size_lo; /* Number of bytes. */ + u32_t size_hi; /* Number of bytes. */ + u32_t type; + u32_t acpi_attrs; +} e820_memory; + EXTERN memory mem[3]; /* List of available memory. */ +EXTERN e820_memory emem[16]; /* List of available memory. */ +EXTERN int mem_entries; EXTERN int mon_return; /* Monitor stays in memory? */ EXTERN int cdbooted; /* Did we boot from CD? (Set by boothead.s.) */ diff --git a/boot/boothead.s b/boot/boothead.s index 7fefb1ec3..0c7a348f5 100644 --- a/boot/boothead.s +++ b/boot/boothead.s @@ -41,6 +41,8 @@ .extern _rem_part ! To pass partition info .extern _k_flags ! Special kernel flags .extern _mem ! Free memory list +.extern _emem ! Free memory list for E820 +.extern _mem_entries ! Free memory E820 list entries .extern _cdbooted ! Whether we booted from CD .extern _cddevice ! Whether we booted from CD @@ -143,6 +145,64 @@ sepID: mov _runsize+0, ax mov _runsize+2, dx ! 32 bit size of this process +!Determine memory using the 0xE820 BIOS function if available + mov di, #_emem + mov 20(di), #1 ! force a valid ACPI 3.X entry + + .data1 o32 + xor bx, bx ! zero EBX + xor bp, bp !zero bp + .data1 o32 + mov dx, e820_magic + .data1 o32 + mov cx, const_24 ! request 24 bytes + + .data1 o32 + mov ax, const_0xe820 + int 0x15 + jc e820_failed + + .data1 o32 + mov dx, e820_magic + .data1 o32 + cmp dx, ax + jne e820_failed + + .data1 o32 + test bx, bx + je e820_failed + jmp e820_gotit + +e820_next: + .data1 o32 + mov ax, const_0xe820 + mov 20(di), #1 ! force a valid ACPI 3.X entry + + .data1 o32 + mov cx, const_24 ! request 24 bytes + int 0x15 + jc e820_done + .data1 o32 + mov dx, e820_magic + + +e820_gotit: + jcxz e820_skip + cmp bp, #16 + je e820_done ! we have only space for 16 entries + inc bp + add di, #24 +e820_skip: + .data1 o32 + test bx, bx + jne e820_next + +e820_done: + mov _mem_entries, bp + jmp memory_detected + +e820_failed: + ! Determine available memory as a list of (base,size) pairs as follows: ! mem[0] = low memory, mem[1] = memory between 1M and 16M, mem[2] = memory ! above 16M. Last two coalesced into mem[1] if adjacent. @@ -185,6 +245,8 @@ adj_ext: add 14(di), bx ! Add ext mem above 16M to mem below 16M no_ext: +memory_detected: + ! Time to switch to a higher level language (not much higher) call _boot @@ -1534,6 +1596,15 @@ p_mcs_desc: .data2 0xFFFF, UNSET .data1 UNSET, 0x9A, 0x00, 0x00 +e820_magic: +! .data1 0x53, 0x4D, 0x41, 0x50 + .data1 0x50, 0x41, 0x4D, 0x53 +const_24: + .data1 0x18, 0x0, 0x0, 0x0 +const_0xe820: + .data2 0xe820 + + .bss .comm old_vid_mode, 2 ! Video mode at startup .comm cur_vid_mode, 2 ! Current video mode