~crm/os

99e45b41b99f1cab5196fef4d5163c448b84eb82 — Christos Margiolis 8 months ago a29e0f7
still cannot load kernel after 1mb
13 files changed, 156 insertions(+), 61 deletions(-)

M Makefile
M kern/Makefile
M kern/boot.s
M kern/idt.c
M kern/idt.h
M kern/intr.s
M kern/io.h
M kern/libk.c
M kern/link.ld
A kern/pic.c
A kern/pic.h
M kern/vga.c
M kern/vga.h
M Makefile => Makefile +1 -1
@@ 4,7 4,7 @@ all:
	cd kern && make install clean && cd -

run:
	qemu-system-i386 -hda ${TGTDIR}/os.bin -serial stdio
	qemu-system-i386 -hda ${TGTDIR}/os.bin -d cpu -monitor stdio

clean:
	rm -rf ${TGTDIR}

M kern/Makefile => kern/Makefile +1 -0
@@ 21,6 21,7 @@ SRC= 		*.c *.s
OBJ= 		kern_main.o \
		libk.o \
		idt.o \
		pic.o \
		intr.o \
		vga.o \
		kbd.o \

M kern/boot.s => kern/boot.s +12 -18
@@ 3,8 3,9 @@
[bits 16]

MAGICOFF	equ (0x7c00 + 510)
KERNLOAD	equ 0x1000
KERNOFF		equ 0x1000
STACKSIZE	equ 0x1000
STACKSIZE	equ 8*1024*1024

section .text
	global _start


@@ 12,15 13,13 @@ section .text
; Entry point.
_start:
	cli			; Disable interrupts.
	jmp	0x0000:zeroseg
zeroseg:
	xor	ax, ax		; Clear segment registers.
	mov	ds, ax
	mov	es, ax
	mov	fs, ax
	mov	gs, ax
	mov	ss, ax		; Stack starts at 0.
	mov	bp, _start	; Set the base and stack pointers.
	mov	bp, _start
	mov	sp, bp
	cld			; Read strings from low to high.
	sti			; Enable interrupts back.


@@ 196,12 195,12 @@ diskerr:
	jmp	$		; There's nothing we can do at this point.

disk_packet:
	.size	db 0x10
	.zero	db 0x00
	.count	dw 0x0030	; FIXME: i don't know why this works...
	.off16	dw KERNOFF
	.seg16	dw 0x0000
	.lba	dq 1
	size:	db 0x10
	zero:	db 0x00
	count:	dw 0x0030	; FIXME: i don't know why this works...
	off16:	dw KERNLOAD
	seg16:	dw 0x0000
	lba:	dq 1

; Set up the GDT (Global Descriptor Table).
gdt:


@@ 266,14 265,9 @@ pm_init:
	mov	gs, ax
	mov	ss, ax

	mov	ebp, kern_stack_top
	mov	esp, ebp
	mov	esp, kern_stack_top

	call	kernel_exec
	jmp	$

; Hand control over to the C kernel. Godspeed! You Black Emperor.
kernel_exec:
	; Hand control over to the C kernel. Godspeed! You Black Emperor.
	call	KERNOFF
	jmp	$



@@ 307,6 301,6 @@ dw	0xaa55

section .bss
	align	4096
kern_stack_bottom: equ	$
kern_stack_bottom:
	resb	STACKSIZE
kern_stack_top:

M kern/idt.c => kern/idt.c +5 -27
@@ 1,10 1,10 @@
#include <libc.h>
#include "libk.h"
#include "idt.h"
#include "pic.h"
#include "io.h"

static void idt_set_gate(struct gate_desc *, void *, u_int, u_int, u_int);
static void pic_remap(void);

static struct gate_desc idt[NINT];
static intrhand_t isr[NINT] = { NULL };


@@ 19,22 19,6 @@ idt_set_gate(struct gate_desc *gd, void *func, u_int sel, u_int dpl, u_int type)
	gd->gd_lo = (sel << 16) | (addr & 0xffff);
}

/* TODO: explain. */
static void
pic_remap(void)
{
	outb(PIC_MASTER_CMD, 0x11);
	outb(PIC_SLAVE_CMD, 0x11);
	outb(PIC_MASTER_DATA, 0x20);
	outb(PIC_SLAVE_DATA, 0x28);
	outb(PIC_MASTER_DATA, 0x04);
	outb(PIC_SLAVE_DATA, 0x02);
	outb(PIC_MASTER_DATA, 0x01);
	outb(PIC_SLAVE_DATA, 0x01);
	outb(PIC_MASTER_DATA, 0x00);
	outb(PIC_MASTER_DATA, 0x00);
}

