mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 23:22:57 +00:00
[FREELDR]
Fix loading with GRUB (CMake builds). svn path=/trunk/; revision=53765
This commit is contained in:
parent
78f25bbeea
commit
6e9cef58d1
3 changed files with 111 additions and 160 deletions
|
@ -117,8 +117,7 @@ if(ARCH MATCHES i386)
|
||||||
disk/scsiport.c)
|
disk/scsiport.c)
|
||||||
if(NOT MSVC)
|
if(NOT MSVC)
|
||||||
list(APPEND FREELDR_COMMON_SOURCE
|
list(APPEND FREELDR_COMMON_SOURCE
|
||||||
arch/i386/drvmap.S
|
arch/i386/drvmap.S)
|
||||||
arch/i386/multiboot.S)
|
|
||||||
endif()
|
endif()
|
||||||
elseif(ARCH MATCHES amd64)
|
elseif(ARCH MATCHES amd64)
|
||||||
list(APPEND FREELDR_COMMON_SOURCE
|
list(APPEND FREELDR_COMMON_SOURCE
|
||||||
|
@ -148,6 +147,9 @@ endif()
|
||||||
add_library(freeldr_common ${FREELDR_COMMON_SOURCE})
|
add_library(freeldr_common ${FREELDR_COMMON_SOURCE})
|
||||||
add_dependencies(freeldr_common bugcodes)
|
add_dependencies(freeldr_common bugcodes)
|
||||||
|
|
||||||
|
if(ARCH MATCHES i386 AND NOT MSVC)
|
||||||
|
list(APPEND FREELDR_BASE_SOURCE arch/i386/multiboot.S)
|
||||||
|
endif()
|
||||||
|
|
||||||
list(APPEND FREELDR_BASE_SOURCE
|
list(APPEND FREELDR_BASE_SOURCE
|
||||||
bootmgr.c # This file is compiled with custom definitions
|
bootmgr.c # This file is compiled with custom definitions
|
||||||
|
@ -159,7 +161,7 @@ list(APPEND FREELDR_BASE_SOURCE
|
||||||
add_executable(freeldr_pe ${FREELDR_BASE_SOURCE})
|
add_executable(freeldr_pe ${FREELDR_BASE_SOURCE})
|
||||||
|
|
||||||
if(NOT MSVC)
|
if(NOT MSVC)
|
||||||
set_target_properties(freeldr_pe PROPERTIES LINK_FLAGS "-Wl,--strip-all -Wl,--exclude-all-symbols -Wl,--file-alignment,0x1000 -Wl,-T,${CMAKE_CURRENT_SOURCE_DIR}/freeldr_i386.lnk")
|
set_target_properties(freeldr_pe PROPERTIES LINK_FLAGS "-Wl,--strip-all,--exclude-all-symbols,--file-alignment,0x1000,-T,${CMAKE_CURRENT_SOURCE_DIR}/freeldr_i386.lnk")
|
||||||
else()
|
else()
|
||||||
set_target_properties(freeldr_pe PROPERTIES LINK_FLAGS "/ignore:4078 /ignore:4254 /DRIVER /FIXED /ALIGN:0x400 /SECTION:.text,ERW /SECTION:.data,RW /MERGE:.text16=.text /MERGE:.data=.text /MERGE:.rdata=.text /MERGE:.bss=.text /SUBSYSTEM:BOOT_APPLICATION")
|
set_target_properties(freeldr_pe PROPERTIES LINK_FLAGS "/ignore:4078 /ignore:4254 /DRIVER /FIXED /ALIGN:0x400 /SECTION:.text,ERW /SECTION:.data,RW /MERGE:.text16=.text /MERGE:.data=.text /MERGE:.rdata=.text /MERGE:.bss=.text /SUBSYSTEM:BOOT_APPLICATION")
|
||||||
endif()
|
endif()
|
||||||
|
@ -208,7 +210,7 @@ endif()
|
||||||
add_executable(setupldr_pe ${FREELDR_BASE_SOURCE} ${SETUPLDR_SOURCE})
|
add_executable(setupldr_pe ${FREELDR_BASE_SOURCE} ${SETUPLDR_SOURCE})
|
||||||
|
|
||||||
if(NOT MSVC)
|
if(NOT MSVC)
|
||||||
set_target_properties(setupldr_pe PROPERTIES LINK_FLAGS "-Wl,--strip-all -Wl,--exclude-all-symbols -Wl,--file-alignment,0x1000 -Wl,-T,${CMAKE_CURRENT_SOURCE_DIR}/freeldr_i386.lnk" COMPILE_DEFINITIONS "FREELDR_REACTOS_SETUP")
|
set_target_properties(setupldr_pe PROPERTIES LINK_FLAGS "-Wl,--strip-all,--exclude-all-symbols,--file-alignment,0x1000,-T,${CMAKE_CURRENT_SOURCE_DIR}/freeldr_i386.lnk" COMPILE_DEFINITIONS "FREELDR_REACTOS_SETUP")
|
||||||
else()
|
else()
|
||||||
set_target_properties(setupldr_pe PROPERTIES LINK_FLAGS "/ignore:4078 /ignore:4254 /DRIVER /FIXED /ALIGN:0x400 /SECTION:.text,ERW /SECTION:.data,RW /MERGE:.text16=.text /MERGE:.data=.text /MERGE:.rdata=.text /MERGE:.bss=.text /SUBSYSTEM:BOOT_APPLICATION" COMPILE_DEFINITIONS "FREELDR_REACTOS_SETUP")
|
set_target_properties(setupldr_pe PROPERTIES LINK_FLAGS "/ignore:4078 /ignore:4254 /DRIVER /FIXED /ALIGN:0x400 /SECTION:.text,ERW /SECTION:.data,RW /MERGE:.text16=.text /MERGE:.data=.text /MERGE:.rdata=.text /MERGE:.bss=.text /SUBSYSTEM:BOOT_APPLICATION" COMPILE_DEFINITIONS "FREELDR_REACTOS_SETUP")
|
||||||
endif()
|
endif()
|
||||||
|
|
|
@ -70,8 +70,14 @@ _FrldrStartup:
|
||||||
/* Initialize the idt */
|
/* Initialize the idt */
|
||||||
call _InitIdt
|
call _InitIdt
|
||||||
|
|
||||||
|
/* Pass the command line to BootMain */
|
||||||
|
#ifdef _USE_ML
|
||||||
|
xor eax, eax
|
||||||
|
#else
|
||||||
|
mov eax, offset cmdline
|
||||||
|
#endif
|
||||||
|
|
||||||
/* GO! */
|
/* GO! */
|
||||||
xor eax, eax
|
|
||||||
push eax
|
push eax
|
||||||
call _BootMain
|
call _BootMain
|
||||||
|
|
||||||
|
|
|
@ -21,195 +21,138 @@
|
||||||
#include <arch/pc/x86common.h>
|
#include <arch/pc/x86common.h>
|
||||||
#include <multiboot.h>
|
#include <multiboot.h>
|
||||||
|
|
||||||
|
|
||||||
/* Multiboot support
|
/* Multiboot support
|
||||||
*
|
*
|
||||||
* Allows freeldr to be loaded as a "multiboot kernel" by
|
* Allows freeldr to be loaded as a "multiboot kernel" by
|
||||||
* other boot loaders like Grub
|
* other boot loaders like GRUB.
|
||||||
* This code is not referenced from anywhere. GRUB searches for
|
* This code is not referenced from anywhere. GRUB searches for
|
||||||
* the header signature and uses the header to load it.
|
* the header signature and uses the header to load it.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define MB_INFO_SIZE 90
|
|
||||||
#define MB_INFO_FLAGS_OFFSET 0
|
#define MB_INFO_FLAGS_OFFSET 0
|
||||||
#define MB_INFO_BOOT_DEVICE_OFFSET 12
|
#define MB_INFO_BOOT_DEVICE_OFFSET 12
|
||||||
#define MB_INFO_COMMAND_LINE_OFFSET 16
|
#define MB_INFO_COMMAND_LINE_OFFSET 16
|
||||||
#define CMDLINE_SIZE 256
|
#define CMDLINE_SIZE 256
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We want to execute at 0x8000 (to be compatible with bootsector
|
* We want to execute at FREELDR_BASE (to be compatible with
|
||||||
* loading), but Grub only allows loading of multiboot kernels
|
* bootsector loading), but GRUB only allows loading of
|
||||||
* above 1MB. So we let Grub load us there and then relocate
|
* multiboot kernels above 1MB. So we let GRUB load us
|
||||||
* ourself to 0x8000
|
* there and then relocate ourself to FREELDR_BASE.
|
||||||
*/
|
*/
|
||||||
#define INITIAL_BASE HEX(200000)
|
#define INITIAL_BASE HEX(200000)
|
||||||
|
|
||||||
/* Align 32 bits boundary */
|
/* Align to 32 bits boundary */
|
||||||
.align 4
|
.align 4
|
||||||
|
|
||||||
/* Multiboot header */
|
/* Multiboot header */
|
||||||
MultibootHeader:
|
MultibootHeader:
|
||||||
/* magic */
|
/* magic */
|
||||||
.long MULTIBOOT_HEADER_MAGIC
|
.long MULTIBOOT_HEADER_MAGIC
|
||||||
/* flags */
|
/* flags */
|
||||||
.long MULTIBOOT_HEADER_FLAGS
|
.long MULTIBOOT_HEADER_FLAGS
|
||||||
/* checksum */
|
/* checksum */
|
||||||
.long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)
|
.long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)
|
||||||
/* header_addr */
|
/* header_addr */
|
||||||
.long INITIAL_BASE + MultibootHeader - FREELDR_BASE
|
.long INITIAL_BASE + MultibootHeader - FREELDR_BASE
|
||||||
/* load_addr */
|
/* load_addr */
|
||||||
.long INITIAL_BASE
|
.long INITIAL_BASE
|
||||||
/* load_end_addr */
|
/* load_end_addr */
|
||||||
.long INITIAL_BASE + __bss_start__ - FREELDR_BASE
|
.long INITIAL_BASE + __bss_start__ - FREELDR_BASE
|
||||||
/* bss_end_addr */
|
/* bss_end_addr */
|
||||||
.long INITIAL_BASE + __bss_end__ - FREELDR_BASE
|
.long 0
|
||||||
/* entry_addr */
|
/* entry_addr */
|
||||||
.long INITIAL_BASE + MultibootEntry - FREELDR_BASE
|
.long INITIAL_BASE + MultibootEntry - FREELDR_BASE
|
||||||
|
|
||||||
MultibootEntry:
|
MultibootEntry:
|
||||||
cli /* Even after setting up the our IDT below we are
|
cld
|
||||||
* not ready to handle hardware interrupts (no entries
|
|
||||||
* in IDT), so there's no sti here. Interrupts will be
|
|
||||||
* enabled in due time */
|
|
||||||
|
|
||||||
/* Although the multiboot spec says we should be called with the
|
/* Save command line */
|
||||||
* segment registers set to 4GB flat mode, let's be sure and set up
|
test dword ptr [ebx + MB_INFO_FLAGS_OFFSET], MB_INFO_FLAG_COMMAND_LINE
|
||||||
* our own */
|
jz mb2
|
||||||
lgdt gdtptrhigh + INITIAL_BASE - FREELDR_BASE
|
mov esi, [ebx + MB_INFO_COMMAND_LINE_OFFSET]
|
||||||
/* Reload segment selectors */
|
mov edi, offset cmdline + INITIAL_BASE - FREELDR_BASE
|
||||||
//ljmp $PMODE_CS, $(mb1 + INITIAL_BASE - FREELDR_BASE)
|
mov ecx, CMDLINE_SIZE - 1
|
||||||
jmp far ptr PMODE_CS: (mb1 + INITIAL_BASE - FREELDR_BASE)
|
|
||||||
mb1:
|
mb1:
|
||||||
mov dx, PMODE_DS
|
lodsb
|
||||||
mov ds, dx
|
stosb
|
||||||
mov es, dx
|
test al, al
|
||||||
|
jz mb2
|
||||||
|
dec ecx
|
||||||
|
jnz mb1
|
||||||
|
|
||||||
/* Check for valid multiboot signature */
|
mb2:
|
||||||
cmp eax, MULTIBOOT_BOOTLOADER_MAGIC
|
/* See if the boot device was passed in */
|
||||||
jne mbfail
|
test dword ptr [ebx + MB_INFO_FLAGS_OFFSET], MB_INFO_FLAG_BOOT_DEVICE
|
||||||
|
|
||||||
/* Store multiboot info in a safe place */
|
/* If no boot device known, assume first partition of first harddisk */
|
||||||
mov esi, ebx
|
mov dx, HEX(0180)
|
||||||
mov edi, offset mb_info + INITIAL_BASE - FREELDR_BASE
|
jz mb3
|
||||||
mov ecx, MB_INFO_SIZE
|
|
||||||
rep movsb
|
/* Load boot drive into DL, boot partition into DH */
|
||||||
|
mov edx, [ebx + MB_INFO_BOOT_DEVICE_OFFSET]
|
||||||
|
bswap edx
|
||||||
|
inc dh
|
||||||
|
|
||||||
/* Save commandline */
|
|
||||||
mov edx, [ebx + MB_INFO_FLAGS_OFFSET]
|
|
||||||
test dword ptr [ebx + MB_INFO_FLAGS_OFFSET], MB_INFO_FLAG_COMMAND_LINE
|
|
||||||
jz mb3
|
|
||||||
mov esi, [ebx + MB_INFO_COMMAND_LINE_OFFSET]
|
|
||||||
mov edi, offset cmdline + INITIAL_BASE - FREELDR_BASE
|
|
||||||
mov ecx, CMDLINE_SIZE
|
|
||||||
mb2: lodsb
|
|
||||||
stosb
|
|
||||||
test al, al
|
|
||||||
jz mb3
|
|
||||||
dec ecx
|
|
||||||
jnz mb2
|
|
||||||
mb3:
|
mb3:
|
||||||
|
/* Relocate itself to lower address */
|
||||||
|
mov esi, INITIAL_BASE
|
||||||
|
mov edi, FREELDR_BASE
|
||||||
|
mov ecx, (offset __bss_start__ - FREELDR_BASE + 3)
|
||||||
|
shr ecx, 2
|
||||||
|
rep movsd
|
||||||
|
|
||||||
/* Copy to low mem */
|
/* Clean out bss */
|
||||||
mov esi, INITIAL_BASE
|
xor eax, eax
|
||||||
mov edi, FREELDR_BASE
|
mov ecx, offset __bss_end__ + 3
|
||||||
mov ecx, (offset __bss_end__ - FREELDR_BASE)
|
sub ecx, offset __bss_start__
|
||||||
add ecx, 3
|
shr ecx, 2
|
||||||
shr ecx, 2
|
rep stosd
|
||||||
rep movsd
|
|
||||||
|
|
||||||
/* Load the GDT and IDT */
|
/* Load segment registers for real-address mode */
|
||||||
lgdt gdtptr
|
lgdt gdtptr
|
||||||
lidt i386idtptr
|
mov ax, HEX(10)
|
||||||
|
mov ds, ax
|
||||||
|
mov es, ax
|
||||||
|
mov fs, ax
|
||||||
|
mov gs, ax
|
||||||
|
mov ss, ax
|
||||||
|
|
||||||
/* Clear prefetch queue & correct CS,
|
/* Jump to relocated code */
|
||||||
* jump to low mem */
|
ljmp HEX(08), mb4
|
||||||
//ljmp $PMODE_CS, $mb4
|
|
||||||
jmp far ptr PMODE_CS:mb4
|
.code16
|
||||||
mb4:
|
mb4:
|
||||||
/* Reload segment selectors */
|
/* Disable protected mode */
|
||||||
mov dx, PMODE_DS
|
mov eax, cr0
|
||||||
mov ds, dx
|
and eax, CR0_PE_CLR
|
||||||
mov es, dx
|
mov cr0, eax
|
||||||
mov fs, dx
|
|
||||||
mov gs, dx
|
|
||||||
mov ss, dx
|
|
||||||
mov esp, STACK32ADDR
|
|
||||||
|
|
||||||
mov ebx, offset mb_info
|
/* Jump to real entry point */
|
||||||
/* See if the boot device was passed in */
|
ljmp16 0, FREELDR_BASE
|
||||||
mov edx, [ebx + MB_INFO_FLAGS_OFFSET]
|
|
||||||
test edx, MB_INFO_FLAG_BOOT_DEVICE
|
|
||||||
jz mb5
|
|
||||||
/* Retrieve boot device info */
|
|
||||||
mov eax, [ebx + MB_INFO_BOOT_DEVICE_OFFSET]
|
|
||||||
shr eax, 16
|
|
||||||
inc al
|
|
||||||
mov byte ptr [_FrldrBootPartition], al
|
|
||||||
mov byte ptr [_FrldrBootDrive], ah
|
|
||||||
jmp mb6
|
|
||||||
mb5: /* No boot device known, assume first partition of first harddisk */
|
|
||||||
mov byte ptr [_FrldrBootDrive], HEX(80)
|
|
||||||
mov byte ptr [_FrldrBootPartition], 1
|
|
||||||
mb6:
|
|
||||||
/* Check for command line */
|
|
||||||
mov eax, offset cmdline
|
|
||||||
test dword ptr [ebx + MB_INFO_FLAGS_OFFSET], MB_INFO_FLAG_COMMAND_LINE
|
|
||||||
jnz mb7
|
|
||||||
xor eax, eax
|
|
||||||
mb7:
|
|
||||||
|
|
||||||
/* GO! */
|
/* Force 8-byte alignment */
|
||||||
push eax
|
.align 8
|
||||||
call _BootMain
|
|
||||||
|
|
||||||
mbfail:
|
|
||||||
int 3
|
|
||||||
mbstop: jmp mbstop /* We should never get here */
|
|
||||||
|
|
||||||
mb_info:
|
|
||||||
.fill MB_INFO_SIZE, 1, 0
|
|
||||||
|
|
||||||
cmdline:
|
|
||||||
.fill CMDLINE_SIZE, 1, 0
|
|
||||||
|
|
||||||
.align 4 /* force 4-byte alignment */
|
|
||||||
gdt:
|
gdt:
|
||||||
/* NULL Descriptor */
|
/* 16-bit flat CS (!) */
|
||||||
.word HEX(0000)
|
.word HEX(FFFF)
|
||||||
.word HEX(0000)
|
.word HEX(0000)
|
||||||
.word HEX(0000)
|
.word HEX(9B00)
|
||||||
.word HEX(0000)
|
.word HEX(008F)
|
||||||
|
|
||||||
/* 32-bit flat CS */
|
/* 16-bit real mode DS */
|
||||||
.word HEX(FFFF)
|
.word HEX(FFFF)
|
||||||
.word HEX(0000)
|
.word HEX(0000)
|
||||||
.word HEX(9A00)
|
.word HEX(9300)
|
||||||
.word HEX(00CF)
|
.word HEX(0000)
|
||||||
|
|
||||||
/* 32-bit flat DS */
|
/* GDT pointer */
|
||||||
.word HEX(FFFF)
|
|
||||||
.word HEX(0000)
|
|
||||||
.word HEX(9200)
|
|
||||||
.word HEX(00CF)
|
|
||||||
|
|
||||||
/* 16-bit real mode CS */
|
|
||||||
.word HEX(FFFF)
|
|
||||||
.word HEX(0000)
|
|
||||||
.word HEX(9E00)
|
|
||||||
.word HEX(0000)
|
|
||||||
|
|
||||||
/* 16-bit real mode DS */
|
|
||||||
.word HEX(FFFF)
|
|
||||||
.word HEX(0000)
|
|
||||||
.word HEX(9200)
|
|
||||||
.word HEX(0000)
|
|
||||||
|
|
||||||
/* GDT table pointer */
|
|
||||||
gdtptr:
|
gdtptr:
|
||||||
.word HEX(27) /* Limit */
|
.word HEX(17) /* Limit */
|
||||||
.long gdt /* Base Address */
|
.long gdt - 8 /* Base Address */
|
||||||
|
|
||||||
/* Initial GDT table pointer for multiboot */
|
PUBLIC cmdline
|
||||||
gdtptrhigh:
|
cmdline:
|
||||||
.word HEX(27) /* Limit */
|
.space CMDLINE_SIZE
|
||||||
.long gdt + INITIAL_BASE - FREELDR_BASE /* Base Address */
|
|
||||||
|
END
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue