mirror of
https://github.com/reactos/reactos.git
synced 2025-01-04 21:38:43 +00:00
[FREELDR]
Make freeldr/setupldr composed of a PE file and prepended raw 16bit code. The 16 bit code starts with the usual fathelp code. This brings back support for fragmented fat12/16 disks. Later all 16 bit code is supposed to go into the raw binary chunk to be able to build freeldr with MSVC. svn path=/trunk/; revision=52204
This commit is contained in:
parent
6a588bbcd4
commit
8c46f42495
9 changed files with 634 additions and 41 deletions
|
@ -227,12 +227,7 @@ FoundFreeLoader:
|
|||
// to the helper code. Skip the first three bytes
|
||||
// because they contain a jump instruction to skip
|
||||
// over the helper code in the FreeLoader image.
|
||||
//jmp 0000:9003h
|
||||
push 0 // push segment (0x0000)
|
||||
mov bx, [HEX(8000) + HEX(0A8)] // load the RVA of the EntryPoint into eax
|
||||
add bx, HEX(8003) // RVA -> VA and skip 3 bytes (jump to fathelper code)
|
||||
push bx // push offset
|
||||
retf // Transfer control to FreeLoader
|
||||
ljmp16 0, HEX(8003)
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -420,11 +420,8 @@ LoadFileDone:
|
|||
mov dl, byte ptr BP_REL(BootDrive) // Load boot drive into DL
|
||||
mov dh, byte ptr ds:[BootPartition] // Load boot partition into DH
|
||||
|
||||
push 0 // push segment (0x0000)
|
||||
mov eax, dword ptr ds:[HEX(8000) + HEX(0A8)] // load the RVA of the EntryPoint into eax
|
||||
add eax, HEX(8000) // RVA -> VA
|
||||
push ax // push offset
|
||||
retf // Transfer control to FreeLoader
|
||||
/* Transfer execution to the bootloader */
|
||||
ljmp16 0, HEX(8000)
|
||||
|
||||
// Returns the FAT entry for a given cluster number
|
||||
// On entry EAX has cluster number
|
||||
|
|
|
@ -372,12 +372,9 @@ get_fs_structures:
|
|||
|
||||
mov dl, byte ptr ds:[DriveNo] // dl = boot drive
|
||||
mov dh, 0 // dh = boot partition
|
||||
push 0 // push segment (0x0000)
|
||||
mov eax, dword ptr ds:[HEX(8000) + HEX(0A8)] // load the RVA of the EntryPoint into eax
|
||||
add eax, HEX(8000) // RVA -> VA
|
||||
push ax // push offset
|
||||
retf // Transfer control to ROSLDR
|
||||
|
||||
/* Transfer execution to the bootloader */
|
||||
ljmp16 0, HEX(8000)
|
||||
|
||||
//
|
||||
// searchdir:
|
||||
|
|
|
@ -14,7 +14,6 @@ if(ARCH MATCHES i386)
|
|||
arch/i386/realmode.S)
|
||||
else()
|
||||
list(APPEND FREELDR_STARTUP_SOURCE
|
||||
arch/i386/fathelp.S
|
||||
arch/i386/arch.S)
|
||||
endif()
|
||||
elseif(ARCH MATCHES amd64)
|
||||
|
@ -23,7 +22,6 @@ elseif(ARCH MATCHES amd64)
|
|||
arch/amd64/stubs.S)
|
||||
else()
|
||||
list(APPEND FREELDR_STARTUP_SOURCE
|
||||
arch/i386/fathelp.S
|
||||
arch/amd64/arch.S)
|
||||
endif()
|
||||
endif()
|
||||
|
@ -182,6 +180,11 @@ set_source_files_properties(${FREELDR_ARCH_SOURCE} PROPERTIES COMPILE_DEFINITION
|
|||
add_library(freeldr_arch ${FREELDR_ARCH_SOURCE})
|
||||
add_dependencies(freeldr_arch bugcodes)
|
||||
|
||||
CreateBootSectorTarget2(frldr16
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/arch/realmode/i386.S
|
||||
${CMAKE_CURRENT_BINARY_DIR}/frldr16.bin
|
||||
8000)
|
||||
|
||||
list(APPEND FREELDR_SOURCE
|
||||
bootmgr.c
|
||||
${FREELDR_STARTUP_SOURCE}
|
||||
|
@ -189,24 +192,23 @@ list(APPEND FREELDR_SOURCE
|
|||
${FREELDR_BASE_SOURCE}
|
||||
)
|
||||
|
||||
add_library(freeldr SHARED ${FREELDR_SOURCE})
|
||||
add_executable(freeldr_pe ${FREELDR_SOURCE})
|
||||
|
||||
if(NOT MSVC)
|
||||
set_target_properties(freeldr PROPERTIES LINK_FLAGS "-Wl,--strip-all -Wl,--exclude-all-symbols -Wl,--file-alignment,0x1000 -Wl,-T,${CMAKE_CURRENT_SOURCE_DIR}/freeldr_i386.lnk" SUFFIX ".sys")
|
||||
set_image_base(freeldr 0x8000)
|
||||
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")
|
||||
else()
|
||||
set_target_properties(freeldr 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" SUFFIX ".sys")
|
||||
set_image_base(freeldr 0x10000)
|
||||
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()
|
||||
|
||||
set_subsystem(freeldr native)
|
||||
set_entrypoint(freeldr mainCRTStartup)
|
||||
set_subsystem(freeldr_pe native)
|
||||
set_image_base(freeldr_pe 0x9000)
|
||||
set_entrypoint(freeldr_pe mainCRTStartup)
|
||||
|
||||
if(ARCH MATCHES i386)
|
||||
target_link_libraries(freeldr mini_hal)
|
||||
target_link_libraries(freeldr_pe mini_hal)
|
||||
endif()
|
||||
|
||||
target_link_libraries(freeldr
|
||||
target_link_libraries(freeldr_pe
|
||||
freeldr_arch
|
||||
cportlib
|
||||
rossym
|
||||
|
@ -214,10 +216,17 @@ target_link_libraries(freeldr
|
|||
rtl
|
||||
libcntpr)
|
||||
|
||||
add_pch(freeldr include/freeldr.h)
|
||||
add_dependencies(freeldr asm)
|
||||
add_pch(freeldr_pe include/freeldr.h)
|
||||
add_dependencies(freeldr_pe asm)
|
||||
|
||||
add_cd_file(TARGET freeldr DESTINATION loader NO_CAB FOR all)
|
||||
concatenate_files(
|
||||
${CMAKE_CURRENT_BINARY_DIR}/frldr16.bin
|
||||
${CMAKE_CURRENT_BINARY_DIR}/freeldr_pe.exe
|
||||
${CMAKE_CURRENT_BINARY_DIR}/freeldr.sys)
|
||||
|
||||
add_custom_target(freeldr ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/freeldr.sys)
|
||||
|
||||
add_cd_file(FILE ${CMAKE_CURRENT_BINARY_DIR}/freeldr.sys DESTINATION loader NO_CAB FOR all)
|
||||
|
||||
list(APPEND SETUPLDR_MAIN_SOURCE
|
||||
bootmgr.c
|
||||
|
@ -238,23 +247,23 @@ list(APPEND SETUPLDR_SOURCE
|
|||
${FREELDR_BASE_SOURCE}
|
||||
${SETUPLDR_MAIN_SOURCE})
|
||||
|
||||
add_library(setupldr SHARED ${SETUPLDR_SOURCE})
|
||||
add_executable(setupldr_pe ${SETUPLDR_SOURCE})
|
||||
|
||||
if(NOT MSVC)
|
||||
set_target_properties(setupldr PROPERTIES LINK_FLAGS "-Wl,--strip-all -Wl,--exclude-all-symbols -Wl,--file-alignment,0x1000 -Wl,-T,${CMAKE_CURRENT_SOURCE_DIR}/freeldr_i386.lnk" SUFFIX ".sys" COMPILE_DEFINITIONS "FREELDR_REACTOS_SETUP")
|
||||
set_image_base(setupldr 0x8000)
|
||||
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")
|
||||
else()
|
||||
set_target_properties(setupldr PROPERTIES LINK_FLAGS "/DRIVER /SECTION:.text,ERWP,ALIGN=0x1000" SUFFIX ".sys" COMPILE_DEFINITIONS "FREELDR_REACTOS_SETUP")
|
||||
set_target_properties(setupldr_pe PROPERTIES LINK_FLAGS "/DRIVER /SECTION:.text,ERWP,ALIGN=0x1000" COMPILE_DEFINITIONS "FREELDR_REACTOS_SETUP")
|
||||
endif()
|
||||
|
||||
set_subsystem(setupldr native)
|
||||
set_entrypoint(setupldr mainCRTStartup)
|
||||
set_subsystem(setupldr_pe native)
|
||||
set_image_base(setupldr_pe 0x9000)
|
||||
set_entrypoint(setupldr_pe mainCRTStartup)
|
||||
|
||||
if(ARCH MATCHES i386)
|
||||
target_link_libraries(setupldr mini_hal)
|
||||
target_link_libraries(setupldr_pe mini_hal)
|
||||
endif()
|
||||
|
||||
target_link_libraries(setupldr
|
||||
target_link_libraries(setupldr_pe
|
||||
freeldr_arch
|
||||
cportlib
|
||||
rossym
|
||||
|
@ -262,7 +271,14 @@ target_link_libraries(setupldr
|
|||
rtl
|
||||
libcntpr)
|
||||
|
||||
add_dependencies(setupldr asm)
|
||||
add_dependencies(setupldr_pe asm)
|
||||
|
||||
add_cd_file(TARGET setupldr DESTINATION loader NO_CAB FOR all)
|
||||
concatenate_files(
|
||||
${CMAKE_CURRENT_BINARY_DIR}/frldr16.bin
|
||||
${CMAKE_CURRENT_BINARY_DIR}/setupldr_pe.exe
|
||||
${CMAKE_CURRENT_BINARY_DIR}/setupldr.sys)
|
||||
|
||||
add_custom_target(setupldr ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/setupldr.sys)
|
||||
|
||||
add_cd_file(FILE ${CMAKE_CURRENT_BINARY_DIR}/setupldr.sys DESTINATION loader NO_CAB FOR all)
|
||||
|
||||
|
|
|
@ -56,6 +56,7 @@ PUBLIC _mainCRTStartup // For Mingw32 builds where the linker looks for this sym
|
|||
_mainCRTStartup:
|
||||
PUBLIC start
|
||||
start:
|
||||
#if 0
|
||||
.byte HEX(e9)
|
||||
.byte HEX(fd)
|
||||
.byte HEX(01)
|
||||
|
@ -134,7 +135,7 @@ LoadFile_Done:
|
|||
|
||||
// Reads the entire FAT into memory at 7000:0000
|
||||
ReadFatIntoMemory:
|
||||
mov ax, [bp+HiddenSectors]
|
||||
mov ax, [bp+HiddenSectors]
|
||||
mov dx, [bp+HiddenSectors+2]
|
||||
add ax, [bp+ReservedSectors]
|
||||
adc dx, 0
|
||||
|
@ -233,6 +234,7 @@ msgLoading: .asciz "Loading FreeLoader...\r\n"
|
|||
|
||||
.org HEX(1fe) // Pad to 510 bytes
|
||||
.word HEX(0aa55) // BootSector signature
|
||||
#endif
|
||||
|
||||
.endcode16
|
||||
|
||||
|
|
225
reactos/boot/freeldr/freeldr/arch/realmode/amd64.S
Normal file
225
reactos/boot/freeldr/freeldr/arch/realmode/amd64.S
Normal file
|
@ -0,0 +1,225 @@
|
|||
|
||||
#include <asm.inc>
|
||||
#include <arch/pc/x86common.h>
|
||||
|
||||
#define IMAGE_DOS_HEADER_e_lfanew 36
|
||||
#define IMAGE_FILE_HEADER_SIZE 20
|
||||
#define IMAGE_OPTIONAL_HEADER_AddressOfEntryPoint 16
|
||||
|
||||
|
||||
.code16
|
||||
|
||||
/* fat helper code */
|
||||
#include "fathelp.inc"
|
||||
|
||||
.org 512
|
||||
RealEntryPoint:
|
||||
|
||||
cli
|
||||
|
||||
/* Setup real mode segment registers */
|
||||
xor ax, ax
|
||||
mov ds, ax
|
||||
mov es, ax
|
||||
mov fs, ax
|
||||
mov gs, ax
|
||||
mov ss, ax
|
||||
|
||||
/* checkPoint Charlie - where it all began... */
|
||||
mov si, offset CheckPoint0
|
||||
call writestr
|
||||
|
||||
/* Setup a real mode stack */
|
||||
mov sp, stack16
|
||||
|
||||
/* Zero BootDrive and BootPartition */
|
||||
xor eax, eax
|
||||
mov BootDrive, eax
|
||||
mov BootPartition, eax
|
||||
|
||||
/* Store the boot drive */
|
||||
mov BootDrive, dl
|
||||
|
||||
/* Store the boot partition */
|
||||
mov BootPartition, dh
|
||||
|
||||
/* Load the GDT */
|
||||
lgdt gdtptr
|
||||
/* Load the IDT */
|
||||
// lidt idtptr
|
||||
|
||||
call x86_16_EnableA20
|
||||
|
||||
/* checkPoint Charlie - where it all began... */
|
||||
mov si, offset CheckPoint1
|
||||
call writestr
|
||||
|
||||
call x86_16_BuildPageTables
|
||||
|
||||
/* checkPoint Charlie - where it all began... */
|
||||
mov si, offset CheckPoint2
|
||||
call writestr
|
||||
|
||||
/* Check if CPU supports CPUID */
|
||||
pushfd
|
||||
pop eax
|
||||
mov ebx, eax
|
||||
xor eax, HEX(00200000)
|
||||
push eax
|
||||
popfd
|
||||
pushfd
|
||||
pop eax
|
||||
cmp eax,ebx
|
||||
jz no_cpuid_support_detected
|
||||
|
||||
/* CPUID support detected - getting the PAE/PGE */
|
||||
|
||||
mov eax,1 // Fn0000_0001 - PAE in EDX[6]
|
||||
cpuid
|
||||
xor eax,eax
|
||||
and edx, HEX(00a0)
|
||||
test edx,edx // are PAE and PGE bits set?
|
||||
jz no_x64_support_detected
|
||||
|
||||
/* PAE and PGE are here */
|
||||
|
||||
xor edx, edx
|
||||
mov eax, HEX(80000001)
|
||||
cpuid
|
||||
and edx, HEX(20000000)
|
||||
test edx,edx
|
||||
jz no_x64_support_detected
|
||||
|
||||
/* X64 Processor */
|
||||
|
||||
/* checkPoint Charlie - where it all began... */
|
||||
mov si, offset CheckPoint3
|
||||
call writestr
|
||||
|
||||
/* Get address of optional header */
|
||||
mov eax, dword ptr ds:[FREELDR_PE_BASE + IMAGE_DOS_HEADER_e_lfanew]
|
||||
add eax, FREELDR_PE_BASE + 4 + IMAGE_FILE_HEADER_SIZE
|
||||
|
||||
/* Get address of entry point */
|
||||
mov eax, dword ptr ds:[eax + IMAGE_OPTIONAL_HEADER_AddressOfEntryPoint]
|
||||
|
||||
/* Store the address in the callback return variable */
|
||||
mov dword ptr ds:[CallbackReturnAddress], eax
|
||||
|
||||
switch64:
|
||||
mov
|
||||
jmp x86_16_ReturnToLong
|
||||
|
||||
|
||||
no_x64_support_detected:
|
||||
mov si, offset NotAnX64Processor // Loading message
|
||||
call writestr
|
||||
jmp fail
|
||||
|
||||
no_cpuid_support_detected:
|
||||
mov si, offset NoCPUIDSupport // Loading message
|
||||
call writestr
|
||||
|
||||
fail:
|
||||
jmp fail
|
||||
nop
|
||||
nop
|
||||
|
||||
/*
|
||||
* We define 512 2MB pages at the start of memory, so we can access the first
|
||||
* 1 GB as if paging was disabled
|
||||
*/
|
||||
x86_16_BuildPageTables:
|
||||
pusha
|
||||
push es
|
||||
|
||||
/* Get segment of pml4 */
|
||||
mov eax, offset pml4_startup
|
||||
shr eax, 4
|
||||
mov es, ax
|
||||
cld
|
||||
xor di, di
|
||||
|
||||
/* One entry in the PML4 pointing to PDP */
|
||||
mov eax, offset pdp_startup
|
||||
or eax, HEX(00f)
|
||||
stosd
|
||||
/* clear rest */
|
||||
xor eax, eax
|
||||
mov cx, HEX(03ff)
|
||||
rep stosd
|
||||
|
||||
/* One entry in the PDP pointing to PD */
|
||||
mov eax, offset pd_startup
|
||||
or eax, HEX(00f)
|
||||
stosd
|
||||
/* clear rest */
|
||||
xor eax, eax
|
||||
mov ecx, HEX(03ff)
|
||||
rep stosd
|
||||
|
||||
/* 512 entries in the PD defining a 2MB page each */
|
||||
mov ecx, 512
|
||||
mov eax, HEX(008f)
|
||||
|
||||
Bpt2:
|
||||
mov es: [di], eax
|
||||
mov dword ptr es: [di + 4], 0
|
||||
add eax, 512 << 12 // add 512 4k pages
|
||||
add di, 8
|
||||
|
||||
/* Loop it */
|
||||
dec cx
|
||||
jnz Bpt2
|
||||
|
||||
/* Return */
|
||||
pop es
|
||||
popa
|
||||
ret
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
x86_16_ReturnToLong:
|
||||
|
||||
cli
|
||||
|
||||
xor ax,ax
|
||||
mov ds,ax
|
||||
mov es,ax
|
||||
mov fs,ax
|
||||
mov gs,ax
|
||||
mov ss,ax
|
||||
|
||||
/* Get the return address off the stack */
|
||||
pop word ptr code64ret
|
||||
|
||||
/* Save 16-bit stack pointer */
|
||||
mov stack16, sp
|
||||
|
||||
mov eax, 0x00a0 // Set PAE and PGE: 10100000b
|
||||
mov cr4, eax
|
||||
|
||||
mov edx, offset pml4_startup // Point cr3 at PML4
|
||||
mov cr3, edx
|
||||
|
||||
mov ecx, HEX(0C0000080) // Specify EFER MSR
|
||||
|
||||
rdmsr // Enable long mode
|
||||
or eax, HEX(00000100)
|
||||
wrmsr
|
||||
|
||||
mov ebx, cr0 // Activate long mode
|
||||
or ebx, HEX(080000001) // by enabling paging and protection simultaneously
|
||||
mov cr0, ebx // skipping protected mode entirely
|
||||
|
||||
//jmp LMODE_CS:offset LongCat //Load CS with 64 bit segment and flush the instruction cache
|
||||
// Do a long jmp to the CallbackReturn address
|
||||
|
||||
|
||||
#include "helpers.inc"
|
||||
|
||||
.endcode16
|
||||
|
||||
END
|
225
reactos/boot/freeldr/freeldr/arch/realmode/fathelp.inc
Normal file
225
reactos/boot/freeldr/freeldr/arch/realmode/fathelp.inc
Normal file
|
@ -0,0 +1,225 @@
|
|||
// fathelp.S
|
||||
// FAT12/16 Boot Sector Helper Code
|
||||
// Copyright (c) 1998, 2001, 2002, 2003 Brian Palmer
|
||||
|
||||
//#include <asm.inc>
|
||||
|
||||
//org 8000h
|
||||
|
||||
//.text
|
||||
|
||||
#define BootSectorStackTop HEX(7bf2)
|
||||
#define DataAreaStartHigh 2
|
||||
#define DataAreaStartLow 4
|
||||
#define BiosCHSDriveSizeHigh 6
|
||||
#define BiosCHSDriveSizeLow 8
|
||||
#define BiosCHSDriveSize 8
|
||||
#define ReadSectorsOffset 10
|
||||
#define ReadClusterOffset 12
|
||||
#define PutCharsOffset 14
|
||||
|
||||
#define OEMName 3
|
||||
#define BytesPerSector 11
|
||||
#define SectsPerCluster 13
|
||||
#define ReservedSectors 14
|
||||
#define NumberOfFats 16
|
||||
#define MaxRootEntries 17
|
||||
#define TotalSectors 19
|
||||
#define MediaDescriptor 21
|
||||
#define SectorsPerFat 22
|
||||
#define SectorsPerTrack 24
|
||||
#define NumberOfHeads 26
|
||||
#define HiddenSectors 28
|
||||
#define TotalSectorsBig 32
|
||||
#define BootDrive 36
|
||||
#define Reserved 37
|
||||
#define ExtendSig 38
|
||||
#define SerialNumber 39
|
||||
#define VolumeLabel 43
|
||||
#define FileSystem 54
|
||||
|
||||
#define BootPartition HEX(7dfd)
|
||||
|
||||
|
||||
// This code will be stored in the first 512 bytes
|
||||
// of freeldr.sys. The first 3 bytes will be a jmp
|
||||
// instruction to skip past the FAT helper code
|
||||
// that is stored in the rest of the 512 bytes.
|
||||
//
|
||||
|
||||
PUBLIC start
|
||||
start:
|
||||
// This code is loaded at 0000:8000 so we have to
|
||||
// encode a jmp instruction to jump to 0000:8200
|
||||
.byte HEX(e9), HEX(fd), HEX(01)
|
||||
|
||||
// Now starts the extra boot code that we will store
|
||||
// in the first 512 bytes of freeldr.sys. This code
|
||||
// allows the FAT12/16 bootsector to navigate the
|
||||
// FAT table so that we can still load freeldr.sys
|
||||
// even if it is fragmented.
|
||||
|
||||
|
||||
FatHelperEntryPoint:
|
||||
/* First save AX - the start cluster of freeldr.sys */
|
||||
push ax
|
||||
|
||||
/* Display "Loading FreeLoader..." message */
|
||||
mov si, offset msgLoading
|
||||
call word ptr [bp-PutCharsOffset]
|
||||
|
||||
call ReadFatIntoMemory
|
||||
|
||||
/* Restore AX (start cluster) */
|
||||
pop ax
|
||||
|
||||
// AX has start cluster of freeldr.sys
|
||||
mov bx, HEX(800)
|
||||
mov es,bx
|
||||
|
||||
LoadFile:
|
||||
push ax
|
||||
call IsFat12
|
||||
pop ax
|
||||
jnc LoadFile2
|
||||
cmp ax, HEX(0ff8) // Check to see if this is the last cluster in the chain
|
||||
jmp LoadFile3
|
||||
|
||||
LoadFile2:
|
||||
cmp ax, HEX(0fff8)
|
||||
LoadFile3:
|
||||
jae LoadFile_Done // If so continue, if not then read then next one
|
||||
push ax
|
||||
xor bx,bx // Load ROSLDR starting at 0000:8000h
|
||||
push es
|
||||
call word ptr [bp-ReadClusterOffset]
|
||||
pop es
|
||||
|
||||
xor bx,bx
|
||||
mov bl, [bp+SectsPerCluster]
|
||||
shl bx,5 // BX = BX * 512 / 16
|
||||
mov ax,es // Increment the load address by
|
||||
add ax,bx // The size of a cluster
|
||||
mov es,ax
|
||||
|
||||
call IsFat12
|
||||
pop ax
|
||||
push es
|
||||
jnc LoadFile4
|
||||
call GetFatEntry12 // Get the next entry
|
||||
jmp LoadFile5
|
||||
LoadFile4:
|
||||
call GetFatEntry16
|
||||
LoadFile5:
|
||||
pop es
|
||||
|
||||
jmp LoadFile // Load the next cluster (if any)
|
||||
|
||||
LoadFile_Done:
|
||||
mov dl, byte ptr [bp+BootDrive] // Load the boot drive into DL
|
||||
mov dh, byte ptr ds:[BootPartition] // Load the boot partition into DH
|
||||
|
||||
/* continue where other bootsectors start */
|
||||
jmp start
|
||||
|
||||
|
||||
// Reads the entire FAT into memory at 7000:0000
|
||||
ReadFatIntoMemory:
|
||||
mov ax, [bp+HiddenSectors]
|
||||
mov dx, [bp+HiddenSectors+2]
|
||||
add ax, [bp+ReservedSectors]
|
||||
adc dx, 0
|
||||
mov cx, [bp+SectorsPerFat]
|
||||
mov bx, HEX(7000)
|
||||
mov es,bx
|
||||
xor bx,bx
|
||||
call word ptr [bp-ReadSectorsOffset]
|
||||
ret
|
||||
|
||||
|
||||
// Returns the FAT entry for a given cluster number for 16-bit FAT
|
||||
// On entry AX has cluster number
|
||||
// On return AX has FAT entry for that cluster
|
||||
GetFatEntry16:
|
||||
mov cx,2 // AX = AX * 2 (since FAT16 entries are 2 bytes)
|
||||
mul cx
|
||||
shl dx,12
|
||||
|
||||
mov bx, HEX(7000)
|
||||
add bx,dx
|
||||
mov es,bx
|
||||
mov bx,ax // Restore FAT entry offset
|
||||
mov ax, es:[bx] // Get FAT entry
|
||||
|
||||
ret
|
||||
|
||||
|
||||
// Returns the FAT entry for a given cluster number for 12-bit FAT
|
||||
// On entry AX has cluster number
|
||||
// On return AX has FAT entry for that cluster
|
||||
GetFatEntry12:
|
||||
push ax
|
||||
mov cx,ax
|
||||
shr ax,1
|
||||
add ax,cx // AX = AX * 1.5 (AX = AX + (AX / 2)) (since FAT12 entries are 12 bits)
|
||||
|
||||
mov bx, HEX(7000)
|
||||
mov es,bx
|
||||
mov bx,ax // Put FAT entry offset into BX
|
||||
mov ax, es:[bx] // Get FAT entry
|
||||
pop cx // Get cluster number from stack
|
||||
and cx,1
|
||||
jz UseLow12Bits
|
||||
and ax, HEX(0fff0)
|
||||
shr ax,4
|
||||
jmp GetFatEntry12_Done
|
||||
|
||||
UseLow12Bits:
|
||||
and ax, HEX(0fff)
|
||||
|
||||
GetFatEntry12_Done:
|
||||
|
||||
ret
|
||||
|
||||
|
||||
// Returns CF = 1 if this is a FAT12 file system
|
||||
// Otherwise CF = 0 for FAT16
|
||||
IsFat12:
|
||||
|
||||
mov ebx, dword ptr [bp-DataAreaStartLow]
|
||||
// EBX now has the number of the starting sector of the data area
|
||||
// starting from the beginning of the disk, so subtrace hidden sectors
|
||||
sub ebx, dword ptr [bp+HiddenSectors]
|
||||
|
||||
|
||||
xor eax,eax
|
||||
mov ax, word ptr [bp+TotalSectors]
|
||||
cmp ax, 0
|
||||
jnz IsFat12_2
|
||||
mov eax, dword ptr [bp+TotalSectorsBig]
|
||||
|
||||
// EAX now contains the number of sectors on the volume
|
||||
|
||||
IsFat12_2:
|
||||
sub eax,ebx // Subtract data area start sector
|
||||
xor edx,edx // from total sectors of volume
|
||||
|
||||
// EDX:EAX now contains the number of data sectors on the volume
|
||||
movzx ebx, byte ptr [bp+SectsPerCluster]
|
||||
div ebx
|
||||
// EAX now has the number of clusters on the volume
|
||||
stc
|
||||
cmp eax,4085
|
||||
jb IsFat12_Done
|
||||
clc
|
||||
|
||||
IsFat12_Done:
|
||||
ret
|
||||
|
||||
|
||||
msgLoading: .asciz "Loading FreeLoader...\r\n"
|
||||
|
||||
.org 510 // Pad to 510 bytes
|
||||
.word HEX(0aa55) // BootSector signature
|
||||
|
||||
END
|
104
reactos/boot/freeldr/freeldr/arch/realmode/helpers.inc
Normal file
104
reactos/boot/freeldr/freeldr/arch/realmode/helpers.inc
Normal file
|
@ -0,0 +1,104 @@
|
|||
|
||||
Empty8042:
|
||||
.word 0x00eb,0x00eb // jmp $+2, jmp $+2
|
||||
in al, 0x64
|
||||
cmp al, 0xff // legacy-free machine without keyboard
|
||||
jz empty_8042_ret // controllers on Intel Macs read back 0xFF
|
||||
test al, 0x02
|
||||
jnz x86_16_Empty8042
|
||||
empty_8042_ret:
|
||||
ret
|
||||
|
||||
EnableA20:
|
||||
pusha
|
||||
call x86_16_Empty8042
|
||||
mov al, 0xD1 // command write
|
||||
out 0x64, al
|
||||
call x86_16_Empty8042
|
||||
mov al, 0xDF // A20 on
|
||||
out 0x60, al
|
||||
call x86_16_Empty8042
|
||||
popa
|
||||
ret
|
||||
|
||||
/*
|
||||
* writestr
|
||||
* si = pointer to zero terminated string
|
||||
*/
|
||||
writestr:
|
||||
pushfd
|
||||
pushad
|
||||
writestr_top:
|
||||
lodsb
|
||||
and al, al
|
||||
jz writestr_end
|
||||
call writechr
|
||||
jmp short writestr_top
|
||||
writestr_end:
|
||||
popad
|
||||
popfd
|
||||
ret
|
||||
|
||||
/*
|
||||
* writechr
|
||||
* al = character to output
|
||||
*/
|
||||
writechr:
|
||||
pushf
|
||||
pusha
|
||||
mov ah, 0x0E
|
||||
xor bx, bx
|
||||
int 0x10
|
||||
popa
|
||||
popf
|
||||
ret
|
||||
|
||||
//
|
||||
// writehex[248]: Write a hex number in (AL, AX, EAX) to the console
|
||||
//
|
||||
writehex2:
|
||||
pushfd
|
||||
pushad
|
||||
shl eax, 24
|
||||
mov cx, 2
|
||||
jmp short writehex_common
|
||||
writehex4:
|
||||
pushfd
|
||||
pushad
|
||||
shl eax, 16
|
||||
mov cx, 4
|
||||
jmp short writehex_common
|
||||
writehex8:
|
||||
pushfd
|
||||
pushad
|
||||
mov cx, 8
|
||||
writehex_common:
|
||||
.loop:
|
||||
rol eax, 4
|
||||
push eax
|
||||
and al, HEX(0F)
|
||||
cmp al, 10
|
||||
jae .high
|
||||
.low:
|
||||
add al, '0'
|
||||
jmp short .ischar
|
||||
.high:
|
||||
add al, 'A'-10
|
||||
.ischar:
|
||||
call writechr
|
||||
pop eax
|
||||
loop .loop
|
||||
popad
|
||||
popfd
|
||||
ret
|
||||
|
||||
SoftReboot:
|
||||
mov ax, HEX(40)
|
||||
mov ds, ax
|
||||
mov si, HEX(72)
|
||||
|
||||
/* Set the word at location 40:72 to 1234h */
|
||||
mov word ptr [si], HEX(1234)
|
||||
|
||||
/* and jump to location FFFF:0 in ROM */
|
||||
ljmp16 HEX(0FFFF), HEX(0000)
|
32
reactos/boot/freeldr/freeldr/arch/realmode/i386.S
Normal file
32
reactos/boot/freeldr/freeldr/arch/realmode/i386.S
Normal file
|
@ -0,0 +1,32 @@
|
|||
|
||||
#include <asm.inc>
|
||||
#include "../../include/arch/pc/x86common.h"
|
||||
|
||||
#define IMAGE_DOS_HEADER_e_lfanew 60
|
||||
#define IMAGE_FILE_HEADER_SIZE 20
|
||||
#define IMAGE_OPTIONAL_HEADER_AddressOfEntryPoint 16
|
||||
|
||||
.code16
|
||||
|
||||
/* fat helper code */
|
||||
#include "fathelp.inc"
|
||||
|
||||
.org 512
|
||||
RealEntryPoint:
|
||||
|
||||
/* Get address of optional header */
|
||||
mov eax, dword ptr ds:[FREELDR_PE_BASE + IMAGE_DOS_HEADER_e_lfanew]
|
||||
add eax, FREELDR_PE_BASE + 4 + IMAGE_FILE_HEADER_SIZE
|
||||
|
||||
/* Jump to address of entry point */
|
||||
mov eax, dword ptr ds:[eax + IMAGE_OPTIONAL_HEADER_AddressOfEntryPoint]
|
||||
add eax, FREELDR_PE_BASE
|
||||
jmp ax
|
||||
|
||||
|
||||
#include "helpers.inc"
|
||||
|
||||
.org (FREELDR_PE_BASE - FREELDR_BASE)
|
||||
.endcode16
|
||||
|
||||
END
|
Loading…
Reference in a new issue