extern void INTVEC(div), INTVEC(dbg), INTVEC(nmsk), INTVEC(bpt), INTVEC(ofl),
    INTVEC(bnd), INTVEC(ill), INTVEC(dna), INTVEC(dbl), INTVEC(fpusegm),
    INTVEC(tss), INTVEC(missing), INTVEC(stk), INTVEC(prot), INTVEC(page),


@@ 141,20 125,13 @@ intr_handler(struct reg *r)
{
	intrhand_t handler;

	/* TODO: dprintf? */
	/* XXX: why did i write this in the first place???? */
	if (r->r_intrno < ARRLEN(exceptmsg))
		printf("sys: trap: %s\n", exceptmsg[r->r_intrno]);
	if ((handler = isr[r->r_intrno]) != NULL)
		handler(r);
	else if (r->r_intrno < ARRLEN(exceptmsg)) {
		dump_regs(r);
		panic("%s: system halted\n", exceptmsg[r->r_intrno]);
	}
	/* EOI */
	if (r->r_intrno >= 40)
		outb(PIC_SLAVE_CMD, 0x20);
	outb(PIC_MASTER_CMD, 0x20);
	pic_eoi(r->r_intrno);
}

void


@@ 163,6 140,7 @@ intr_register_handler(int intrno, intrhand_t handler)
	if (intrno < 0 || intrno >= NINT)
		panic("invalid interrupt number: %d\n", intrno);
	isr[intrno] = handler;
	pic_mask(intrno, PIC_CLEAR_MASK);
}

void


@@ 170,8 148,8 @@ dump_regs(struct reg *r)
{
	printf("eax=%#08x\tebx=%#08x\tecx=%#08x\tedx=%#08x\n",
	    r->r_eax, r->r_ebx, r->r_ecx, r->r_edx);
	printf("esp=%#08x\tebp=%#08x\tesi=%#08x\tedi=%#08x\n",
	    r->r_esp, r->r_ebp, r->r_esi, r->r_edi);
	printf("esi=%#08x\tedi=%#08x\tebp=%#08x\tesp=%#08x\n",
	    r->r_esi, r->r_edi, r->r_ebp, r->r_esp);
	printf("ds=%#08x \tes=%#08x \tfs=%#08x \tgs=%#08x\n",
	    r->r_ds, r->r_es, r->r_fs, r->r_gs);
	printf("eip=%#08x\tcs=%#08x \tss=%#08x \teflags=%#08x\n",

M kern/idt.h => kern/idt.h +0 -5
@@ 38,11 38,6 @@
#define UDSEL		SELECTOR(UDSEG, SELGDT, UPL)
/* TODO: 9front mem.h */

#define PIC_MASTER_CMD	0x20
#define PIC_MASTER_DATA	(PIC_MASTER_CMD + 1)
#define PIC_SLAVE_CMD	0xa0
#define PIC_SLAVE_DATA	(PIC_SLAVE_CMD + 1)

struct gate_desc {
	u_int32_t gd_lo;
	u_int32_t gd_hi;

M kern/intr.s => kern/intr.s +8 -6
@@ 64,22 64,24 @@ intr_common_stub:
	push	es
	push	fs
	push	gs

	mov	ax, 0x10	; Kernel data segment descriptor.
	mov	ds, ax
	mov	es, ax
	mov	fs, ax
	mov	gs, ax
	mov	eax, esp	; Push the stack.
	push	eax
	mov	eax, intr_handler 
	call	eax
	pop	eax
	cld	

	push	esp
	call	intr_handler
	add	esp, 4

	pop	gs
	pop	fs
	pop	es
	pop	ds
	popa
	add	esp, 8		; Clean up ISR info.
	add	esp, 8
	iret			; I spent many hours debugging this...

; TODO: irq_common_stub bx?

M kern/io.h => kern/io.h +6 -0
@@ 66,4 66,10 @@ sti(void)
	__asm__ __volatile("sti");
}

static inline void
io_wait(void)
{
	outb(0x80, 0);
}

#endif /* _IO_H_ */

M kern/libk.c => kern/libk.c +2 -2
@@ 358,7 358,7 @@ printf(const char *fmt, ...)
	va_start(ap, fmt);
	n = vsprintf(buf, fmt, ap);
	va_end(ap);
	vga_write(buf);
	vga_puts(buf);

	return (n);
}


@@ 376,7 376,7 @@ panic(const char *fmt, ...)
	va_start(ap, fmt);
	n = vsprintf(buf, fmt, ap);
	va_end(ap);
	vga_write(buf);
	vga_puts(buf);
	vga_set_color(VGA_BLACK, VGA_WHITE);
	hlt();
}

