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.
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.
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.
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.
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.*)
}
}
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:.
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.
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.
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
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".