Reporting back...
I have been able to get the real mode code working using MichaelPetch's suggestion. Thank you bellezzasolo for responding with your suggestion too
I tried to adapt some parts of your Stackoverflow linker script Michael and found a working formula. I have been able to:
0. Copy realmode code from 0x100000 to 0x1000
a. Jump to 0x1000 and return to real mode and execute an int 0x10 to print $'a' to the screen
b. Run one iteration of the meme820 test successfully.
c. Return to protected mode and do the pic, pit, interrupts, paging etc.
This is my current linker script. They still seem like magic but I tried to pick out the relevant lines from your example. It didn't take cherry picking lines long before I got something that seemed to do as what you describe:
Code:
OUTPUT_FORMAT("elf32-i386")
ENTRY(_start)
PHYSICAL_BASE_ADDRESS = 0x00100000;
REAL_BASE_ADDRESS = 0x1000;
SECTIONS
{
/* Set the counter to 0x100000 */
. = PHYSICAL_BASE_ADDRESS;
/* Find the distance between 0x100000 - 0x1000 => 0xff000 */
__physreal_diff = . - REAL_BASE_ADDRESS;
/* Tell the linker that the .realmode section should have virtual addresses */
/* generated at 0x1000, but is loaded at 0x100000 */
.realmode REAL_BASE_ADDRESS : AT(ADDR(.realmode) + __physreal_diff) {
__realmode_vma_start = .;
/* LOADADDR is the LMA of the specified section */
__realmode_lma_start = LOADADDR(.realmode);
*(.text.realmode);
*(.data.realmode);
*(.multiboot);
}
/* Align at 4 Bytes and define some new symbols in our image we can refernce */
. = ALIGN(4);
__realmode_vma_end = .;
__realmode_secsize = ((__realmode_vma_end)-(__realmode_vma_start));
/* Set virtual address counter to 0x100000 */
. += __physreal_diff;
.text ALIGN(4K) : AT(ADDR(.text))
{
*(.text);
}
/* Read-only data. */
.rodata BLOCK(4K) : ALIGN(4K)
{
*(.rodata)
}
/* Read-write data (initialized) */
.data BLOCK(4K) : ALIGN(4K)
{
*(.data)
}
/* Read-write data (uninitialized) and stack */
.bss BLOCK(4K) : ALIGN(4K)
{
*(COMMON)
*(.bss)
}
/* Put other sections the compiler generates here */
}
I had a some issues that I somehow found ways around, but don't fully understand at the moment and will probably have to go back and work through:
1) I could not get the multiboot section before the .realmode section as you did in your linker script. The multitboot header was consistently moved to be the last section in the output binary (verified by readelf, IDA (free version) and running it!) if I mimicked your script. I could not figure out why this is occurring. I can prevent this is if I included the *(.multiboot) before or after the .realmode.* sections (latter is currently in my linker.ld example). My concern with this is that I am either stepping around or including the multiboot header when I copy the real mode code. My attempts to define symbols to exclude it have failed.
2) Since I was originally loading the kernel to 0x1000, I had identity mapped the first (1024*4096) Bytes and everything worked fine when I turned paging on. Now that my kernel was loaded to 0x100000, it didn't work
I mapped the the whole 0xc0000000 page table to 0x100000+ addresses attempting to map .rodata, .bss, .text etc. I think the text segment works fine. However, I am getting page faults in 0x100100 - 0x1001ff range. I figure that not all code might be relatively addressed and that some addresses might be absolute 0x100000's since I generated these virtual addresses. I guess this is normal? Though I haven't nailed down exactly what is causing the page fault yet.
Thanks again!