From eb6a12e18d45879ec383921f0c7378120b71d159 Mon Sep 17 00:00:00 2001 From: Alexey Gavrilov Date: Wed, 17 Dec 2025 14:13:08 +0700 Subject: Linker script rework `memory.ld` is a architecture-dependent ld config provides some general symbols which every `memory.ld` config must assign and memory regions associated with each output section. 'linker.ld' config file presents segments configuration. Multiboot section filling move in the 'linker.ld' file. Recommendation for further patches: controlled logic implementation for multiboot version and header/entries in build configuration tool (CMake or make). For instance, multiboot version and video mode selection through variable passing in build system: `cmake ... -DMULTIBOOT_VERSION=2 -DMULTIBOOT_VIDEO_MODE=TEXT_VIDEO_MODE` or 'export MULTIBOOT_VERSION=2; export MULTIBOOT_VIDEO_MODE=TEXT_VIDEO_MODE'. Then build system do proper filling of `.multiboot` section depends on passing variables. Signed-off-by: Alexey Gavrilov --- arch/x86/memory.ld | 13 ++++++++ kernel/boot.s | 29 ++---------------- kernel/linker.ld | 88 +++++++++++++++++++++++++++++++++++------------------- makefile | 6 ++-- 4 files changed, 77 insertions(+), 59 deletions(-) create mode 100644 arch/x86/memory.ld diff --git a/arch/x86/memory.ld b/arch/x86/memory.ld new file mode 100644 index 0000000..0226aca --- /dev/null +++ b/arch/x86/memory.ld @@ -0,0 +1,13 @@ +MEMORY + { + RAM : ORIGIN = 0x00100000, LENGTH = 1M + } + +REGION_ALIAS("REGION_MULTIBOOT", RAM); +REGION_ALIAS("REGION_TEXT", RAM); +REGION_ALIAS("REGION_RODATA", RAM); +REGION_ALIAS("REGION_DATA", RAM); +REGION_ALIAS("REGION_BSS", RAM); +REGION_ALIAS("REGION_COMMON", RAM); + +PROVIDE(START_ADDR = ORIGIN(RAM)); diff --git a/kernel/boot.s b/kernel/boot.s index 534beb6..281e1ca 100644 --- a/kernel/boot.s +++ b/kernel/boot.s @@ -1,36 +1,11 @@ -MBFLAGS equ 0 -MAGIC equ 0x1BADB002 -CHECKSUM equ -(MAGIC + MBFLAGS) - - section .multiboot -align 4 - dd MAGIC - dd MBFLAGS - dd CHECKSUM - -section .bss -resb 512 -align 16 -; align 16 bytes according to the System V ABI standard -; Stack space -stack_bottom: -resb 16384 ; 16KiB -stack_top: - section .text extern main +extern _estack global _start:function (_start.end - _start) _start: - mov esp, stack_top + mov esp, _estack call main cli .hang: hlt jmp .hang .end: - -section .kheap -kheap_top: -; Kernel heap space -; Change this value together Kheap::size varibale (mem/Kheap.h file) -resb 4096 -kheap_bottom: diff --git a/kernel/linker.ld b/kernel/linker.ld index abee596..9a0561b 100644 --- a/kernel/linker.ld +++ b/kernel/linker.ld @@ -1,49 +1,77 @@ +INCLUDE memory.ld + ENTRY(_start) +/*Pass this symbols via CMake*/ +MAGIC = 0x1BADB002; +FLAGS = 0; +CHECKSUM = -(MAGIC + FLAGS); + SECTIONS { - . = 1M; - - .multiboot : + /* It's a raw solution. */ + /* Automatic generation of filling .multiboot section needs. */ + .multiboot ALIGN(START_ADDR, CONSTANT(MAXPAGESIZE)) : ALIGN(CONSTANT(MAXPAGESIZE)) { - _startMultiboot = .; - *(.multiboot) - _endMultiboot = .; - } + LONG(MAGIC); + LONG(FLAGS); + LONG(CHECKSUM) + } > REGION_MULTIBOOT - .text BLOCK(4K) : ALIGN(4K) + .text ALIGN(CONSTANT(MAXPAGESIZE)) : ALIGN(CONSTANT(MAXPAGESIZE)) { - _startText = .; - *(.text) - _endText = .; - } + _text = .; + *(.text*) + _etext = .; + } > REGION_TEXT - .rodata BLOCK(4K) : ALIGN(4k) + .rodata ALIGN(CONSTANT(MAXPAGESIZE)): ALIGN(CONSTANT(MAXPAGESIZE)) { - _startRodata = .; - *(.rodata) - _endRodata = .; - } + _rodata = .; + *(.rodata*) + _erodata = .; + } > REGION_RODATA - .data BLOCK(4K) : ALIGN(4K) + .data : { - _startData = .; + _data = .; *(.data) - _endData = .; - } + _edata = .; + } > REGION_DATA - .bss BLOCK(16K) : ALIGN(16K) + .bss : { - _startBss = .; + _bss = .; *(.bss) - _endBss = .; - } + *(COMMON) + _ebss = .; + } > REGION_BSS + + .stack ALIGN(CONSTANT(MAXPAGESIZE)) : ALIGN(CONSTANT(MAXPAGESIZE)) + { + _stack = ABSOLUTE(.); + . += 4 * CONSTANT(MAXPAGESIZE); + _estack = ABSOLUTE(.); + } > REGION_DATA - .kheap BLOCK(4k) : ALIGN(4k) + .kheap ALIGN(CONSTANT(MAXPAGESIZE)) : ALIGN(CONSTANT(MAXPAGESIZE)) { - _startKheap = .; - *(.kheap) - _endKheap = .; - } + _startKheap = ABSOLUTE(.); + . += CONSTANT(MAXPAGESIZE); + _endKheap = ABSOLUTE(.); + } > REGION_DATA + + .eh_frame : + { + _eh_frame = .; + *(.eh_frame) + _e_eh_frame = .; + } > REGION_COMMON + + .ctors : + { + SORT_BY_NAME(CONSTRUCTORS) + } > REGION_COMMON + } diff --git a/makefile b/makefile index fc3286a..051eb0e 100644 --- a/makefile +++ b/makefile @@ -9,10 +9,12 @@ QEMUFLAGS = CFILES = $(shell find ./ -type f \( -name \*.cpp -o -name \*.c \)) AFILES = $(shell find ./ -type f \( -iname \*.s -o -name \*.asm \)) -LDFILE = $(shell find ./ -type f -name *.ld) +LDFILE = ./kernel/linker.ld SOURCE_FILES = $(CFILES) $(AFILES) OBJ_FILES = $(addprefix $(BDIR)/, $(addsuffix .o, $(basename $(SOURCE_FILES)))) INCLUDE = ./include +# Bad practice! +ARCHDIR = arch/x86 ifdef DEBUG CFLAGS := -g3 $(CFLAGS) @@ -29,7 +31,7 @@ build: startbuild $(SOURCE_FILES) echo $(AFLAGS) echo $(CFLAGS) @echo "Link object files..." - $(LD) -o $(OS_BINARY) -T $(LDFILE) $(OBJ_FILES) $(LDFLAGS) + $(LD) -o $(OS_BINARY) -L$(ARCHDIR) -T$(LDFILE) $(OBJ_FILES) $(LDFLAGS) @echo "Project was built" $(CFILES): -- cgit v1.2.3