aboutsummaryrefslogtreecommitdiff
AgeCommit message (Collapse)AuthorFilesLines
2026-09-04x86_64/cpu: fix asm input constraintFelix Morgner1-2/+2
The "X" constraint tells GCC that any operand whatsoever is valid to be placed in the assembler template. This makes no sense in this case, since that would allow for the exact expression to be inserted. If that happens, which it does when `-Og` is active, GCC is unable to assemble that template. The correct constraint is forcing the value into a register.
2026-09-04x86_64/boot: reduce kernel stack size to 8 KiBFelix Morgner1-1/+1
2026-09-04x86_64/cpu: handle #DF inside the arch codeFelix Morgner1-1/+12
A double fault is a very x86-64 specific type of exception and not recoverable in a generalized way. Thus we should handle it internally, with handling currently being triggering a panic, and not forward it to the architecture-independent kernel layer.
2026-09-04x86_64/cpu: use IST1 as the stack for #DFFelix Morgner3-12/+33
2026-09-04x86_64/cpu: isolate kernel and IST1 stackFelix Morgner1-1/+13
Previously, the kernel stack was allocated inside the .kernel_bss section, along other uninitialized data. While this works, it assumes that the section will always be laid out with the kernel stack at the top. If that is not the case, the allocated guard page before .kernel_bss would not trigger a #PF since out-of-bounds (overflow) access would quietly overwrite other data in the section, thus potentially corrupting global kernel data. At the same time, there was no separate section (and guard page) for the future #DF exception stack (IST1 in our case). Thus we allocate a section, and a guard page, while we are already modifying the linker script.
2026-09-04x86_64/cpu: reload the task registerFelix Morgner1-2/+6
When execution enters the kernel, no specific task register state has been established, leaving the power-on state of the CPU itself active. We have no control over that state, ergo we need to reload the task register to point to descriptor under our control. The earliest point when we can do that is after the new global descriptor table has been loaded. Thus this is the exact point where we do that. Additionally, reloading the TR has unveiled another latent bug that was present since the early days of the CPU initialization code: The TSS descriptor was actually incorrect. The reason for this not having been revealed earlier, is that the CPU was quietly using the TR set up by by its own power-on bootstrap. Once a load with the existing, non-TSS, descriptor was issued, A #GP was triggered because the CPU detected that the referenced TSS descriptor is not in fact a TSS descriptor (subtype 0x9): ----- BEGIN EXCEPTION DUMP ----- check_exception old: 0xffffffff new 0xd 0: v=0d e=0028 i=0 cpl=0 IP=0008:ffffffff80281b12 pc=ffffffff80281b12 SP=0010:ffffffff80216390 env->regs[R_EAX]=0000000000000028 RAX=0000000000000028 RBX=0000000000000000 RCX=ffffffff80216100 RDX=ffffffff8010fca0 RSI=0000000000000050 RDI=ffffffff80216260 RBP=ffffffff802163d0 RSP=ffffffff80216390 R8 =ffffffff802160f7 R9 =ffffffff80115328 R10=ffffffff8021626c R11=0000000000000000 R12=0000000000000000 R13=0000000000000000 R14=0000000000000000 R15=0000000000000000 RIP=ffffffff80281b12 RFL=00000092 [--S-A--] CPL=0 II=0 A20=1 SMM=0 HLT=0 ES =0010 0000000000000000 ffffffff 00cf9300 DPL=0 DS [-WA] CS =0008 0000000000000000 ffffffff 00af9800 DPL=0 CS64 [---] SS =0010 0000000000000000 ffffffff 00cf9300 DPL=0 DS [-WA] DS =0010 0000000000000000 ffffffff 00cf9300 DPL=0 DS [-WA] FS =0010 0000000000000000 ffffffff 00cf9300 DPL=0 DS [-WA] GS =0010 0000000000000000 ffffffff 00cf9300 DPL=0 DS [-WA] LDT=0000 0000000000000000 0000ffff 00008200 DPL=0 LDT TR =0000 0000000000000000 0000ffff 00008b00 DPL=0 TSS64-busy GDT= ffffffff801154e0 000001bf IDT= 0000000000000000 00000000 CR0=80000013 CR2=0000000000000000 CR3=0000000000102000 CR4=00000620 DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000 DR6=00000000ffff0ff0 DR7=0000000000000400 CCS=0000000000000090 CCD=ffffffff802161f8 CCO=EFLAGS EFER=0000000000000500 ----- END EXCEPTION DUMP ----- Decoding the e= value of the exception shows that the #GP occurred while the CPU was trying to process index 5 of the GDT (bits 3-15 define the index, with e=0028 being 0000'0000'0010'1000 => index 5). The layout of a system segment descriptor differs from a normal segment descriptor in that the accessed, read/write, conforming, and executable bits change their meaning into a 4-bit subtype number. For a TSS descriptor, this subtype number must be 9. In the future, the data structures of the GDT implementation should be revised to ensure this kind of misconfiguration can not happen again.
2026-09-03x86_64/cpu: fix GDT size calculationFelix Morgner1-1/+1
The GDT pointer already receives the size in bytes when the GDT constructs it to activate the new GDT. Previously, the size in bytes got multiplied by the size of a single segment_descriptor before performing the mandatory subtraction of one. This means that the CPU lived in the believe that the GDT had a size of 448 bytes, instead of the true 56. Additionally, the calculation was flawed in another way, revealing the reason for why the size in bytes was passed to global_descriptor_table_pointer in the first place: it assumes that all entries in the GDT are of the same size. However, system descriptors are larger than basic segment descriptors.
2026-09-03x86_64: replace unreachable builtinFelix Morgner1-1/+2
2026-09-03fs, devices: fix undefined behavior in registrationFelix Morgner3-14/+41
2026-09-03Merge branch 'fmorgner/code-style-cleanup' into 'develop'Felix Morgner60-162/+184
chore: clean up code according to style guide See merge request teachos/kernel!58
2026-09-03chore: fix header guardsFelix Morgner37-72/+72
2026-09-03chore: add missing explicit specifiersFelix Morgner4-1/+11
2026-09-03chore: fix message prefixesFelix Morgner2-45/+43
2026-09-03chore: add missing return typesFelix Morgner7-23/+29
2026-09-03chore: add missing [[nodiscard]] attributesFelix Morgner10-21/+29
2026-09-02docs: add additional brief and guide draftsFelix Morgner5-2/+1049
2026-09-02docs: update thesis opportunitiesFelix Morgner1-23/+56
2026-09-01kernel: fix broken readme symlinkFelix Morgner1-1/+1
2026-09-01docs: update facet dispatch briefFelix Morgner1-4/+4
2026-09-01chore: clean up facet idsFelix Morgner15-51/+58
2026-08-31docs: add brief regarding facet dispatchingFelix Morgner1-0/+430
2026-08-31docs: update documentation structureFelix Morgner6-4/+27
2026-08-31ide: update toolchainFelix Morgner2-6/+14
2026-08-31chore: fix poetry configurationFelix Morgner2-590/+496
2026-08-31docs: prepare for pages deploymentFelix Morgner22-271/+122
2026-08-31ide: switch to MS C/C++ Tools extensionFelix Morgner3-4/+6
2026-08-31doc: fix x86_64 commit exampleFelix Morgner1-1/+1
2026-08-31doc: add additional contributor guidelinesFelix Morgner1-40/+117
2026-08-31doc: replace codestyle with contributingFelix Morgner2-491/+531
2026-08-31chore: minor stylistic cleanupsFelix Morgner13-40/+44
2026-08-30kapi/gdb: extend pretty printersFelix Morgner5-0/+98
2026-08-30kstd/gdb: add flat_map printerFelix Morgner2-0/+52
2026-08-30kstd/gdb: add error_code and result printersFelix Morgner3-3/+124
2026-08-30kstd/gdb: add pretty printers for unitsFelix Morgner2-0/+36
2026-08-30ide: load symbols as symbol file onlyFelix Morgner1-1/+1
2026-08-30doc: clean up and move code style docsFelix Morgner1-149/+142
2026-08-30ide: replace todo tree extensionFelix Morgner1-1/+1
2026-08-29kstd: make UDL operators constevalFelix Morgner1-8/+8
2026-08-29chore: normalize panic messagesFelix Morgner40-112/+610
2026-08-29chore: apply stylistic cleanupsFelix Morgner45-244/+252
2026-08-29build: improve test failure reporting in CIFelix Morgner1-0/+1
2026-08-28kernel/vfs: implement read_directory fixups.Felix Morgner6-2/+134
POSIX requires that the data returned by the readdir() function shows the inode number of the root of a mounted filesystem for its mount point. Additionally, the inode number of the '..' reference in the mounted filesystem must show the inode number of the mount point. We perform this fixup when computing the entries during read_directory on the fly. The implementation of the upward fixup will need to be revised once the kernel supports bind mounts.
2026-08-28kernel/fs: devfs: fix inode encodingFelix Morgner1-2/+1
2026-08-28Merge branch 'fmorgner/vfs-mount-initialization' into 'develop'Felix Morgner14-130/+146
kernel/vfs: rework boot initialization See merge request teachos/kernel!57
2026-08-28fixup! kernel/fs: ext2: fix block allocation on 1 KiB fsFelix Morgner3-7/+12
2026-08-28fixup! kernel/vfs: add identity based mount removalFelix Morgner1-1/+1
2026-08-28kernel/vfs: implement root swivel and mount moveFelix Morgner9-71/+92
Previously, the device filesystem (devfs) was simply grafted on each root filesystem during boot. This caused the existence of an unreachable, dead devfs mount after the VFS instance had been initialized. This changeset implements the ability to relocate an active mount from one mount point to another. That way, no second devfs mount needs to be created. Instead, the existing devfs mount is relocated to a mount point in the persistent root filesystem that get mounted during initialization. Secondly, this changeset also alters the VFS initialization flow, so that only one root mount exists after initialization finishes.
2026-08-28fixup! kernel/vfs: mount: resolve return type todoFelix Morgner1-2/+2
2026-08-28kernel/fs: ext2: fix block allocation on 1 KiB fsFelix Morgner1-2/+2
When computing the actual block numbers for a filesystem, care must be taken to account for which block is the actual first data block. For 1 KiB block size filesystems, that block is actually block 1, not 0. This is because the first 1 KiB on any ext2 volume is reserved for bootloader data. Complicating matters, the bitmaps don't take this into account. They essentially reflect a logical view, describing which data blocks are already allocated. On a 1 KiB filesystem, this effectively means that bit 0 of the allocation bitmap references physical block 1. Luckily, we don't need to make that determination based on the block size at all. The superblock already carries the number of the first data block. That means one can simply add that number, which is 1 in the 1 KiB block size case and 0 otherwise, to the found block index. Interestingly, this was already caught by accident when locating the authoritative block group descriptor (BGD) table. A factor of two was multiplied into the calculation in the case of a 1 KiB block size. This factor arises because the primary BGD table follows the primary superblock. Since the superblock is located in physical block 0 in all cases except for a 1 KiB block size, the BGD table generally lands in block 1. This implies an offset of 1 block size from the volume start. In the 1 KiB case, the BGD table lands in block number 2, effectively at an offset of 2 blocks from the start of the volume. This changeset makes that calculation explicit in the BGD table locator code as well. This clarifies the previously obscure factor of 2.
2026-08-28kernel/vfs: add identity based mount removalFelix Morgner2-1/+17