Page 2 of 3

Re: NASM to GAS assembly help

Posted: Tue Jun 25, 2024 1:57 pm
by Octocontrabass
TheGameMaker90 wrote: Tue Jun 25, 2024 12:22 pmGDT= 00000000 00000000
I assume that means it's not installed.
I assume that means you got it to work. The interrupt log only logs interrupts, so if there are no interrupts while your code is running, the log won't show anything from your code.
TheGameMaker90 wrote: Tue Jun 25, 2024 12:22 pmIt doesn't triple fault anymore, but I think that's just because it's not finding the GDT at all...
Sounds like it works to me.

Re: NASM to GAS assembly help

Posted: Tue Jun 25, 2024 2:14 pm
by TheGameMaker90
Cool, then I'll get started on the IDT. The repo has been made public again if you'd like to take a look and see if all is good for yourself.

Re: NASM to GAS assembly help

Posted: Wed Jun 26, 2024 9:57 am
by TheGameMaker90
Okay, so yesterday, I tried as I said to setup the IDT and I'm having an issue I never had before. For simplicity's sake, I basically reused James Molloy's IDT system and setup the isr's the best I could in GAS syntax. The problem is that when I use the code:

Code: Select all

asm ( "int $0x0" );
it puts 0xF000FF57 into int_no in the registers struct. I've been pulling my hair out trying to figure it out. I'll put the code here:

isr.h:

Code: Select all

#ifndef _ADAMANTIUM_ISR_H
#define _ADAMANTIUM_ISR_H

#include <stdint.h>

#ifndef INTn
#define INTn(n)								asm ( "int $"#n )
#endif

typedef struct
{
	uint32_t ds;
   	uint32_t edi, esi, ebp, esp, ebx, edx, ecx, eax;
   	uint32_t int_no, err_code;
   	uint32_t eip, cs, eflags, useresp, ss;
} registers_t;

typedef void(*isr_t)(registers_t);

extern void exception_handler(void);
extern void register_interrupt_handler(uint8_t n, isr_t hndl);

extern void isr0(void);
extern void isr1(void);
extern void isr2(void);
extern void isr3(void);
extern void isr4(void);
extern void isr5(void);
extern void isr6(void);
extern void isr7(void);
extern void isr8(void);
extern void isr9(void);
extern void isr10(void);
extern void isr11(void);
extern void isr12(void);
extern void isr13(void);
extern void isr14(void);
extern void isr15(void);
extern void isr16(void);
extern void isr17(void);
extern void isr18(void);
extern void isr19(void);
extern void isr20(void);
extern void isr21(void);
extern void isr22(void);
extern void isr23(void);
extern void isr24(void);
extern void isr25(void);
extern void isr26(void);
extern void isr27(void);
extern void isr28(void);
extern void isr29(void);
extern void isr30(void);
extern void isr31(void);

#endif
isr.c:

Code: Select all

void isr_handler(registers_t regs)
{
	printf("Received Intno: 0x%x\n", regs.int_no);	// Here is where the interrupt number is printed...
}
isr_idx.S:

Code: Select all

.code32
.globl isr0
.globl isr1
.globl isr2
.globl isr3
.globl isr4
.globl isr5
.globl isr6
.globl isr7
.globl isr8
.globl isr9
.globl isr10
.globl isr11
.globl isr12
.globl isr13
.globl isr14
.globl isr15
.globl isr16
.globl isr17
.globl isr18
.globl isr19
.globl isr20
.globl isr21
.globl isr22
.globl isr23
.globl isr24
.globl isr25
.globl isr26
.globl isr27
.globl isr28
.globl isr29
.globl isr30
.globl isr31
isr0:
	cli
	push 0x00
	push 0x00
	jmp isr_common_stub
isr1:
	cli
	push 0x00
	push 0x01
	jmp isr_common_stub
isr2:
	cli
	push 0x00
	push 0x02
	jmp isr_common_stub
