OSDev.org https://forum.osdev.org/ |
|
Linker runs but does not generate output https://forum.osdev.org/viewtopic.php?f=1&t=56703 |
Page 1 of 1 |
Author: | Schol-R-LEA [ Mon Jan 23, 2023 8:36 pm ] |
Post subject: | Linker runs but does not generate output |
I've been sweating bullets today over the paging (which is still a mess, though that's beside the point), but along the way ended up with a different problem entirely: the linker invocation runs without any error messages given, but it doesn't produce the kernel.elf file. I only noticed this because changes I was making were having no effect on the kernel output - the existing copy of the kernel file was being re-used, until I deleted it from the obj/ and found the installer failing. The error messages I am getting are: Code: make nasm -w+all -f bin -IVerbum/src/PC-x86/nasm/fat12 Verbum/src/PC-x86/nasm/fat12/verbum.asm -o obj/verbum.bin -l obj/verbum.lst nasm -w+all -f bin -IVerbum/src/PC-x86/nasm/fat12 Verbum/src/PC-x86/nasm/fat12/stagetwo.asm -o obj/stagetwo.bin -l obj/stagetwo.lst aux.asm:209: warning: uninitialized space declared in .text section: zeroing [-w+zeroing] aux.asm:23: warning: uninitialized space declared in .text section: zeroing [-w+zeroing] aux.asm:62: warning: uninitialized space declared in .text section: zeroing [-w+zeroing] tables.asm:88: warning: uninitialized space declared in .text section: zeroing [-w+zeroing] nasm -w+all -f elf32 src/kstart.asm -o obj/kstart.o -l obj/kstart.lst i686-elf-gcc -Wall -Werror -Wpedantic -std=c2x -ffreestanding -I src/include -c src/terminal.c -o obj/terminal.o i686-elf-gcc -Wall -Werror -Wpedantic -std=c2x -ffreestanding -I src/include -c src/mem.c -o obj/mem.o i686-elf-gcc -Wall -Werror -Wpedantic -std=c2x -ffreestanding -I src/include -c src/paging.c -o obj/paging.o i686-elf-gcc -Wall -Werror -Wpedantic -std=c2x -ffreestanding -mgeneral-regs-only -I src/include -c src/idt.c -o obj/idt.o i686-elf-gcc -Wall -Werror -Wpedantic -std=c2x -ffreestanding -I src/include -c src/gdt.c -o obj/gdt.o i686-elf-gcc -Wall -Werror -Wpedantic -std=c2x -ffreestanding -I src/include -c src/acpi.c -o obj/acpi.o i686-elf-gcc -Wall -Werror -Wpedantic -std=c2x -ffreestanding -I src/include -c src/kernel.c -o obj/kernel.o i686-elf-ld -T linker.ld dd if=/dev/zero of=obj/boot.img count=1440 bs=1k 1440+0 records in 1440+0 records out 1474560 bytes (1.5 MB, 1.4 MiB) copied, 0.00553826 s, 266 MB/s mkfs.msdos -F 12 -n "ORDO" obj/boot.img mkfs.fat 4.2 (2021-01-31) dd if=obj/verbum.bin of=obj/boot.img count=1 conv=notrunc 1+0 records in 1+0 records out 512 bytes copied, 0.000110209 s, 4.6 MB/s mkdir -p temp sudo mount obj/boot.img temp [sudo] password for schol-r-lea: sudo cp obj/stagetwo.bin temp/STAGETWO.SYS sudo cp obj/kernel.elf temp/KERNEL.SYS cp: cannot stat 'obj/kernel.elf': No such file or directory make: *** [Makefile:35: install] Error 1 The linker script is Code: /* The bootloader will look at this image and start execution at the symbol designated at the entry point. */ ENTRY(kstart) INPUT( obj/kernel.o obj/terminal.o obj/mem.o obj/idt.o obj/gdt.o obj/paging.o obj/acpi.o ) OUTPUT(kernel.elf) OUTPUT_FORMAT(elf32-i386) STARTUP(obj/kstart.o) /* Tell where the various sections of the object files will be put in the final kernel image. */ SECTIONS { /* Begin putting sections at the higher half. */ . = 0xC0000000; /* the .text section. */ .text : ALIGN(4K) { *(.text) } /* Read-only data. */ .rodata : ALIGN(4K) { *(.rodata) } /* Read-write data (initialized) */ .data : ALIGN(4K) { *(.data) } /* Read-write data (uninitialized) and stack */ .bss : ALIGN(4K) { *(COMMON) *(.bss) } /* hardware tables */ . = 0xC0100000; .tables : { tables_base = .; } .boot_data BLOCK(4K) : ALIGN (4K) { boot_data = .; . = . + 4K; } .gdt BLOCK(64K) : { gdt = .; . = . + 64K; } .tss BLOCK(4K) : ALIGN(4K) { default_tss = .; . = . + 4K; } .idt BLOCK(4K) : ALIGN(4K) { idt = .; . = . + 4K; } .paging BLOCK(4K) : ALIGN(4K) { page_directory = .; . = . + 4K; page_tables = .; . = . + (1K * 4K); } /* set up the kernel stack */ . = 0xC1000000; .stack : { kernel_stack_base = .; kernel_stack_top = . + 16K; } } while the Makefile is Code: ASM = nasm -w+all COPY = dd FORMAT = mkfs.msdos -F 12 -n "ORDO" REIMAGE=qemu-img SYS_INSTALL = ~/Deployments/ms-sys-2.5.3/bin/ms-sys --fat12 BOOTPATH=Verbum/src/PC-x86/nasm/fat12 BOOT = verbum STAGE_TWO = stagetwo DISKTARGET = boot.img DISKSIZE = 1440 CC=i686-elf-gcc LD=i686-elf-ld LINK_SCRIPT=linker.ld CFLAGS=-Wall -Werror -Wpedantic -std=c2x -ffreestanding C_SRC=src C_INCLUDES=-I $(C_SRC)/include OBJPATH=obj KERNEL=kernel KSTART=kstart GDT=gdt IDT=idt TERMINAL=terminal MEM=mem PAGING=paging ACPI=acpi install: boot stage2 link $(COPY) if=/dev/zero of=$(OBJPATH)/$(DISKTARGET) count=$(DISKSIZE) bs=1k $(FORMAT) $(OBJPATH)/$(DISKTARGET) $(COPY) if=$(OBJPATH)/$(BOOT).bin of=$(OBJPATH)/$(DISKTARGET) count=1 conv=notrunc mkdir -p temp sudo mount $(OBJPATH)/$(DISKTARGET) temp sudo cp $(OBJPATH)/$(STAGE_TWO).bin temp/STAGETWO.SYS sudo cp $(OBJPATH)/$(KERNEL).elf temp/KERNEL.SYS sudo umount temp rmdir temp $(REIMAGE) convert -f raw -O qcow2 $(OBJPATH)/$(DISKTARGET) ordo.qcow2 link: kstart kernel terminal mem idt acpi paging gdt $(LD) -T $(LINK_SCRIPT) kernel: terminal paging mem idt gdt acpi $(CC) $(CFLAGS) $(C_INCLUDES) -c $(C_SRC)/$(KERNEL).c -o $(OBJPATH)/$(KERNEL).o acpi: terminal $(CC) $(CFLAGS) $(C_INCLUDES) -c $(C_SRC)/$(ACPI).c -o $(OBJPATH)/$(ACPI).o idt: terminal $(CC) $(CFLAGS) -mgeneral-regs-only $(C_INCLUDES) -c $(C_SRC)/$(IDT).c -o $(OBJPATH)/$(IDT).o gdt: $(CC) $(CFLAGS) $(C_INCLUDES) -c $(C_SRC)/$(GDT).c -o $(OBJPATH)/$(GDT).o paging: terminal mem $(CC) $(CFLAGS) $(C_INCLUDES) -c $(C_SRC)/$(PAGING).c -o $(OBJPATH)/$(PAGING).o mem: terminal $(CC) $(CFLAGS) $(C_INCLUDES) -c $(C_SRC)/$(MEM).c -o $(OBJPATH)/$(MEM).o terminal: $(CC) $(CFLAGS) $(C_INCLUDES) -c $(C_SRC)/$(TERMINAL).c -o $(OBJPATH)/$(TERMINAL).o kstart: $(ASM) -f elf32 $(C_SRC)/$(KSTART).asm -o $(OBJPATH)/$(KSTART).o -l $(OBJPATH)/$(KSTART).lst boot: $(ASM) -f bin -I$(BOOTPATH) $(BOOTPATH)/$(BOOT).asm -o $(OBJPATH)/$(BOOT).bin -l $(OBJPATH)/$(BOOT).lst stage2: $(ASM) -f bin -I$(BOOTPATH) $(BOOTPATH)/$(STAGE_TWO).asm -o $(OBJPATH)/$(STAGE_TWO).bin -l $(OBJPATH)/$(STAGE_TWO).lst What puzzles me most is the lack of any sort of error message from ld. |
Author: | Octocontrabass [ Mon Jan 23, 2023 8:46 pm ] |
Post subject: | Re: Linker runs but does not generate output |
Code: i686-elf-ld -T linker.ld You're not passing any input files to the linker. |
Author: | Schol-R-LEA [ Mon Jan 23, 2023 9:25 pm ] |
Post subject: | Re: Linker runs but does not generate output |
I... sigh I must have misunderstood the documentation for linker scripts. I had the impression that the entries in the INPUTS() and OUTPUT() fields were could be used in place of the command line arguments. Code: INPUT( obj/kernel.o obj/terminal.o obj/mem.o obj/idt.o obj/gdt.o obj/paging.o obj/acpi.o ) OUTPUT(kernel.elf) Having reinstated the arguments, I am now finding that the line intended to move the kernel stack is causing a triple fault. Code: extern kernel_main extern kernel_stack_top global kstart [SECTION .text] kstart: mov esp, kernel_stack_top call kernel_main .halted_loop: hlt jmp short .halted_loop If I comment out that mov it works as before, more or less. |
Author: | Schol-R-LEA [ Mon Jan 23, 2023 9:29 pm ] |
Post subject: | Re: Linker runs but does not generate output |
RE: the linker script, the problem was that I hadn't included the path for the kernel.elf file in the OUTPUT() statement. |
Author: | Octocontrabass [ Mon Jan 23, 2023 11:51 pm ] |
Post subject: | Re: Linker runs but does not generate output |
Schol-R-LEA wrote: I had the impression that the entries in the INPUTS() and OUTPUT() fields were could be used in place of the command line arguments. I did not know the linker could do that. Whoops. I've never seen anyone use that before. Other projects use the makefile to generate the list of file names and pass it to the linker; that way only the makefile needs to be updated when making changes instead of both the makefile and the linker script. Schol-R-LEA wrote: If I comment out that mov it works as before, more or less. It's hard to say for sure without more debugging information, but it sounds like your bootloader isn't preparing appropriate pages for the kernel stack. Does your bootloader actually use the program headers to decide which pages it maps, or does it create a fixed mapping that doesn't cover enough memory to include your new kernel stack? |
Author: | Schol-R-LEA [ Mon Jan 23, 2023 11:58 pm ] |
Post subject: | Re: Linker runs but does not generate output |
Octocontrabass wrote: Schol-R-LEA wrote: If I comment out that mov it works as before, more or less. It's hard to say for sure without more debugging information, but it sounds like your bootloader isn't preparing appropriate pages for the kernel stack. Does your bootloader actually use the program headers to decide which pages it maps, or does it create a fixed mapping that doesn't cover enough memory to include your new kernel stack? I'm not even certain what you mean by program headers, in this context. It is creating a fixed mapping. |
Author: | Schol-R-LEA [ Tue Jan 24, 2023 12:04 am ] |
Post subject: | Re: Linker runs but does not generate output |
Just to clarify what I mean, here is the entirety of the boot loader's paging declarations: Code: %ifndef _PAGING__INC__ %define _PAGING__INC__ %define PDE_Present 0b00000000000000000000000000000001 %define PDE_Read_Write 0b00000000000000000000000000000010 %define PDE_User 0b00000000000000000000000000000100 %define PDE_Write_Thru 0b00000000000000000000000000001000 %define PDE_Cache_Disable 0b00000000000000000000000000010000 %define PDE_Acccessed 0b00000000000000000000000000100000 %define PDE_Dirty 0b00000000000000000000000001000000 %define PDE_Page_Size 0b00000000000000000000000010000000 %define PDE_Global 0b00000000000000000000000100000000 %define PDE_Availability_Mask 0b00000000000000000000111000000000 %define PDE_Page_Attr_Table 0b00000000000000000001000000000000 %define PDE_Page_Index_Mask 0b11111111111111111110000000000000 %define PTE_Present 0b00000000000000000000000000000001 %define PTE_Read_Write 0b00000000000000000000000000000010 %define PTE_User 0b00000000000000000000000000000100 %define PTE_Write_Through 0b00000000000000000000000000001000 %define PTE_Cache_Disable 0b00000000000000000000000000010000 %define PTE_Acccessed 0b00000000000000000000000000100000 %define PTE_Dirty 0b00000000000000000000000001000000 %define PTE_Page_Attr_Table 0b00000000000000000000000010000000 %define PTE_Global 0b00000000000000000000000100000000 %define PTE_Availability_Mask 0b00000000000000000000111000000000 %define PTE_Page_Index_Mask 0b11111111111111111111000000000000 %endif and the code that uses them: Code: %ifndef _PAGING_CODE__INC__ %define _PAGING_CODE__INC__ %line 0, "paging.asm" bits 32 page_directory equ 0x0040000 page_table_0 equ page_directory + 0x1000 page_table_768 equ page_table_0 + 0x1000 init_page_directory: mov ebx, dword page_directory memset32 0, 0x0400, ebx ; clear the page dir table ; start by setting up the base page table mov ebx, dword page_table_0 ; get index into the base page table memset32 0, 0x0400, ebx ; clear the table entries ; entries 0-1024 - identity mapping the first 1 MiB of memory mov ecx, 0x0100 ; 256 entries * 4KiB = 1 MiB mov eax, 0 .pt_0_fill: mov edx, eax or edx, PTE_Present mov [ebx], dword edx add eax, 0x1000 add ebx, 4 loop .pt_0_fill ; set up the kernel code table mov ebx, page_table_768 ; get index into the kernel code page table memset32 0, 0x0400, ebx ; clear the table entries ; entries 0-4096 - mapping the start of higher half mov ecx, 0x1000 ; 4096 entries * 4KiB = 4 MiB mov eax, 0x00100000 ; the 1MiB entry point .pt_768_fill: mov edx, eax or edx, PTE_Present mov [ebx], dword edx add eax, 0x1000 add ebx, 4 loop .pt_768_fill .setup_directory: mov ebx, page_directory .pd_fill: mov eax, page_table_0 or eax, PDE_Present mov [ebx], eax add ebx, 768 * 4 mov eax, page_table_768 or eax, PDE_Present mov [ebx], eax ; set the page directory mov eax, page_directory mov cr3, eax ret %endif So clearly, it doesn't map the area I am trying to access. |
Author: | Schol-R-LEA [ Tue Jan 24, 2023 12:41 am ] |
Post subject: | Re: Linker runs but does not generate output |
As a quick update, I simplified the existing code somewhat by writing a macro which populates a given page table. Code: %macro populate_pte 3 ; set up the page table mov ebx, %3 ; get location to save the table entry memset32 0, 0x0400, ebx ; clear the table entries ; entries 0-4096 mov ecx, 0x1000 ; 4096 entries * 4KiB = 4 MiB mov eax, %2 ; the physical address to map %%pt_fill: mov edx, eax or edx, PTE_Present mov [ebx], dword edx add eax, 0x1000 add ebx, 4 loop %%pt_fill %endmacro While this does not directly address the issue of mapping the new pages, it does make it easier to add new entries, provided that they are filling an entire page table at a time. |
Author: | Octocontrabass [ Tue Jan 24, 2023 1:24 am ] |
Post subject: | Re: Linker runs but does not generate output |
Schol-R-LEA wrote: I'm not even certain what you mean by program headers, in this context. I'm referring to the ELF program headers. Since your bootloader performs fixed mappings, you could move the stack somewhere within the mapped area. Or, if you're fine spending even more time on bootloader development, you could make your bootloader set up the higher half mappings according to the program headers. (Stuff like this is why I still haven't finished a bootloader...) |
Author: | Schol-R-LEA [ Tue Jan 24, 2023 2:14 am ] |
Post subject: | Re: Linker runs but does not generate output |
I took the simpler option of writing macros to automate the entries, and just over-mapping the whole section. Which did in fact work, if crudely. Code: %ifndef _PAGING__INC__ %define _PAGING__INC__ %define PDE_Present 0b00000000000000000000000000000001 %define PDE_Read_Write 0b00000000000000000000000000000010 %define PDE_User 0b00000000000000000000000000000100 %define PDE_Write_Thru 0b00000000000000000000000000001000 %define PDE_Cache_Disable 0b00000000000000000000000000010000 %define PDE_Acccessed 0b00000000000000000000000000100000 %define PDE_Dirty 0b00000000000000000000000001000000 %define PDE_Page_Size 0b00000000000000000000000010000000 %define PDE_Global 0b00000000000000000000000100000000 %define PDE_Availability_Mask 0b00000000000000000000111000000000 %define PDE_Page_Attr_Table 0b00000000000000000001000000000000 %define PDE_Page_Index_Mask 0b11111111111111111110000000000000 %define PTE_Present 0b00000000000000000000000000000001 %define PTE_Read_Write 0b00000000000000000000000000000010 %define PTE_User 0b00000000000000000000000000000100 %define PTE_Write_Through 0b00000000000000000000000000001000 %define PTE_Cache_Disable 0b00000000000000000000000000010000 %define PTE_Acccessed 0b00000000000000000000000000100000 %define PTE_Dirty 0b00000000000000000000000001000000 %define PTE_Page_Attr_Table 0b00000000000000000000000010000000 %define PTE_Global 0b00000000000000000000000100000000 %define PTE_Availability_Mask 0b00000000000000000000111000000000 %define PTE_Page_Index_Mask 0b11111111111111111111000000000000 %macro populate_pte 3 ; set up the page table mov ebx, dword %3 ; get location to save the table entry memset32 0, 0x0400, ebx ; clear the table entries mov ecx, dword %2 ; number of entries to fill mov eax, dword %1 ; the physical address to map %%pt_fill: mov edx, eax or edx, PTE_Present mov [ebx], dword edx add eax, 0x1000 add ebx, 4 loop %%pt_fill %endmacro %macro populate_pde 2 mov ebx, page_directory add ebx, %1 * 4 mov eax, %2 or eax, PDE_Present mov [ebx], eax %endmacro %endif Code: %ifndef _PAGING_CODE__INC__
%define _PAGING_CODE__INC__ %line 0, "paging.asm" bits 32 page_directory equ 0x0040000 page_table_0 equ page_directory + 0x1000 page_table_0x0300 equ page_table_0 + 0x1000 page_table_0x0301 equ page_table_0x0300 + 0x1000 page_table_0x0302 equ page_table_0x0301 + 0x1000 page_table_0x0303 equ page_table_0x0302 + 0x1000 page_table_0x0304 equ page_table_0x0303 + 0x1000 page_table_0x0305 equ page_table_0x0304 + 0x1000 init_page_directory: mov ebx, dword page_directory memset32 0, 0x0400, ebx ; clear the page dir table populate_pte 0x00000000, 0x0100, page_table_0 populate_pte 0x00100000, 0x1000, page_table_0x0300 populate_pte 0x00400000, 0x1000, page_table_0x0301 populate_pte 0x00800000, 0x1000, page_table_0x0302 populate_pte 0x00C00000, 0x1000, page_table_0x0303 populate_pte 0x01000000, 0x1000, page_table_0x0304 populate_pte 0x01400000, 0x1000, page_table_0x0305 .setup_directory: populate_pde 0, page_table_0 populate_pde 0x0300, page_table_0x0300 populate_pde 0x0301, page_table_0x0301 populate_pde 0x0302, page_table_0x0302 populate_pde 0x0303, page_table_0x0303 populate_pde 0x0304, page_table_0x0304 populate_pde 0x0305, page_table_0x0305 ; set the page directory mov eax, page_directory mov cr3, eax ret %endif |
Author: | MichaelPetch [ Tue Jan 24, 2023 1:04 pm ] |
Post subject: | Re: Linker runs but does not generate output |
I'm curious if you have tried to git clone your project and build it from scratch in a new directory? I notice there is no `obj` directory so Make will fail and then there seems to be errors with your Color enum among other things. |
Author: | Schol-R-LEA [ Tue Jan 24, 2023 4:30 pm ] |
Post subject: | Re: Linker runs but does not generate output |
Ah, OK, thanks for pointing that out. I'll add a mkdir -p obj to the Makefile. Also, aside from calling magenta purple in two places, what problems are there with the Color enum? I'm sure there are some, but I don't see them offhand. I do know that you need to use -std=c2x for the typed enum support, but that's deliberate. |
Author: | MichaelPetch [ Tue Jan 24, 2023 10:50 pm ] |
Post subject: | Re: Linker runs but does not generate output |
While I had a compiler that supports `-std=c2x` (still experimental) it lacks a feature that you now use. N2963 Enhancements to Enumerations. Appears this is added for milestone GCC 13, and I'm currently on GCC 12.2. As a result I get errors with enums defined as: Code: enum Color : uint8_t (with the underlying type being specified).I assume you are using a bleeding edge version of GCC? |
Author: | Schol-R-LEA [ Wed Jan 25, 2023 1:11 am ] |
Post subject: | Re: Linker runs but does not generate output |
Yes, I am. Perhaps a bit too bleeding edge, then. |
Author: | MichaelPetch [ Wed Jan 25, 2023 3:04 am ] |
Post subject: | Re: Linker runs but does not generate output |
No problem. Might be something to mention in a README. |
Page 1 of 1 | All times are UTC - 6 hours |
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |