OSDev.org

The Place to Start for Operating System Developers
It is currently Wed Apr 24, 2024 5:02 pm

All times are UTC - 6 hours




Post new topic Reply to topic  [ 294 posts ]  Go to page Previous  1 ... 3, 4, 5, 6, 7, 8, 9 ... 20  Next
Author Message
 Post subject: Re: How to make a GDT?
PostPosted: Wed Oct 12, 2022 11:43 am 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5144
zap8600 wrote:
Can BOOTBOOT load x86 code?

If you mean 32-bit x86, no. BOOTBOOT can only load 64-bit code.

zap8600 wrote:
If I understand correctly, BOOTBOOT will need to load the x86 part of the kernel, then the GDT and paging will be setup.

There is no "x86 part" of the kernel. Your kernel will be entirely x86-64 code.

zap8600 wrote:
Or should I just make my own bootloader?

No.

zap8600 wrote:
If I should, then I would like it to boot from UEFI.

There are several bootloaders out there that already support UEFI, including BOOTBOOT.


Top
 Profile  
 
 Post subject: Re: How to make a GDT?
PostPosted: Wed Oct 12, 2022 12:05 pm 
Offline
Member
Member

Joined: Tue Nov 02, 2021 11:26 am
Posts: 195
Octocontrabass wrote:
zap8600 wrote:
Can BOOTBOOT load x86 code?

If you mean 32-bit x86, no. BOOTBOOT can only load 64-bit code.

So then how do I setup the GDT and paging from my kernel? Doesn't it have to be in Protected Mode to do so?


Top
 Profile  
 
 Post subject: Re: How to make a GDT?
PostPosted: Wed Oct 12, 2022 12:13 pm 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5144
zap8600 wrote:
So then how do I setup the GDT and paging from my kernel?

Prepare your GDT and page tables, then tell the CPU to use them.

zap8600 wrote:
Doesn't it have to be in Protected Mode to do so?

No.


Top
 Profile  
 
 Post subject: Re: How to make a GDT?
PostPosted: Wed Oct 12, 2022 12:29 pm 
Offline
Member
Member

Joined: Tue Nov 02, 2021 11:26 am
Posts: 195
Octocontrabass wrote:
zap8600 wrote:
Doesn't it have to be in Protected Mode to do so?

No.

I think I understand now. I was just confused. Thanks for the help. I will probably be back later, though.


Top
 Profile  
 
 Post subject: Re: How to make a GDT?
PostPosted: Thu Oct 13, 2022 10:50 am 
Offline
Member
Member

Joined: Wed Aug 30, 2017 8:24 am
Posts: 1604
linguofreak wrote:
With respect to the IDT specifically, I'd argue that that's not so much of an outgrowth of Intel segmentation: the 8086 had segments, but a fixed IVT. The VAX was entirely a flat-address-space machine, but had a register that set the base address for a System Control Block, which contained interrupt and exception vectors. And I'd say it's generally good practice in designing a CPU architecture to expose things like that in registers so the OS can put them where it wants them, rather than baking addresses into the microcode.
I guess I should have written it the other way around. I meant that the IDT is an outgrowth of the 8086's interrupt handling mechanism. You know, where it has multiple interrupt cycles, and the hardware has to place the vector number onto the data bus at the right cycle. That stuff just doesn't exist anywhere else, most other CPU architectures give you one exception for "external interrupt" and then you have to ask your interrupt controller for details. I am however admittedly not very experienced with other CISC architectures, except maybe the 6502 (which also had a fixed exception table, and only a single entry for external interrupts).

I would disagree with your point about flexibility. It has its place, but can also cause a lot of configuration effort to get right. PowerPC has its exceptions at a fixed address, which basically necessitates all OSes on that architecture to load the kernel to address 0. However, when the kernel loads, all of address space is free (or will be free eventually), and so that is not a large burden.

_________________
Carpe diem!


Top
 Profile  
 
 Post subject: Re: How to make a GDT?
PostPosted: Tue Oct 18, 2022 7:04 pm 
Offline
Member
Member

Joined: Tue Nov 02, 2021 11:26 am
Posts: 195
I'm having some trouble setting up my kernel in x86_64. I'm using the Meaty Skeleton tutorial. Do I need a boot.S file? How should the link.ld file be setup? I have look at multiple articles and the BOOTBOOT example kernel.