isr3:
	cli
	push 0x00
	push 0x03
	jmp isr_common_stub
isr4:
	cli
	push 0x00
	push 0x04
	jmp isr_common_stub
isr5:
	cli
	push 0x00
	push 0x05
	jmp isr_common_stub
isr6:
	cli
	push 0x00
	push 0x06
	jmp isr_common_stub
isr7:
	cli
	push 0x00
	push 0x07
	jmp isr_common_stub
isr8:
	cli
	push 0x08
	jmp isr_common_stub
isr9:
	cli
	push 0x00
	push 0x09
	jmp isr_common_stub
isr10:
	cli
	push 0x0A
	jmp isr_common_stub
isr11:
	cli
	push 0x0B
	jmp isr_common_stub
isr12:
	cli
	push 0x0C
	jmp isr_common_stub
isr13:
	cli
	push 0x0D
	jmp isr_common_stub
isr14:
	cli
	push 0x0E
	jmp isr_common_stub
isr15:
	cli
	push 0x00
	push 0x0F
	jmp isr_common_stub
isr16:
	cli
	push 0x00
	push 0x10
	jmp isr_common_stub
isr17:
	cli
	push 0x11
	jmp isr_common_stub
isr18:
	cli
	push 0x00
	push 0x12
	jmp isr_common_stub
isr19:
	cli
	push 0x00
	push 0x13
	jmp isr_common_stub
isr20:
	cli
	push 0x00
	push 0x14
	jmp isr_common_stub
isr21:
	cli
	push 0x00
	push 0x15
	jmp isr_common_stub
isr22:
	cli
	push 0x00
	push 0x16
	jmp isr_common_stub
isr23:
	cli
	push 0x00
	push 0x17
	jmp isr_common_stub
isr24:
	cli
	push 0x00
	push 0x18
	jmp isr_common_stub
isr25:
	cli
	push 0x00
	push 0x19
	jmp isr_common_stub
isr26:
	cli
	push 0x00
	push 0x1A
	jmp isr_common_stub
isr27:
	cli
	push 0x00
	push 0x1B
	jmp isr_common_stub
isr28:
	cli
	push 0x00
	push 0x1C
	jmp isr_common_stub
isr29:
	cli
	push 0x00
	push 0x1D
	jmp isr_common_stub
isr30:
	cli
	push 0x1E
	jmp isr_common_stub
isr31:
	cli
	push 0x00
	push 0x1F
	jmp isr_common_stub

.extern isr_handler
isr_common_stub:
	pusha

	movw %ds, %ax
	push %eax

	movw $0x10, %ax
	movw %ax, %ds
	movw %ax, %es
	movw %ax, %fs
	movw %ax, %gs

	call isr_handler

	pop %eax
	movw %ax, %ds
	movw %ax, %es
	movw %ax, %fs
	movw %ax, %gs

	popa
	add $8, %esp
	sti
	iret
idt.h:

Code: Select all

#ifndef _ADAMANTIUM_IDT_H
#define _ADAMANTIUM_IDT_H					1

#include <compiler.h>	// For the _packed macro definition
#include <stdint.h>
#include "isr.h"

typedef struct idt_entry_struct
{
	uint16_t 	base_low;
	uint16_t 	selector;
	uint8_t		zero;
	uint8_t		flags;
	uint16_t	base_high;
} _packed idt_entry_t;

typedef struct idt_ptr_struct
{
	uint16_t	limit;
	uint32_t	base;
} _packed idt_ptr_t;
#endif
descriptors.h:

Code: Select all

#ifndef _ADAMANTIUM_DESCRIPTORS_H
#define _ADAMANTIUM_DESCRIPTORS_H

#define MAX_GDT_ENTRIES						5
#define MAX_IDT_ENTRIES						256

#if !defined(__ASSEMBLER__)
#include <kernel/tty.h>
#include <vga.h>
#include <stdint.h>
#include <stdio.h>
#include "interrupt.h"

