SFI systems support
Moderator: Moderator Team
Re: SFI systems support
Questions about freeldr multiboot code. I testing it on VM and simulator and found potential bugs:
Base address of freeldr_pe.exe is 10000, and multiboot code is located after this address. When it switching to real mode, final jump "ljmp16 0, FREELDR_BASE" may not execute as it located after first 64kb, but realmode IP register is 16 bit.
Also, manuals recommend to set IDT to 3ff, 0 before entering real mode, but it is not done in freeldr.
Freeldr still works on my device, but anyone can explain, this code is correct for all real CPUs?
P.S. About VGA/Vulkan - source code of linux GMA500/600 drivers was always available, Vulkan GPU is not related to SFI platforms.
Base address of freeldr_pe.exe is 10000, and multiboot code is located after this address. When it switching to real mode, final jump "ljmp16 0, FREELDR_BASE" may not execute as it located after first 64kb, but realmode IP register is 16 bit.
Also, manuals recommend to set IDT to 3ff, 0 before entering real mode, but it is not done in freeldr.
Freeldr still works on my device, but anyone can explain, this code is correct for all real CPUs?
P.S. About VGA/Vulkan - source code of linux GMA500/600 drivers was always available, Vulkan GPU is not related to SFI platforms.
Re: SFI systems support
There seems to be some misconceptions.
First, for reference, here is the multiboot support code:
https://git.reactos.org/?p=reactos.git; ... c3e9d37c60
We adhere to the Multiboot 0.96 specification: https://www.gnu.org/software/grub/manua ... der-layout
According to that specification, "The Multiboot header must be contained completely within the first 8192 bytes of the OS image". It is this point that you need to verify. This is relative to the beginning of the image that is being loaded by the compliant loader (e.g. GRUB).
GRUB will load freeldr.sys (that contains freeldr_pe.exe) at some address (higher than 1MB, and we tell it, via the multiboot header, to load it at some random 2MB address, see the INITIAL_BASE variable).
After loading, the multiboot stub code is run, and relocates the whole image down to FREELDR_BASE (which is under 1MB: its value is `#define FREELDR_BASE HEX(F800)`). So to me, "ljmp16 0, FREELDR_BASE" looks quite fine.
The IDT set to 3ff is done however, for example here: https://git.reactos.org/?p=reactos.git; ... d37c60#l97 (and see rmode_idtptr at the end of this file), where we need to be consistent as this is the implementation of the real-mode <--> protected-mode switch (that we use to switch back and forth between these two modes, when we call 16-bit code from 32-bit protected mode).
First, for reference, here is the multiboot support code:
https://git.reactos.org/?p=reactos.git; ... c3e9d37c60
We adhere to the Multiboot 0.96 specification: https://www.gnu.org/software/grub/manua ... der-layout
According to that specification, "The Multiboot header must be contained completely within the first 8192 bytes of the OS image". It is this point that you need to verify. This is relative to the beginning of the image that is being loaded by the compliant loader (e.g. GRUB).
GRUB will load freeldr.sys (that contains freeldr_pe.exe) at some address (higher than 1MB, and we tell it, via the multiboot header, to load it at some random 2MB address, see the INITIAL_BASE variable).
After loading, the multiboot stub code is run, and relocates the whole image down to FREELDR_BASE (which is under 1MB: its value is `#define FREELDR_BASE HEX(F800)`). So to me, "ljmp16 0, FREELDR_BASE" looks quite fine.
This is not done here because the idea is that we don't care about all the work GRUB has done to put us in protected mode: we just want to discard everything and go back to real mode, **as if** it was the real mode freeldr started with by booting "normally" from a 16-bit bootsector.Also, manuals recommend to set IDT to 3ff, 0 before entering real mode, but it is not done in freeldr.
The IDT set to 3ff is done however, for example here: https://git.reactos.org/?p=reactos.git; ... d37c60#l97 (and see rmode_idtptr at the end of this file), where we need to be consistent as this is the implementation of the real-mode <--> protected-mode switch (that we use to switch back and forth between these two modes, when we call 16-bit code from 32-bit protected mode).
Re: SFI systems support
There is 2 stages:
1 PM32 -> PM16
2 PM16 -> RM
RM code is located at f800, but PM16 entry point (mb4 label in multiboot.S) at 102e4:
mb4: //102e4
mov eax, cr0
and eax, CR0_PE_CLR
mov cr0, eax
//at this point CPU will switch to real mode and IP register losing its high 16 bits (102ee -> 2ee), so next jump may be not executed
102ee: ljmp16 0, FREELDR_BASE //jmp to f800
Re: SFI systems support
What are the settings of the CS segment at this point? What does the GDT table contents do regarding it?//at this point CPU will switch to real mode and IP register losing its high 16 bits (102ee -> 2ee), so next jump may be not executed
Re: SFI systems support
Yep, and does the CS segment get set to a sane value? Because if so, the physical address 102ee could perhaps still be accessible, if CS == "correct value" (to be determined) and IP == 2ee.
Re: SFI systems support
After mov cr0, eax CS value and its effect remains same as before (8 = "16-bit flat CS"), only IP value is affected.
I move PM16 code to ff00 address and now it works both on VM and real machine.
Dirty hack code:
mb3:
mov esi, offset mb4
mov edi, 0xff00
mov ecx, gdt - mb4
rep movsb
...
/* Jump to relocated code */
ljmp HEX(08), 0xff00
- binarymaster
- Posts: 482
- Joined: Sun Nov 16, 2014 7:05 pm
- Location: Russia, Moscow
- Contact:
Re: SFI systems support
Hi, I have created a git branch for your changes, it compiles without problems on gcc i386, but there are some errors when compiling for amd64 and with MSVC compilers:Xen wrote: ↑Wed Dec 15, 2021 6:31 pm Sources is here: https://gitlab.com/XenRE/sfi-freeldr
I decide to pack all new/modified files to archive, you can extract it over existing ReactOS sources and build. Sources is updated to lastest version from github.
Common changes: fixes in fs.c (described above), new CallFar16 realmode function, new bootpath command line argument.
Warning: I set [set(SARCH "sfi"] in base\sdk\cmake\config.cmake so SFI build will be default. Set it back to "pc" before merging with main repository.
Code: Select all
From build-linux (gcc, amd64, Debug):
boot/freeldr/freeldr/arch/realmode/amd64.S:383: Error: attempt to move .org backwards
From build-msvc (windows-latest, 14.2, i386, Debug):
boot\freeldr\freeldr\arch\drivers\SfiMcfgPci\SfiMcfgPci.c(1934) : error C4700: uninitialized local variable 'Status' used
by Stas'M | https://github.com/binarymaster
Re: SFI systems support
Hi.
Fix: remove declaration EFI_STATUS Status; and replace return Status; to return EFI_SUCCESS;binarymaster wrote: ↑Wed May 11, 2022 4:34 pm boot\freeldr\freeldr\arch\drivers\SfiMcfgPci\SfiMcfgPci.c(1934) : error C4700: uninitialized local variable 'Status' used
This code is a part of original ROS sources: https://github.com/reactos/reactos/blob ... de/amd64.Sbinarymaster wrote: ↑Wed May 11, 2022 4:34 pm boot/freeldr/freeldr/arch/realmode/amd64.S:383: Error: attempt to move .org backwards
Re: SFI systems support
hi i have a zenfone 2 and im willing to help test. Do yall have discord? my discord is floppa2#6312 if you wanna talk to me cause i check that alot more often than i would check here.
Last edited by amyfloppa on Wed Jun 01, 2022 8:29 pm, edited 1 time in total.
Re: SFI systems support
Hi. If you have questions - you can ask here or via PM. First, you need to root your device, and please make dump of first 1MB ram and MCFG table.
If your device using x64 android, you need this x64 rawexec to run freeldr. Also you need to find VGA BIOS, compatible with your device.
- Attachments
-
- rawexec64.zip
- (313.32 KiB) Downloaded 48 times
Who is online
Users browsing this forum: Google [Bot], Majestic-12 [Bot] and 70 guests