Top
 Profile  
 
 Post subject: Re: How to make a GDT?
PostPosted: Tue Oct 18, 2022 9:25 pm 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5144
zap8600 wrote:
Do I need a boot.S file?

You don't need it. You can still have it if you want it, though.

zap8600 wrote:
How should the link.ld file be setup?

Use the linker script provided with the example kernel.


Top
 Profile  
 
 Post subject: Re: How to make a GDT?
PostPosted: Tue Oct 18, 2022 9:34 pm 
Offline
Member
Member

Joined: Wed Aug 30, 2017 8:24 am
Posts: 1604
zap8600 wrote:
I'm having some trouble setting up my kernel in x86_64. I'm using the Meaty Skeleton tutorial. Do I need a boot.S file? How should the link.ld file be setup? I have look at multiple articles and the BOOTBOOT example kernel.
BOOTBOOT is an ELF64 loader that apparently already sets up a stack. From my brief glance at the documentation just now, I would expect not. Indeed I think you are following the wrong tutorial. In short, you can just create a normal C application, except it starts at _start(), and compile it with -ffreestanding -nostdlib, and link it with a start address of -2GB.

I have a linker file that does the job for me:
Code:
OUTPUT_FORMAT("elf64-x86-64")

PHDRS {
    headers PT_PHDR PHDRS;
    text PT_LOAD FILEHDR PHDRS;
    data PT_LOAD;
}

SECTIONS {
    . = 0xffffffff80000000 + SIZEOF_HEADERS;
    .text : {
        *(.text)
        *(.text.*)
    } :text
    .rodata : {
        *(.rodata)
        *(.rodata.*)
    }

    .eh_frame_hdr : {
        __eh_frame_hdr = .;
        *(.eh_frame_hdr)
    }
    .eh_frame : {
        *(.eh_frame)
        *(.eh_frame.*)
    }

    /* Normally, the overlap between text and data section is handled by having
     * two different pages for the last bits of text and the first bits of data.
     * That way, if the last bits of text are overwritten, it won't affect the
     * text that is actually used. Unfortunately, for the kernel this is not
     * possible. The whole file is loaded into memory en bloc, so the same page
     * would be mapped twice. Therefore, a write access to the writable page
     * would end up being visible in the non-writable side of things. Therefore,
     * we must actually page-align here.
     */
    . = ALIGN(2M);
    .data : {
        *(.data)
        *(.data.*)
    } :data
    .bss : {
        *(.bss)
        *(COMMON)
        *(.bss.*)
    }
}

_________________
Carpe diem!


Top
 Profile  
 
 Post subject: Re: How to make a GDT?
PostPosted: Tue Oct 18, 2022 9:50 pm 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5144
nullplan wrote:
I have a linker file that does the job for me:

BOOTBOOT is much more limited than whichever bootloader you're using, so your linker script won't work with BOOTBOOT.


Top
 Profile  
 
 Post subject: Re: How to make a GDT?
PostPosted: Wed Oct 19, 2022 7:03 am 
Offline
Member
Member

Joined: Tue Nov 02, 2021 11:26 am
Posts: 195
nullplan wrote:
BOOTBOOT is an ELF64 loader that apparently already sets up a stack. From my brief glance at the documentation just now, I would expect not. Indeed I think you are following the wrong tutorial. In short, you can just create a normal C application, except it starts at _start(), and compile it with -ffreestanding -nostdlib, and link it with a start address of -2GB.

I probably should have said that I'm using the tutorial as a base. The boot.S file also uses _start:.


Top
 Profile  
 
 Post subject: Re: How to make a GDT?
PostPosted: Wed Oct 19, 2022 9:56 am 
Offline
Member
Member

Joined: Wed Aug 30, 2017 8:24 am
Posts: 1604
Octocontrabass wrote:
BOOTBOOT is much more limited than whichever bootloader you're using, so your linker script won't work with BOOTBOOT.

How so? Does it not like the high load VMA? Is that why bzt had a bee in his bonnet about -mcmodel=kernel? Anyway, I use my own adapters. The main kernel is linked with that script, and the adapters adapt their boot environment appropriately to this main kernel. I have one for multiboot that is ca. 600 lines of C and another 300 lines of ASM. The UEFI one is still under development.