M kern/link.ld => kern/link.ld +1 -0
@@ 2,6 2,7 @@ ENTRY(_start)
SECTIONS
{
	.text 0x1000 : {
		*(text.prologue)
		*(.text)
		. = ALIGN(4096);
	}

A kern/pic.c => kern/pic.c +84 -0
@@ 0,0 1,84 @@
#include "pic.h"
#include "idt.h"
#include "io.h"

/* 
 * BIOS reserves IRQ 0 to 15 for the PIC. We need to remap it to non-reserved
 * vectors so that there are no conflicts when setting our IRQs.
 */
void
pic_remap(void)
{
	u_char m1, m2;

	/* Save masks */
	m1 = inb(PIC_MASTER_DATA);
	m2 = inb(PIC_SLAVE_DATA);

	/* Reinit both PICs */
	outb(PIC_MASTER_CMD, ICW1_INIT | ICW1_ICW4);
	/* Older machines need some time... */
	io_wait();
	outb(PIC_SLAVE_CMD, ICW1_INIT | ICW1_ICW4);
	io_wait();
	/* Change offsets */
	outb(PIC_MASTER_DATA, PIC_MASTER_OFFT);
	io_wait();
	outb(PIC_SLAVE_DATA, PIC_SLAVE_OFFT);
	io_wait();
	/* Slave PIC at IRQ2 */
	outb(PIC_MASTER_DATA, 0x04);
	io_wait();
	/* Tell Slave PIC its cascade identity */
	outb(PIC_SLAVE_DATA, ICW1_SINGLE);
	io_wait();
	/* 8086 mode */
	outb(PIC_MASTER_DATA, ICW4_8086);
	io_wait();
	outb(PIC_SLAVE_DATA, ICW4_8086);
	io_wait();
	/* Restore masks */
	outb(PIC_MASTER_DATA, m1);
	outb(PIC_SLAVE_DATA, m2);
}

void
pic_eoi(u_int32_t intrno)
{
	outb(PIC_MASTER_CMD, PIC_EOI);
	if (intrno >= IRQ8)
		outb(PIC_SLAVE_CMD, PIC_EOI);
}

void
pic_mask(u_char irq, int flag)
{
	u_int16_t port;
	u_int8_t v;

	if (irq < 8)
		port = PIC_MASTER_DATA;
	else {
		port = PIC_SLAVE_DATA;
		irq -= 8;
	}
	if (flag == PIC_SET_MASK)
		v = inb(port) | (1 << irq);
	else if (flag == PIC_CLEAR_MASK)
		v = inb(port) & ~(1 << irq);
	else
		return;
	outb(port, v);
}

void
pic_on(void)
{
}

void
pic_off(void)
{
	outb(PIC_MASTER_DATA, 0xff);
	outb(PIC_SLAVE_DATA, 0xff);
}

A kern/pic.h => kern/pic.h +34 -0
@@ 0,0 1,34 @@
#ifndef _PIC_H_
#define _PIC_H_

#include <u.h>

#define PIC_MASTER_CMD	0x20
#define PIC_MASTER_DATA	(PIC_MASTER_CMD + 1)
#define PIC_MASTER_OFFT	0x20
#define PIC_SLAVE_CMD	0xa0
#define PIC_SLAVE_DATA	(PIC_SLAVE_CMD + 1)
#define PIC_SLAVE_OFFT	(PIC_MASTER_OFFT + 8)

#define PIC_SET_MASK	0
#define PIC_CLEAR_MASK	1
#define PIC_EOI		0x20	/* End of interrupt */

#define ICW1_ICW4	0x01	/* ICW4 not needed */
#define ICW1_SINGLE	0x02	/* Single cascade mode */
#define ICW1_INTVAL4	0x04	/* Call address interval 4 (8) */
#define ICW1_LEVEL	0x08	/* Level triggered mode */
#define ICW1_INIT	0x10	/* Initialization */
#define ICW4_8086	0x01	/* 8086/88 (MCS-80/85) mode */
#define ICW4_AUTO	0x02	/* Auto EOI */
#define ICW4_BUF_SLAVE	0x08	/* Buffered slave */
#define ICW4_BUF_MASTER	0x0c	/* Buffered master */
#define ICW4_SFNM	0x10	/* Special fully nested */

void		pic_remap(void);
void		pic_eoi(u_int32_t);
void		pic_mask(u_char, int);
void		pic_on(void);
void		pic_off(void);

#endif /* _PIC_H_ */

M kern/vga.c => kern/vga.c +1 -1
@@ 77,7 77,7 @@ vga_putc(char c)
}

void
vga_write(const char *str)
vga_puts(const char *str)
{
	while (*str != '\0')
		vga_putc(*str++);

M kern/vga.h => kern/vga.h +1 -1
@@ 25,7 25,7 @@ enum vga_color {
void vga_clear(u_int8_t, u_int8_t);
void vga_set_color(u_int8_t, u_int8_t);
void vga_putc(char);
void vga_write(const char *);
void vga_puts(const char *);
void vga_curs_enable(u_int8_t, u_int8_t);
void vga_curs_disable(void);
void vga_curs_setpos(int, int);