extern void descriptors_init(void);

#endif

// For use with both C and Asembly sources:
#define GDT_KERNEL_CODE_SEGMENT				0x08
#define GDT_KERNEL_DATA_SEGMENT				0x10
#endif
descriptors.c:

Code: Select all

#include <kernel/i386/descriptors.h>
#include <kernel/i386/idt.h>
#include <string.h>

// Install the GDT. Located in file boot/desc.S
extern void gdt_install(void);
static void idt_install(void);

static void gdt_init(void);
static void idt_init(void);
static void idt_set_gate(uint8_t, uint32_t, uint16_t, uint8_t);

idt_entry_t	idt_entries[MAX_IDT_ENTRIES];
idt_ptr_t	idt_ptr;

void descriptors_init(void)
{
	gdt_init();
	idt_init();
}

static void gdt_init(void)
{
	gdt_install();
}

static void idt_init(void)
{
	idt_ptr.limit	= (sizeof(idt_entry_t) * (MAX_IDT_ENTRIES - 1));
	idt_ptr.base	= (uint32_t)&idt_entries;

	memset(&idt_entries, 0, sizeof(idt_entry_t) * MAX_IDT_ENTRIES);

	idt_set_gate(0x00, (uint32_t)isr0, GDT_KERNEL_CODE_SEGMENT, 0x8E);	// GDT_KERNEL_CODE_SEGMENT=0x08 (duh!)
	idt_set_gate(0x01, (uint32_t)isr1, GDT_KERNEL_CODE_SEGMENT, 0x8E);
	idt_set_gate(0x02, (uint32_t)isr2, GDT_KERNEL_CODE_SEGMENT, 0x8E);
	idt_set_gate(0x03, (uint32_t)isr3, GDT_KERNEL_CODE_SEGMENT, 0x8E);
	idt_set_gate(0x04, (uint32_t)isr4, GDT_KERNEL_CODE_SEGMENT, 0x8E);
	idt_set_gate(0x05, (uint32_t)isr5, GDT_KERNEL_CODE_SEGMENT, 0x8E);
	idt_set_gate(0x06, (uint32_t)isr6, GDT_KERNEL_CODE_SEGMENT, 0x8E);
	idt_set_gate(0x07, (uint32_t)isr7, GDT_KERNEL_CODE_SEGMENT, 0x8E);
	idt_set_gate(0x08, (uint32_t)isr8, GDT_KERNEL_CODE_SEGMENT, 0x8E);
	idt_set_gate(0x09, (uint32_t)isr9, GDT_KERNEL_CODE_SEGMENT, 0x8E);
	idt_set_gate(0x0A, (uint32_t)isr10, GDT_KERNEL_CODE_SEGMENT, 0x8E);
	idt_set_gate(0x0B, (uint32_t)isr11, GDT_KERNEL_CODE_SEGMENT, 0x8E);
	idt_set_gate(0x0C, (uint32_t)isr12, GDT_KERNEL_CODE_SEGMENT, 0x8E);
	idt_set_gate(0x0D, (uint32_t)isr13, GDT_KERNEL_CODE_SEGMENT, 0x8E);
	idt_set_gate(0x0E, (uint32_t)isr14, GDT_KERNEL_CODE_SEGMENT, 0x8E);
	idt_set_gate(0x0F, (uint32_t)isr15, GDT_KERNEL_CODE_SEGMENT, 0x8E);
	idt_set_gate(0x10, (uint32_t)isr16, GDT_KERNEL_CODE_SEGMENT, 0x8E);
	idt_set_gate(0x11, (uint32_t)isr17, GDT_KERNEL_CODE_SEGMENT, 0x8E);
	idt_set_gate(0x12, (uint32_t)isr18, GDT_KERNEL_CODE_SEGMENT, 0x8E);
	idt_set_gate(0x13, (uint32_t)isr19, GDT_KERNEL_CODE_SEGMENT, 0x8E);
	idt_set_gate(0x14, (uint32_t)isr20, GDT_KERNEL_CODE_SEGMENT, 0x8E);
	idt_set_gate(0x15, (uint32_t)isr21, GDT_KERNEL_CODE_SEGMENT, 0x8E);
	idt_set_gate(0x16, (uint32_t)isr22, GDT_KERNEL_CODE_SEGMENT, 0x8E);
	idt_set_gate(0x17, (uint32_t)isr23, GDT_KERNEL_CODE_SEGMENT, 0x8E);
	idt_set_gate(0x18, (uint32_t)isr24, GDT_KERNEL_CODE_SEGMENT, 0x8E);
	idt_set_gate(0x19, (uint32_t)isr25, GDT_KERNEL_CODE_SEGMENT, 0x8E);
	idt_set_gate(0x1A, (uint32_t)isr26, GDT_KERNEL_CODE_SEGMENT, 0x8E);
	idt_set_gate(0x1B, (uint32_t)isr27, GDT_KERNEL_CODE_SEGMENT, 0x8E);
	idt_set_gate(0x1C, (uint32_t)isr28, GDT_KERNEL_CODE_SEGMENT, 0x8E);
	idt_set_gate(0x1D, (uint32_t)isr29, GDT_KERNEL_CODE_SEGMENT, 0x8E);
	idt_set_gate(0x1E, (uint32_t)isr30, GDT_KERNEL_CODE_SEGMENT, 0x8E);
	idt_set_gate(0x1F, (uint32_t)isr31, GDT_KERNEL_CODE_SEGMENT, 0x8E);
	
	idt_install();
	asm volatile ( "sti" );
}

