"Page fault detected" using anything from "fstream" library

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
amandude
Posts: 10
Joined: Wed Jul 07, 2021 7:18 pm

"Page fault detected" using anything from "fstream" library

Post by amandude »

I just fixed an issue where the linker (ld) command throws an error:

Code: Select all

undefined reference to basic_ifstream
And fixed it by using

Code: Select all

G++
;
No more linker errors.
Now there is a new problem: When I compile my C++ code with the library alone (without any use of the library), it works. But when I start to use it, and recompile and run, I get my Page Fault Interrupt called. I don't understand this one bit. Is there not enough free disk space? Sometimes, running

Code: Select all

make buildimg
(randomly) says

Code: Select all

Disk Full
("make buildimg" Makefile label shown below in Kernel Makefile).

Here is my Kernel Makefile:

Code: Select all

ARCH = x86_64
TARGET = ../setup/kernel.elf
SRCS = c/kernel.cpp
BUILDDIR = disk
OSNAME = BirdOS
OBJDIR := build
MAINDIR = ../setup

SRCDIR := c
CC = gcc
LD = g++
rwildcard=$(foreach d,$(wildcard $(1:=/*)),$(call rwildcard,$d,$2) $(filter $(subst *,%,$2),$d))

SRC = $(call rwildcard,$(SRCDIR),*.cpp)
OBJS = $(patsubst $(SRCDIR)/%.cpp, $(OBJDIR)/%.o, $(SRC))
all: $(OBJS) link

# UEFI wastes lots and lots of memory. Link our "kernel" at an address (32M) which isn't used by UEFI

$(OBJDIR)/interrupts/interrupts.o: $(SRCDIR)/interrupts/interrupts.cpp
	@ mkdir -p $(@D)
	$(CC) -mno-red-zone -mgeneral-regs-only -ffreestanding -c $^ -o $@

$(OBJDIR)/%.o: $(SRCDIR)/%.cpp
	@ mkdir -p $(@D)
	$(CC) -ffreestanding -fshort-wchar -mno-red-zone -c $^ -o $@

assem:
	@ mkdir -p build/GDT
	nasm c/GDT/GDTASM.asm -f elf64 -o build/GDT/GDTASM.o

link:
	g++ -Wl,-estart -Wl,-z -Wl,max-page-size=0x1000 -Wl,-Ttext=0x01000000 -Wl,-Bsymbolic -static -o $(TARGET) $(OBJS) build/GDT/GDTASM.o


clean:
	rm build/*.o $(TARGET) 2>/dev/null || true

buildimg:
	dd if=/dev/zero of=$(BUILDDIR)/$(OSNAME).img bs=512 count=93750
	mformat -i $(BUILDDIR)/$(OSNAME).img -f 2880 ::
	mmd -i $(BUILDDIR)/$(OSNAME).img ::/EFI
	mmd -i $(BUILDDIR)/$(OSNAME).img ::/EFI/BOOT
	mcopy -i $(BUILDDIR)/$(OSNAME).img $(BUILDDIR)/startup.nsh ::
	mcopy -i $(BUILDDIR)/$(OSNAME).img $(BUILDDIR)/main.efi ::
	mcopy -i $(BUILDDIR)/$(OSNAME).img $(TARGET) ::
In case you didn't know, I am using POSIX-UEFI:
Bootloader Makefile:

Code: Select all

TARGET = ../src/disk/main.efi
SRCS = main.c
EXTRA = kernel.elf
#USE_GCC=1
include uefi/Makefile

kernel.elf:
	@make -C kernel all USE_GCC=$(USE_GCC)
kernel.cpp:

Code: Select all

#include "stream/ostream.h"
#include <iostream>
#include <fstream>
bootparam_t *bootp;

using namespace std;

extern "C" void start(bootparam_t *bootpar)
{
    bootp = bootpar;
    LoadKernel();
    ofstream myFile("hello.txt");
    myFile.open("h");
    myFile << "Hello, world!";
    myFile.close();

    while(true) {
        ActivateCursorBlinker(KeyboardPositionX, KeyboardPositionY);
    };
}

I am all confused now to why it is doing this.
Does anybody know why it is doing this and how to resolve it?
Thanks for your help! :D
Ethin
Member
Member
Posts: 625
Joined: Sun Jun 23, 2019 5:36 pm
Location: North Dakota, United States

Re: "Page fault detected" using anything from "fstream" libr

Post by Ethin »

There are a couple problems that I see right off the bat:
  1. Your not linking your code as position independent. From your comments in your makefile your trying to force UEFI to load your code at a particular address. UEFI does not allow this; the address you specify may not be available on a particular UEFI implementation. UEFI therefore will use relocations in your kernel and load it at a random address that is available to it. (As a side note, can you prove that UEFI "waists" lots of RAM? Even if it did, you have to abide by its rules.)
  2. You are not using a cross-compiler. I'd recommend you use one unless you want a lot of problems.
  3. You are attempting to use libstdc++ in your kernel. Unless you've ported libstdc++ to kernel mode (something that would be quite difficult to do) this will not work as libstdc++ is built for your host system and not for your kernel or for UEFI.
Last edited by Ethin on Wed Aug 11, 2021 11:00 pm, edited 1 time in total.
nullplan
Member
Member
Posts: 1790
Joined: Wed Aug 30, 2017 8:24 am

Re: "Page fault detected" using anything from "fstream" libr

Post by nullplan »

Well, this can't possibly work. You are linking your program against some libstdc++ from the host system, which I assume is Linux, so you get a Linux executable out. And then you run that one under UEFI. That cannot work, as UEFI does not provide the system call layer you require. But also you set the start symbol to "start", which is a C++ function. Normally it would be _start, which is an ASM function, for one thing, and it would initialize the library before running your code. You are therefore skipping the initialization step which is required to get the other stuff to work. My guess is that the library code you linked in at some point accesses an invalid pointer because it was not initialized properly.

So to untangle this mess, you cannot call any standard C++ library functions in your kernel until you have ported them to the kernel. You should link with -ffreestanding. You should use a cross-compiler. I have no idea how it is that UEFI has been allowing you to run ELF executables, but UEFI requires PE, so you might need to mess about with GNU-EFI or use EDK2. Or use a cross-compiler that directly creates PE executables for UEFI. Also, you must link and compile as position-independent code, because contrary to what your Makefile believes, 32M is not guaranteed to be free. Just make it position independent, and UEFI will load your executable wherever there is space.
Carpe diem!
nexos
Member
Member
Posts: 1081
Joined: Tue Feb 18, 2020 3:29 pm
Libera.chat IRC: nexos

Re: "Page fault detected" using anything from "fstream" libr

Post by nexos »

In case you didn't know, I am using POSIX-UEFI:
I personally would recommend that you use a cross compiler (i.e., x86_64-mingw-w64-gcc) with UEFI headers (more then likely, GNU-EFI's), or you bite the bullet and use EDK2 (what I am doing). POSIX-UEFI started development earlier this year; I wouldn't trust it to be stable.

Besides, UEFI's API isn't too hard to understand. It looks daunting, but after learning the base concepts, it isn't to bad

As for the topic, I am no C++ expert :) . Just make sure you are using stable, well tested tools, then you we can figure out the problem.

Hopefully this wasn't too off topic
"How did you do this?"
"It's very simple — you read the protocol and write the code." - Bill Joy
Projects: NexNix | libnex | nnpkg
amandude
Posts: 10
Joined: Wed Jul 07, 2021 7:18 pm

Re: "Page fault detected" using anything from "fstream" libr

Post by amandude »

Thanks for all of your help! I have just started working on a Bare-Bones UEFI OS that uses a cross-compiler.
Post Reply