No, I don't know if it's the only way, there may be better ones. Depends on how you want to do it.Silverhawk wrote: So, according to you, this is the only way to do the job being full multiboot compliant ?
OS memory structure
Re:OS memory structure
Re:OS memory structure
So, as I've promised, I've tried to code :
1) For setting up a temporary GDT with segments with bases of 0x40100000, I need to have my piece of code linked at 0x100000 in order to grub gives me the hand. no ?
2) Then, if I want my kernel to be located at virtual address 0xC0000000, I need to link the other part of my kernel at 0xC0000000.
The result is that I've my kernel covering 0x100000 to 0xC0000000 and a little more... So Bochs gives me the following error : "Error 28 : Selected Item cannot fit into memory" that seems normal !
What's the correct way to do it ?
Here's my code :
And my linker script file :
All comments and criticals are welcomed !
1) For setting up a temporary GDT with segments with bases of 0x40100000, I need to have my piece of code linked at 0x100000 in order to grub gives me the hand. no ?
2) Then, if I want my kernel to be located at virtual address 0xC0000000, I need to link the other part of my kernel at 0xC0000000.
The result is that I've my kernel covering 0x100000 to 0xC0000000 and a little more... So Bochs gives me the following error : "Error 28 : Selected Item cannot fit into memory" that seems normal !
What's the correct way to do it ?
Here's my code :
Code: Select all
[bits 32]
[global startAfterGrub] ; Entry point for the linker script
[extern paging_enable] ; Function that enables paging (in paging_enable.asm)
[extern startKernel] ; Entry point for the C kernel
[global gdt] ; GDT start address
[global idt] ; IDT start address
section .trampoline
startAfterGrub :
; We use a temporary GDT in order to jump at kernel virual address
lgdt [gdt48_ptr]
mov ax,GDT48_DATA_SEL
mov ds,ax
mov es,ax
mov ss,ax
mov fs,ax
mov gs,ax
jmp GDT48_CODE_SEL:startKernelASM
gdt48:
; NULL descriptor
dw 0 ; limit 15:0
dw 0 ; base 15:0
db 0 ; base 23:16
db 0 ; type
db 0 ; limit 19:16, flags
db 0 ; base 31:24
GDT48_CODE_SEL equ $-gdt48 ; use a base segment of 0x40100000, so the MMU will
dw 0FFFFh ; transform the offset startKernelASM = 0xC0000000
dw 0 ; in 0xC0000000 + 0x40100000 = 4Gb + 1Mb, that will be
db 10h ; truncate into 1Mb...
db 9Ah ; present,ring 0,code,non-conforming,readable
db 0CFh ; page-granular (4 gig limit), 32-bit
db 40h
GDT48_DATA_SEL equ $-gdt48
dw 0FFFFh
dw 0
db 10h
db 92h ; present, ring 0, data, expand-up, writable
db 0CFh ; page-granular (4 gig limit), 32-bit
db 40h
gdt48_end:
gdt48_ptr:
dw gdt48_end - gdt48 - 1
dd gdt48
;-----------------------------------------------------------------------------;
;-----------------------------------------------------------------------------;
Section .text
startKernelASM : /* linked at 0xC0000000*/
[...]
Section .multiboot
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Multiboot header for GRUB bootloader. This must be in the first 8K
; of the kernel file. We use the aout kludge so it works with ELF,
; DJGPP COFF, Win32 PE, or other formats.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
MULTIBOOT_PAGE_ALIGN equ 1<<0
MULTIBOOT_MEMORY_INFO equ 1<<1
MULTIBOOT_AOUT_KLUDGE equ 1<<16
MULTIBOOT_HEADER_MAGIC equ 0x1BADB002
MULTIBOOT_HEADER_FLAGS equ MULTIBOOT_PAGE_ALIGN | MULTIBOOT_MEMORY_INFO | MULTIBOOT_AOUT_KLUDGE
MULTIBOOT_CHECKSUM equ -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)
; these are in the linker script file
extern code, erodata, ebss
align 4
mboot:
dd MULTIBOOT_HEADER_MAGIC
dd MULTIBOOT_HEADER_FLAGS
dd MULTIBOOT_CHECKSUM
; aout kludge. These must be PHYSICAL addresses
dd mboot ; Start address of the multiboot header
dd code ; Physical address of the begining of the code segment
dd erodata ; Physical address of end of data data segment
dd ebss ; Physical address of end of bss segment
dd startAfterGrub ; Physical address where boot loader give us the hand
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;-----------------------------------------------------------------------------;
;-----------------------------------------------------------------------------;
Section .data
[...] /* definitive GDT and IDT */
;-----------------------------------------------------------------------------;
;-----------------------------------------------------------------------------;
Section .bss
resd 1024 ; 4ko Stack
stack:
Code: Select all
/* Generating elf binary format */
OUTPUT_FORMAT("elf32-i386","elf32-i386","elf32-i386")
/* Target architecture is i386 */
OUTPUT_ARCH("i386")
/* Entry point is startAfterGrub defined in jumToKernel.asm */
ENTRY(startAfterGrub)
/* Physical start address for the kernel */
Phys_Addr = 0x100000; /* 1 mega */
Virt_Addr = 0xc0000000;
SECTIONS
{
. = Phys_Addr;
.multiboot ALIGN(4) :
{
*(.multiboot)
. = ALIGN(4);
}
.trampoline :
{
*(.trampoline)
}
. = Virt_Addr;
/* Section .text for code */
.text ALIGN(4096) :
{
code = .;
*(.text*)
}
[...] /* and so on... */
All comments and criticals are welcomed !
Re:OS memory structure
Hi !
For those who are interested, I think I found a solution to my problem into grub tutorial : http://www.openbg.net/sto/os/xml/grub.html.
a solution may be, I quote :
The remaining is in the page linked above.
I've try it, and it seems to work...
But I've another little problem, gdb now doesn't seem to stop on break point ! (for debugging, I use bochs gdb's stub)
see you.
For those who are interested, I think I found a solution to my problem into grub tutorial : http://www.openbg.net/sto/os/xml/grub.html.
a solution may be, I quote :
Code: Select all
If the load address is beyond the end of RAM, you get error #28: Selected item cannot fit into memory.
[...]
Normally, the physical address is the same as the VMA, and is set either in the linker script or on the linker command line ("ld -Ttext=0x100000 ..."). If your version of 'ld' supports it, the physical and virtual addresses can be specified separately in the linker script using 'AT'
[...]
I've try it, and it seems to work...
But I've another little problem, gdb now doesn't seem to stop on break point ! (for debugging, I use bochs gdb's stub)
see you.