static void idt_set_gate(uint8_t index, uint32_t base, uint16_t selector, uint8_t flags)
{
	idt_entries[index].base_low		= base & 0xFFFF;
	idt_entries[index].base_high	= (base >> 16) & 0xFFFF;
	idt_entries[index].selector		= selector;
	idt_entries[index].zero			= 0x00;
	idt_entries[index].flags		= flags;
}

static void idt_install(void)
{
	asm volatile ( "lidt %0" : : "m"( idt_ptr ));
}
I have tried everything and nothing seems to work. It's expected to say "Received intno: 0x0", but it says "Received Intno: 0xf000ff57". That doesn't seem right at all... Any and all help is appreciated. Thanks.

Re: NASM to GAS assembly help

Posted: Wed Jun 26, 2024 9:12 pm
by Octocontrabass
TheGameMaker90 wrote: Wed Jun 26, 2024 9:57 amFor simplicity's sake, I basically reused James Molloy's IDT system
Careful, that tutorial has a lot of bugs.
TheGameMaker90 wrote: Wed Jun 26, 2024 9:57 am

Code: Select all

asm ( "int $0x0" );
The INT instruction isn't the same as an exception. If you want to test an exception handler, you should use code that will cause the exception, like this:

Code: Select all

asm( "div %ah" );
TheGameMaker90 wrote: Wed Jun 26, 2024 9:57 am0xF000FF57
That's the value located at (physical) address 0 in memory.
TheGameMaker90 wrote: Wed Jun 26, 2024 9:57 am

Code: Select all

	push 0x00
That's a memory operand. You probably wanted an immediate operand. Immediate operands have a "$" prefix.
TheGameMaker90 wrote: Wed Jun 26, 2024 9:57 am

Code: Select all

	asm volatile ( "sti" );
Why are you enabling maskable hardware interrupts?

Re: NASM to GAS assembly help

Posted: Wed Jun 26, 2024 9:27 pm
by TheGameMaker90
Octocontrabass wrote: Wed Jun 26, 2024 9:12 pm
TheGameMaker90 wrote: Wed Jun 26, 2024 9:57 amFor simplicity's sake, I basically reused James Molloy's IDT system
Careful, that tutorial has a lot of bugs.
TheGameMaker90 wrote: Wed Jun 26, 2024 9:57 am