Oh my god. I just had a look at BOOTBOOT's ELF loader. Talk about a hack. Every page that I turn, I find more questionable things there. So sorry zap8600, I don't think that script will work for you. There is one in the example kernel, tho.
zap8600 wrote:
I probably should have said that I'm using the tutorial as a base. The boot.S file also uses _start:.
Yes, I require you to think for yourself a bit. Obviously the Meaty Skeleton code will not work in a 64-bit environment as-is. You need to change it to fit the new environment. Now, one change is that with BOOTBOOT, your _start() symbol already has the stack setup, and you can just write it in C rather than ASM. So now you actually need to read that boot.S you pilfered to figure out what it is doing and whether you need to keep it or not.

_________________
Carpe diem!


Top
 Profile  
 
 Post subject: Re: How to make a GDT?
PostPosted: Wed Oct 19, 2022 10:55 am 
Offline
Member
Member

Joined: Tue Nov 02, 2021 11:26 am
Posts: 195
nullplan wrote:
Oh my god. I just had a look at BOOTBOOT's ELF loader. Talk about a hack. Every page that I turn, I find more questionable things there. So sorry zap8600, I don't think that script will work for you. There is one in the example kernel, tho.

It is alright. I'll try to figure out how to write my own. It is very confusing, so I'll probably come back for help. How should I start?

nullplan wrote:
Yes, I require you to think for yourself a bit. Obviously the Meaty Skeleton code will not work in a 64-bit environment as-is. You need to change it to fit the new environment. Now, one change is that with BOOTBOOT, your _start() symbol already has the stack setup, and you can just write it in C rather than ASM. So now you actually need to read that boot.S you pilfered to figure out what it is doing and whether you need to keep it or not.

I have been converting the Meaty Skeleton code to x86_64. And for the record, I'm not exactly trying to pilfer the boot.S file. I'm using the Meaty Skeleton code as a base and/or reference.


Top
 Profile  
 
 Post subject: Re: How to make a GDT?
PostPosted: Wed Oct 19, 2022 11:50 am 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5144
zap8600 wrote:
How should I start?

Copy the example kernel's linker script. It should have everything you need for now.


Top
 Profile  
 
 Post subject: Re: How to make a GDT?
PostPosted: Wed Oct 19, 2022 5:46 pm 
Offline
Member
Member