Code: Select all

asm ( "int $0x0" );
The INT instruction isn't the same as an exception. If you want to test an exception handler, you should use code that will cause the exception, like this:

Code: Select all

asm( "div %ah" );
TheGameMaker90 wrote: Wed Jun 26, 2024 9:57 am0xF000FF57
That's the value located at (physical) address 0 in memory.
TheGameMaker90 wrote: Wed Jun 26, 2024 9:57 am

Code: Select all

	push 0x00
That's a memory operand. You probably wanted an immediate operand. Immediate operands have a "$" prefix.
TheGameMaker90 wrote: Wed Jun 26, 2024 9:57 am

Code: Select all

	asm volatile ( "sti" );
Why are you enabling maskable hardware interrupts?
Yeah, I've heard. It's just I got it working once before using his page ands the one you linked. Thanks foir linking it btw. Also his page is down, so I had to use an internet archive.

Good point. It's just how I've tested in the past, but I see the difference. For some reason, using your asm("div %ah"); spams the interrupt then crashes. I'll have to fix that too.

I see, so without the '$' it screws up because that is where the value's address is stored? Wow.

And you are amazing! I can't believe I forgot to put the '$' symbol. Why did I not think of that. It now works as expected thanks to you.

I've already removed it. But I added it initially because I thought it was required to get interrupts working to begin with. STI = SeT Interrupts from what I understand. Effectively enabling them. If there's a reason against it an an invisible level, I'd really love to learn.

Re: NASM to GAS assembly help

Posted: Wed Jun 26, 2024 9:55 pm
by Octocontrabass
TheGameMaker90 wrote: Wed Jun 26, 2024 9:27 pmSTI = SeT Interrupts from what I understand. Effectively enabling them. If there's a reason against it an an invisible level, I'd really love to learn.
The interrupt flag only applies to maskable hardware interrupts. Exceptions, software interrupts, and non-maskable hardware interrupts are always enabled.

Hardware interrupts are generated by hardware outside the CPU. You haven't configured any of that hardware yet, so you don't know what kind of interrupts will arrive when you enable them. For added fun, those hardware interrupts are usually configured to use the same vectors as exceptions, so your exception handlers will run when hardware interrupts arrive, even though there was no exception. (The wiki even calls out how common it is to see a mystery "double fault" caused by an interrupt controller directing IRQ0 to interrupt vector 8.)

Re: NASM to GAS assembly help

Posted: Wed Jun 26, 2024 10:24 pm
by TheGameMaker90
Thanks again Octo, if I could give you 1000 stars for how helpful your responses are, I would.

With that said, what advice do you have on the TSS? I decided that since I have interrupts working, it's time to move onto the TSS. Also, should it have packed alignment or not? If I remember correctly, James Molloy used __attribute__((packed)) with it. But I want to make sure it is absolutely necessary like the GDT and IDT.
Also, does the order the TSS struct members are in matter at all?

Re: NASM to GAS assembly help

Posted: Wed Jun 26, 2024 10:42 pm
by Octocontrabass
TheGameMaker90 wrote: Wed Jun 26, 2024 10:24 pmI decided that since I have interrupts working, it's time to move onto the TSS.
If you're going to set up ring 3 next, sure. A TSS isn't going to do anything for you in ring 0, so there's no reason to set it up before you can use it.
TheGameMaker90 wrote: Wed Jun 26, 2024 10:24 pmAlso, should it have packed alignment or not?
Probably not, but it depends on how you define the struct.
TheGameMaker90 wrote: Wed Jun 26, 2024 10:24 pmAlso, does the order the TSS struct members are in matter at all?
Yes. Just like the GDT and IDT, you need to put things where the CPU expects them to be.

Re: NASM to GAS assembly help

Posted: Wed Jun 26, 2024 10:57 pm
by TheGameMaker90
Okay, so this is intended to be a microkernel. But I do feel like there are things I should setup first. But since you seem to be on another plane expert, what do you recommend? I have the basic setup from the looks of it, but I want to do this right. And as performant as possible. So if not the TSS, then what would you suggest as the next step? Here is my TSS btw just in case:

Code: Select all

#ifndef _ADAMANTIUM_TSS_H
#define _ADAMANTIUM_TSS_H

#include <compiler.h>
#include <stdint.h>

typedef struct tss_entry
{
	uint32_t link;
	uint32_t esp0;
	uint32_t ss0;
	uint32_t esp1;
	uint32_t ss1;
	uint32_t esp2;
	uint32_t ss2;
	uint32_t cr3;
	uint32_t eip;
	uint32_t eflags;
	uint32_t eax;
	uint32_t ecx;
	uint32_t edx;
	uint32_t ebx;
	uint32_t esp;
	uint32_t ebp;
	uint32_t esi;
	uint32_t edi;
	uint32_t es;
	uint32_t cs;
	uint32_t ss;
	uint32_t ds;
	uint32_t fs;
	uint32_t gs;
	uint32_t ldt;
	uint16_t trap;
	uint16_t iomap_base;
} _packed tss_entry_t;

#endif
I have never developed a microkernel before, and I'm using The MINIX book as a tool of sorts. It's very informative and I read most of it once before a few years ago during the pandemic. But I'm not writing MINIX. I'm writing Adamantium. Getting to user mode is on my mind, but I want a fully setup microkernel first.

Re: NASM to GAS assembly help

Posted: Wed Jun 26, 2024 11:44 pm
by Octocontrabass
TheGameMaker90 wrote: Wed Jun 26, 2024 10:57 pmSo if not the TSS, then what would you suggest as the next step?
Memory management is pretty fundamental, so that's usually a good way to go. Or, you could spend some time polishing up your exception handlers, since you'll be relying on them to help you debug your code.

Actually, hold on, how "micro" is your microkernel going to be? Will any of your kernel's memory management be handled in user mode?
TheGameMaker90 wrote: Wed Jun 26, 2024 10:57 pmHere is my TSS btw just in case:
The compiler won't add any padding to that struct, so it doesn't need to be packed.

Re: NASM to GAS assembly help

Posted: Thu Jun 27, 2024 7:53 am
by TheGameMaker90
I've thought of that as well as paging. Honestly, I think memory management would be better in kernel mode. User space has limited access to memory, so I'll be making my life a lot harder by trying to do it in user mode. As for the exception handler, what things should be incorporated that I haven't included in my code? Have you seen the exception handler on my repo by chance?

Oh, and to answer your question, as small as possible while also incorporating all minimum functionality. And maybe a simple keyboard driver using IRQ1 (or interrupt 33). At a base level, my kernel is to have support for drivers in the same manor as other microkernels, but have as little as possible. With that said, the main items I think I may have to do in the kernel before switching to user mode is GDT (done), IDT (done, for now), memory management (as you pointed out), paging, PIC, APIC (possibly), PIT, and maybe the keyboard driver. Unless all of that would indeed make it less of a microkernel. If so, let me know so I can do this right. Thanks.

Re: NASM to GAS assembly help

Posted: Thu Jun 27, 2024 8:10 pm
by Octocontrabass
TheGameMaker90 wrote: Thu Jun 27, 2024 7:53 amAs for the exception handler, what things should be incorporated that I haven't included in my code?
Halting the CPU would be a good start. There's no point in returning from an exception handler if you're not going to do anything to stop the exception from immediately happening again.

If you want your exception handlers to help you debug exceptions, you should at least display the rest of the regs struct. For page faults, you'll also want to see CR2.

At some point, you probably will do something to stop exceptions from immediately happening again, but returning won't work properly because you copied some bugs out of the tutorial. Now would be a great time to go back and fix those bugs.
TheGameMaker90 wrote: Thu Jun 27, 2024 7:53 amUnless all of that would indeed make it less of a microkernel.
I don't think there's a solid definition of what counts as a microkernel, so it's up to you. Personally, I wouldn't put a keyboard driver in a microkernel.