Joined: Tue Nov 02, 2021 11:26 am
Posts: 195
I'm unsure what I'm doing wrong. Here is the error I get.
Code:
mkdir -p /home/linuxlite/workspace/CCOS-new/sysroot/usr/include
cp -R --preserve=timestamps include/. /home/linuxlite/workspace/CCOS-new/sysroot/usr/include/.
mkdir -p /home/linuxlite/workspace/CCOS-new/sysroot/usr/include
cp -R --preserve=timestamps include/. /home/linuxlite/workspace/CCOS-new/sysroot/usr/include/.
mkdir -p /home/linuxlite/workspace/CCOS-new/sysroot/usr/include
cp -R --preserve=timestamps include/. /home/linuxlite/workspace/CCOS-new/sysroot/usr/include/.
mkdir -p /home/linuxlite/workspace/CCOS-new/sysroot/usr/lib
cp libk.a /home/linuxlite/workspace/CCOS-new/sysroot/usr/lib
mkdir -p /home/linuxlite/workspace/CCOS-new/sysroot/usr/include
cp -R --preserve=timestamps include/. /home/linuxlite/workspace/CCOS-new/sysroot/usr/include/.
x86_64-elf-gcc --sysroot=/home/linuxlite/workspace/CCOS-new/sysroot -isystem=/usr/include -T arch/x86_64/linker.ld -o myos.kernel -O2 -g -Wall -Wextra -ffreestanding    arch/x86_64/crti.o arch/x86_64/crtbegin.o arch/x86_64/tty.o  kernel/kernel.o font/unifont.o  -nostdlib -lk -lgcc  arch/x86_64/crtend.o arch/x86_64/crtn.o
/home/linuxlite/opt/cross/lib/gcc/x86_64-elf/12.2.0/../../../../x86_64-elf/bin/ld: warning: myos.kernel has a LOAD segment with RWX permissions
`.eh_frame' referenced in section `.text' of arch/x86_64/crtbegin.o: defined in discarded section `.eh_frame' of arch/x86_64/crtbegin.o
`.eh_frame' referenced in section `.text' of arch/x86_64/crtbegin.o: defined in discarded section `.eh_frame' of arch/x86_64/crtbegin.o
arch/x86_64/crtbegin.o: in function `deregister_tm_clones':
crtstuff.c:(.text+0x1): relocation truncated to fit: R_X86_64_32 against symbol `__TMC_END__' defined in .dtors section in myos.kernel
crtstuff.c:(.text+0x18): relocation truncated to fit: R_X86_64_32 against `.tm_clone_table'
arch/x86_64/crtbegin.o: in function `register_tm_clones':
crtstuff.c:(.text+0x31): relocation truncated to fit: R_X86_64_32 against symbol `__TMC_END__' defined in .dtors section in myos.kernel
crtstuff.c:(.text+0x5a): relocation truncated to fit: R_X86_64_32 against `.tm_clone_table'
arch/x86_64/crtbegin.o: in function `__do_global_dtors_aux':
crtstuff.c:(.text+0x88): relocation truncated to fit: R_X86_64_32 against `.dtors'
crtstuff.c:(.text+0x8e): relocation truncated to fit: R_X86_64_32 against symbol `__DTOR_END__' defined in .dtors section in arch/x86_64/crtend.o
arch/x86_64/crtbegin.o: in function `frame_dummy':
crtstuff.c:(.text+0x10c): relocation truncated to fit: R_X86_64_32 against `.bss'
/home/linuxlite/opt/cross/lib/gcc/x86_64-elf/12.2.0/../../../../x86_64-elf/bin/ld: arch/x86_64/tty.o: in function `terminal_initialize':
/home/linuxlite/workspace/CCOS-new/kernel/arch/x86_64/tty.c:14: undefined reference to `_binary_console_sfn_start'
kernel/kernel.o: in function `_start':
/home/linuxlite/workspace/CCOS-new/kernel/kernel/kernel.c:7:(.text+0xc): relocation truncated to fit: R_X86_64_32 against `.rodata.str1.1'
arch/x86_64/crtend.o: in function `__do_global_ctors_aux':
crtstuff.c:(.text+0x13): relocation truncated to fit: R_X86_64_32 against `.ctors'
collect2: error: ld returned 1 exit status
make: *** [Makefile:57: myos.kernel] Error 1

Here is my Makefile file.
Code:
DEFAULT_HOST!=../default-host.sh
HOST?=DEFAULT_HOST
HOSTARCH!=../target-triplet-to-arch.sh $(HOST)

CFLAGS?=-O2 -g
CPPFLAGS?=
LDFLAGS?=
LIBS?=

DESTDIR?=
PREFIX?=/usr/local
EXEC_PREFIX?=$(PREFIX)
BOOTDIR?=$(EXEC_PREFIX)/boot
INCLUDEDIR?=$(PREFIX)/include

CFLAGS:=$(CFLAGS) -Wall -Wextra -ffreestanding
CPPFLAGS:=$(CPPFLAGS) -D__is_kernel -Iinclude
LDFLAGS:=$(LDFLAGS)
LIBS:=$(LIBS) -nostdlib -lk -lgcc

ARCHDIR=arch/$(HOSTARCH)

include $(ARCHDIR)/make.config

CFLAGS:=$(CFLAGS) $(KERNEL_ARCH_CFLAGS)
CPPFLAGS:=$(CPPFLAGS) $(KERNEL_ARCH_CPPFLAGS)
LDFLAGS:=$(LDFLAGS) $(KERNEL_ARCH_LDFLAGS)
LIBS:=$(LIBS) $(KERNEL_ARCH_LIBS)

KERNEL_OBJS=\
$(KERNEL_ARCH_OBJS) \
kernel/kernel.o \
font/unifont.o

OBJS=\
$(ARCHDIR)/crti.o \
$(ARCHDIR)/crtbegin.o \
$(KERNEL_OBJS) \
$(ARCHDIR)/crtend.o \
$(ARCHDIR)/crtn.o \

LINK_LIST=\
$(LDFLAGS) \
$(ARCHDIR)/crti.o \
$(ARCHDIR)/crtbegin.o \
$(KERNEL_OBJS) \
$(LIBS) \
$(ARCHDIR)/crtend.o \
$(ARCHDIR)/crtn.o \

.PHONY: all clean install install-headers install-kernel
.SUFFIXES: .o .c .S

all: myos.kernel

myos.kernel: $(OBJS) $(ARCHDIR)/linker.ld
   $(CC) -T $(ARCHDIR)/linker.ld -o $@ $(CFLAGS) $(LINK_LIST)
   x86_64-elf-strip -s -K mmio -K fb -K bootboot -K environment -K initstack myos.kernel

font/unifont.o:
   x86_64-elf-ld -r -b binary -o font/unifont.o font/unifont.sfn

$(ARCHDIR)/crtbegin.o $(ARCHDIR)/crtend.o:
   OBJ=`$(CC) $(CFLAGS) $(LDFLAGS) -print-file-name=$(@F)` && cp "$$OBJ" $@

.c.o:
   $(CC) -MD -c $< -o $@ -std=gnu11 $(CFLAGS) $(CPPFLAGS)

.S.o:
   $(CC) -MD -c $< -o $@ $(CFLAGS) $(CPPFLAGS)

clean:
   rm -f myos.kernel
   rm -f $(OBJS) *.o */*.o */*/*.o
   rm -f $(OBJS:.o=.d) *.d */*.d */*/*.d

install: install-headers install-kernel

install-headers:
   mkdir -p $(DESTDIR)$(INCLUDEDIR)
   cp -R --preserve=timestamps include/. $(DESTDIR)$(INCLUDEDIR)/.

install-kernel: myos.kernel
   mkdir -p $(DESTDIR)$(BOOTDIR)
   cp myos.kernel $(DESTDIR)$(BOOTDIR)

-include $(OBJS:.o=.d)

I'm trying to use the ssfn library as well. Here is my tty.c file.
Code:
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>

#define SSFN_CONSOLEBITMAP_TRUECOLOR        /* use the special renderer for 32 bit truecolor packed pixels */
#include <kernel/ssfn.h>
#include <kernel/tty.h>

extern uint8_t fb;
extern volatile unsigned char _binary_console_sfn_start;

void terminal_initialize(void) {
   ssfn_src = &_binary_console_sfn_start;      /* the bitmap font to use */
   ssfn_dst.ptr = &fb;                  /* framebuffer address and bytes per line */
   ssfn_dst.p = 4096;
   ssfn_dst.fg = 0xFFFFFFFF;                   /* colors, white on black */
   ssfn_dst.bg = 0;
   ssfn_dst.x = 100;                           /* coordinates to draw to */
   ssfn_dst.y = 200;
}

void terminal_putentryat(char *s) {
   if(*s == '\n') {
          ssfn_dst.y += ssfn_src->height;
          ssfn_dst.x = 0;
   } else
          ssfn_putc(*s);
}

void terminal_putchar(char c) {
   terminal_putentryat(c);
}

void terminal_write(const char* data, size_t size) {
   for (size_t i = 0; i < size; i++)
      terminal_putchar(data[i]);
}

void terminal_writestring(const char* data) {
   terminal_write(data, strlen(data));
}

Any help is appreciated.


Top
 Profile  
 
 Post subject: Re: How to make a GDT?
PostPosted: Wed Oct 19, 2022 6:00 pm 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5144
zap8600 wrote:
Code:
relocation truncated to fit

You need to add "-mcmodel=kernel" to your CFLAGS. You should also add "-mno-red-zone" to avoid problems later.

zap8600 wrote:
Code:
undefined reference to `_binary_console_sfn_start'

The symbol name depends on the file name. Your font is named "font/unifont.sfn" instead of "console.sfn", so you need to replace "_binary_console_sfn_start" with "_binary_font_unifont_sfn_start".


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 294 posts ]  Go to page Previous  1 ... 3, 4, 5, 6, 7, 8, 9 ... 20  Next

All times are UTC - 6 hours


Who is online

Users browsing this forum: No registered users and 123 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group