Re: NASM to GAS assembly help

Posted: Fri Jun 28, 2024 11:31 am
by eekee
Octocontrabass wrote: Thu Jun 27, 2024 8:10 pm
TheGameMaker90 wrote: Thu Jun 27, 2024 7:53 amUnless all of that would indeed make it less of a microkernel.
I don't think there's a solid definition of what counts as a microkernel, so it's up to you.
Ayup. There are different reasons for choosing a microkernel, and which reasons you have will influence what you include in the kernel. For example, my reasons are more to do with ease of providing new services than anything else, so I'm not worried about pure microkernel design at all.

Re: NASM to GAS assembly help

Posted: Fri Jun 28, 2024 12:21 pm
by TheGameMaker90
Octocotrabass:
I do halt the CPU. In the bootloader at the end.

Code: Select all

	cli
1:	hlt
	jmp 1b
But you make a good point. How then would I stop it from spamming (it only spammed when I put the division by zero code you gave me, not when I did int $0x0). And aha, so I will be using CR2? I thought about using all four rings for their respective purposes, but decided against it since microkernels tend to already have performance issues and constantly switching rings would only make it worse, but if I'll be using ring 2 anyway, I may as well explore that as an option.

Yeah, as I said, it's most likely temporary code. I like how I'm able to write my fault handler the way it is now, and tbh, I don't know how to write a full fledged IDT on my own. So this speeds up development a bit.

Fair enough. The way I'm thinking of doing it is kind of a bare bones keyboard driver. A one size fits all for any and all supported keyboards. Just plug it in and boom, you're done. But if you want advanced features, like say per key lighting, or media controls like my Corsair K70 RGB keyboard, you would need a user mode driver that essentially overrides the default one.

eekee:
My main reason is that it's smaller and something I could probably actually finish in a reasonable time. But it's also because I want to explore different ways of implementing Oses. During quarantine, I was writing an OS called Adamantine (not Adamantium). I decided to abandon that project because despite the progress I made with it, I could not get to user mode and the code base was getting difficult to manage. Not because of how large it was, but because of how unorganized it was. My hopes is that a microkernel will solve all of my problems. With that said, I don't think there's a one size fits all solution, but it's a decent start. One of the nice things is that my kernel so far has the Multiboot specification in the bag and I tested switching to graphic mode. Nice big black screen, but it works. I'll just have to setup a frame buffer and support for graphical fonts (glyphs) later on. So I'm more confident with this one then that of previous kernel designs.

Re: NASM to GAS assembly help

Posted: Fri Jun 28, 2024 6:03 pm
by Octocontrabass
TheGameMaker90 wrote: Fri Jun 28, 2024 12:21 pmHow then would I stop it from spamming (it only spammed when I put the division by zero code you gave me, not when I did int $0x0).
Halt the CPU instead of returning from the exception handler.
TheGameMaker90 wrote: Fri Jun 28, 2024 12:21 pmAnd aha, so I will be using CR2? I thought about using all four rings
Hold on a minute, I said CR2, not ring 2. Nobody uses ring 2.
TheGameMaker90 wrote: Fri Jun 28, 2024 12:21 pmThe way I'm thinking of doing it is kind of a bare bones keyboard driver. A one size fits all for any and all supported keyboards. Just plug it in and boom, you're done.
Having a basic PS/2 keyboard driver inside your kernel can be helpful during early development, but I wouldn't plan on keeping it permanently. Most keyboards nowadays are actually USB, they'll only work when the firmware runs a USB driver in SMM to emulate a PS/2 keyboard. Once you start your own USB drivers, the firmware emulation goes away. Even if you want to keep it around for the handful of real PS/2 keyboards you can find, you'll still have to deal with other devices that might be plugged into the PS/2 controller alongside the keyboard.

Of course, at the end of the day it's your OS and you can do what you want with it.