Pārlūkot izejas kodu

* Total kernel rewrite

tags/v0.99.beta17
Jean-Yves Lamoureux jylam pirms 15 gadiem
vecāks
revīzija
5a9b7d78ee
23 mainītis faili ar 1850 papildinājumiem un 556 dzēšanām
  1. +1
    -1
      configure.ac
  2. +123
    -0
      kernel/boot/bootsect.asm
  3. +101
    -0
      kernel/boot/gdt.c
  4. +132
    -0
      kernel/boot/idt.c
  5. +147
    -0
      kernel/boot/int.asm
  6. +112
    -0
      kernel/boot/interruptions.c
  7. +73
    -0
      kernel/boot/pic.c
  8. +30
    -0
      kernel/boot/stage2.c
  9. +1
    -0
      kernel/boot/stage2.h
  10. +56
    -0
      kernel/drivers/floppy.c
  11. +14
    -0
      kernel/drivers/floppy.h
  12. +101
    -0
      kernel/drivers/keyboard.c
  13. +4
    -0
      kernel/drivers/memory.c
  14. +0
    -0
      kernel/drivers/memory.h
  15. +50
    -0
      kernel/drivers/processor.c
  16. +81
    -0
      kernel/drivers/processor.h
  17. +42
    -0
      kernel/drivers/timer.c
  18. +2
    -0
      kernel/drivers/timer.h
  19. +47
    -374
      kernel/kernel.c
  20. +10
    -108
      kernel/kernel.h
  21. +598
    -0
      kernel/klibc.c
  22. +125
    -0
      kernel/klibc.h
  23. +0
    -73
      kernel/multiboot.S

+ 1
- 1
configure.ac Parādīt failu

@@ -308,7 +308,7 @@ fi

if test "${enable_vga}" = "yes"; then
ac_cv_my_have_vga="yes"
CPPFLAGS="${CPPFLAGS} -I. -D__KERNEL__ -nostdinc -include kernel/kernel.h -fno-stack-protector"
CPPFLAGS="${CPPFLAGS} -I. -D__KERNEL__ -nostdinc -include kernel/klibc.h -fno-stack-protector"
CFLAGS="${CFLAGS} -fno-builtin -O2 -Wall -fno-stack-protector"
CCASFLAGS="${CCASFLAGS} -I. -fno-stack-protector"
LDFLAGS="${LDFLAGS} -nostdlib -Wl,-N -Wl,-Ttext -Wl,100000 -fno-stack-protector"


+ 123
- 0
kernel/boot/bootsect.asm Parādīt failu

@@ -0,0 +1,123 @@
; Boot sector, freely inspired by http://jojo.ouvaton.org/dossiers/boot_sector/tutorial02.html
; Sets a GDT and protected mode
; Copy the kernel (or stage2) to 0x1000 (linear)
; Max kernel size is 25600 bytes (50 sectors)


%define BASE 0x100 ; 0x0100:0x0 = 0x1000
%define KSIZE 50

[BITS 16]
[ORG 0x0]

; Code starts here, jump to our real entry point, skipping print
jmp start

; print string using BIOS
print:
push ax
push bx
.start:
lodsb ; ds:si -> al
cmp al,0
jz .fin
mov ah,0x0E ; 0x0e function of BIOS 0x10 interruption
mov bx,0x07 ; bx -> attribute, al -> ascii
int 0x10
jmp .start
.fin:
pop bx
pop ax
ret
; Entry point
start:
mov [bootdrv],dl ; boot drive

; Stack and section initialization at 0x07C0
mov ax,0x07C0
mov ds,ax
mov es,ax
mov ax,0x8000 ; stack at 0xFFFF
mov ss,ax
mov sp, 0xf000

; print 'Loading kernel ...'
mov si, ldKernel
call print

; Load kernel
xor ax,ax
int 0x13

push es
mov ax,BASE
mov es,ax
mov bx,0
mov ah,2
mov al,KSIZE
mov ch,0
mov cl,2
mov dh,0
mov dl,[bootdrv]
int 0x13
pop es

; GDT pointer
mov ax,gdtend ; GDT limit
mov bx,gdt
sub ax,bx
mov word [gdtptr],ax

xor eax,eax ; GDT linear address
xor ebx,ebx
mov ax,ds
mov ecx,eax
shl ecx,4
mov bx,gdt
add ecx,ebx
mov dword [gdtptr+2],ecx

; pmode
cli
lgdt [gdtptr] ; load GDT
mov eax, cr0
or ax,1
mov cr0,eax ; enter Protected Mode

jmp next
next:
mov ax,0x10 ; data segment
mov ds,ax
mov fs,ax
mov gs,ax
mov es,ax
mov ss,ax
mov esp,0x9F000

jmp dword 0x8:0x1000 ; jump to kernel _start at 0x1000 of 'second' selector (*8)


;--------------------------------------------------------------------
bootdrv: db 0
ldKernel db "Loading kernel ...",13,10,0
;--------------------------------------------------------------------
gdt:
db 0,0,0,0,0,0,0,0
gdt_cs:
db 0xFF,0xFF,0x0,0x0,0x0,10011011b,11011111b,0x0
gdt_ds:
db 0xFF,0xFF,0x0,0x0,0x0,10010011b,11011111b,0x0
gdtend:

;--------------------------------------------------------------------
gdtptr:
dw 0 ; limit
dd 0 ; base


;--------------------------------------------------------------------
;; fill remaining space with NOPs
times 510-($-$$) db 144
dw 0xAA55

+ 101
- 0
kernel/boot/gdt.c Parādīt failu

@@ -0,0 +1,101 @@
/*
*'freely' inspired by http://jojo.ouvaton.org/dossiers/boot_sector/tutorial02.html
* (actually, that's mostly copied, with minor compilation fixes)
*/
#include "kernel.h"
#include "klibc.h"

#define GDTBASE 0x800 /* Physical address of GDT */
#define GDTSIZE 0xFF /* Maximum table size (in entries) */

/* Segment descriptor */
struct gdtdesc {
u16 lim0_15;
u16 base0_15;
u8 base16_23;
u8 acces;
u8 lim16_19 : 4;
u8 other : 4;
u8 base24_31;
} __attribute__ ((packed));

/* GDTR register */
struct gdtr {
u16 limite ;
u32 base ;
} __attribute__ ((packed));
struct gdtr kgdtr;


struct gdtdesc kgdt[GDTSIZE] = {{0, 0, 0, 0, 0, 0, 0}};
unsigned int kgdtptr = 1;

void init_code_desc(u32 base, u32 limite, struct gdtdesc* desc);
void init_data_desc(u32 base, u32 limite, struct gdtdesc* desc);
void add_gdt_desc(struct gdtdesc desc);
void init_gdt(void);



void init_gdt_desc(u32 base, u32 limite, u8 acces, u8 other, struct gdtdesc* desc) {
desc->lim0_15 = (limite & 0xffff);
desc->base0_15 = (base & 0xffff);
desc->base16_23 = (base & 0xff0000)>>16;
desc->acces = acces;
desc->lim16_19 = (limite & 0xf0000)>>16;
desc->other = (other & 0xf);
desc->base24_31 = (base & 0xff000000)>>24;
return;
}


void init_code_desc(u32 base, u32 limite, struct gdtdesc* desc) {
init_gdt_desc(base, limite, 0x9B, 0x0D, desc);
}

void init_data_desc(u32 base, u32 limite, struct gdtdesc* desc) {
init_gdt_desc(base, limite, 0x93, 0x0D, desc);
}

void add_gdt_desc(struct gdtdesc desc) {
kgdt[kgdtptr] = desc;
kgdtptr++;
}

void init_gdt(void) {
struct gdtdesc code, data, stack;
/* initialisation des descripteurs de segment */
init_code_desc(0x0, 0xFFFFF, &code);
init_data_desc(0x0, 0xFFFFF, &data);
init_gdt_desc(0, 0x10, 0x97, 0x0D, &stack);
add_gdt_desc(code);
add_gdt_desc(data);
add_gdt_desc(stack);
/* initialisation de la structure pour GDTR */
kgdtr.limite = GDTSIZE*8;
kgdtr.base = GDTBASE;
/* recopie de la GDT a son adresse */
memcpy((void*)kgdtr.base, kgdt, kgdtr.limite);
/* chargement du registre GDTR */
asm("lgdtl (kgdtr)");
/* initialisation des segments */
asm(" movw $0x10,%ax \n \
movw %ax, %ds \n \
movw %ax, %es \n \
movw %ax, %fs \n \
movw %ax, %gs \n \
movw $0x18,%ax \n \
movw %ax, %ss \n \
movl $0x1FFFF,%esp \n \
nop \n \
nop \n \
ljmp $0x08,$next \n \
next: \n");
}



+ 132
- 0
kernel/boot/idt.c Parādīt failu

@@ -0,0 +1,132 @@
/*
*'freely' inspired by http://jojo.ouvaton.org/dossiers/boot_sector/tutorial02.html
* (actually, that's mostly copied, with minor compilation fixes)
*/
#include "kernel.h"
#include "klibc.h"

#define IDTBASE 0 /* GDT Physical address */
#define IDTSIZE 256 /* Max descriptor count */
#define INTGATE 0x8E00 /* Interruptions */
#define TRAPGATE 0x8F00 /* Syscalls */
#define TASKGATE 0x8500 /* Task switching */

/* segment descriptor */
struct idtdesc {
u16 offset0_15;
u16 select;
u16 type;
u16 offset16_31;
} __attribute__ ((packed));

/* IDTR register */
struct idtr {
u16 limite;
u32 base;
} __attribute__ ((packed));

struct idtr kidtr;

/* IDT table */
struct idtdesc kidt[IDTSIZE] = {{0, 0, 0, 0}};

/* pointer on a free IDT entry */
unsigned int kidtptr = 0;

void default_int(void);
void k_int0(void);
void k_int1(void);
void k_int2(void);
void k_int3(void);
void k_int4(void);
void k_int5(void);
void k_int6(void);
void k_int7(void);
void k_int8(void);
void k_int9(void);
void k_int10(void);
void k_int11(void);
void k_int12(void);
void k_int13(void);
void k_int14(void);
void k_int15(void);
void k_int16(void);
void k_int17(void);
void k_int18(void);
void k_irq0(void);
void k_irq1(void);
void k_irq2(void);
void k_irq3(void);
void k_irq4(void);
void k_irq5(void);
void k_irq6(void);
void k_irq7(void);
void k_irq8(void);


void init_idt_desc(u32 offset, u16 select, u16 type, struct idtdesc* desc) {
desc->offset0_15 = (offset & 0xffff);
desc->select = select;
desc->type = type;
desc->offset16_31 = (offset & 0xffff0000) >> 16;
return;
}


void add_idt_desc(struct idtdesc desc) {
kidt[kidtptr++] = desc;
return;
}


void init_idt(void) {
struct idtdesc desc;
int i;

for(i=0;i<IDTSIZE;i++) {
init_idt_desc((u32)default_int, 0x08, INTGATE, &desc);
add_idt_desc(desc);
}

init_idt_desc((u32)k_int0, 0x08, INTGATE, &kidt[0]);
init_idt_desc((u32)k_int1, 0x08, INTGATE, &kidt[1]);
init_idt_desc((u32)k_int2, 0x08, INTGATE, &kidt[2]);
init_idt_desc((u32)k_int3, 0x08, INTGATE, &kidt[3]);
init_idt_desc((u32)k_int4, 0x08, INTGATE, &kidt[4]);
init_idt_desc((u32)k_int5, 0x08, INTGATE, &kidt[5]);
init_idt_desc((u32)k_int6, 0x08, INTGATE, &kidt[6]);
init_idt_desc((u32)k_int7, 0x08, INTGATE, &kidt[7]);
init_idt_desc((u32)k_int8, 0x08, INTGATE, &kidt[8]);
init_idt_desc((u32)k_int9, 0x08, INTGATE, &kidt[9]);
init_idt_desc((u32)k_int10, 0x08, INTGATE, &kidt[10]);
init_idt_desc((u32)k_int11, 0x08, INTGATE, &kidt[11]);
init_idt_desc((u32)k_int12, 0x08, INTGATE, &kidt[12]);
init_idt_desc((u32)k_int13, 0x08, INTGATE, &kidt[13]);
init_idt_desc((u32)k_int14, 0x08, INTGATE, &kidt[14]);
init_idt_desc((u32)k_int15, 0x08, INTGATE, &kidt[15]);
init_idt_desc((u32)k_int16, 0x08, INTGATE, &kidt[16]);
init_idt_desc((u32)k_int17, 0x08, INTGATE, &kidt[17]);
init_idt_desc((u32)k_int18, 0x08, INTGATE, &kidt[18]);
init_idt_desc((u32)k_irq0, 0x08, INTGATE, &kidt[32]);
init_idt_desc((u32)k_irq1, 0x08, INTGATE, &kidt[33]);
init_idt_desc((u32)k_irq2, 0x08, INTGATE, &kidt[34]);
init_idt_desc((u32)k_irq3, 0x08, INTGATE, &kidt[35]);
init_idt_desc((u32)k_irq4, 0x08, INTGATE, &kidt[36]);
init_idt_desc((u32)k_irq5, 0x08, INTGATE, &kidt[37]);
init_idt_desc((u32)k_irq6, 0x08, INTGATE, &kidt[38]);
init_idt_desc((u32)k_irq7, 0x08, INTGATE, &kidt[39]);
init_idt_desc((u32)k_irq8, 0x08, INTGATE, &kidt[40]);
kidtr.limite = IDTSIZE*8;
kidtr.base = IDTBASE;
memcpy((void*)kidtr.base, kidt, kidtr.limite);
#define printf(format, ...) { char __str[255]; sprintf (__str, format, __VA_ARGS__); print(__str);}

printf("Loading IDT from 0x%x\n", kidtr);
#undef printf
asm("lidtl (kidtr)");
}

+ 147
- 0
kernel/boot/int.asm Parādīt failu

@@ -0,0 +1,147 @@
extern idt_default_int,idt_int0, idt_int1, idt_int2, idt_int3, idt_int4, idt_int5, idt_int6, idt_int7, idt_int8, idt_int9, idt_int10, idt_int11, idt_int12, idt_int13, idt_int14, idt_int15, idt_int16, idt_int17, idt_int18, idt_irq0, kbd_int, idt_irq2, idt_irq3, idt_irq4, idt_irq5, idt_irq6, idt_irq7, idt_irq8
global default_int, k_int0, k_int1, k_int2, k_int3, k_int4, k_int5, k_int6, k_int7, k_int8, k_int9, k_int10, k_int11, k_int12, k_int13, k_int14, k_int15, k_int16, k_int17, k_int18, k_irq0, k_irq1, k_irq2, k_irq3, k_irq4, k_irq5, k_irq6, k_irq7, k_irq8
default_int:
call idt_default_int ; Call C function
mov al,0x20 ; End Of Interruption
out 0x20,al ; Send EOI to PIC
iret
k_int0:
call idt_int0
mov al,0x20
out 0x20,al
iret
k_int1:
call idt_int1
mov al,0x20
out 0x20,al
iret
k_int2:
call idt_int2
mov al,0x20
out 0x20,al
iret
k_int3:
call idt_int3
mov al,0x20
out 0x20,al
iret
k_int4:
call idt_int4
mov al,0x20
out 0x20,al
iret
k_int5:
call idt_int5
mov al,0x20
out 0x20,al
iret
k_int6:
call idt_int6
mov al,0x20
out 0x20,al
iret
k_int7:
call idt_int7
mov al,0x20
out 0x20,al
iret
k_int8:
call idt_int8
mov al,0x20
out 0x20,al
iret
k_int9:
call idt_int9
mov al,0x20
out 0x20,al
iret
k_int10:
call idt_int10
mov al,0x20
out 0x20,al
iret
k_int11:
call idt_int11
mov al,0x20
out 0x20,al
iret
k_int12:
call idt_int12
mov al,0x20
out 0x20,al
iret
k_int13:
call idt_int13
mov al,0x20
out 0x20,al
iret
k_int14:
call idt_int14
mov al,0x20
out 0x20,al
iret
k_int15:
call idt_int15
mov al,0x20
out 0x20,al
iret
k_int16:
call idt_int16
mov al,0x20
out 0x20,al
iret
k_int17:
call idt_int17
mov al,0x20
out 0x20,al
iret
k_int18:
call idt_int18
mov al,0x20
out 0x20,al
iret
k_irq0:
call idt_irq0
mov al,0x20
out 0x20,al
iret
k_irq1:
call kbd_int
mov al,0x20
out 0x20,al
iret
k_irq2:
call idt_irq2
mov al,0x20
out 0x20,al
iret
k_irq3:
call idt_irq3
mov al,0x20
out 0x20,al
iret
k_irq4:
call idt_irq4
mov al,0x20
out 0x20,al
iret
k_irq5:
call idt_irq5
mov al,0x20
out 0x20,al
iret
k_irq6:
call idt_irq6
mov al,0x20
out 0x20,al
iret
k_irq7:
call idt_irq7
mov al,0x20
out 0x20,al
iret
k_irq8:
call idt_irq8
mov al,0x20
out 0x20,al
iret

+ 112
- 0
kernel/boot/interruptions.c Parādīt failu

@@ -0,0 +1,112 @@
#include "kernel.h"
#include "klibc.h"
#include "drivers/timer.h"


void idt_default_int(void) {
print("!! Unknown interrupt\n");
}

void idt_int0(void) {
print("!! Divide by 0\n ");
}
void idt_int1(void) {
print("!! Debug exception ");
}
void idt_int2(void) {
print("!! NMI ");
}
void idt_int3(void) {
print("!! Breakpoint ");
}
void idt_int4(void) {
print("!! Overflow ");
}
void idt_int5(void) {
print("!! BoundCheck ");
}
void idt_int6(void) {
print("!! Invalid Opcode ");
}
void idt_int7(void) {
print("!! Coprocessor not available ");
}
void idt_int8(void) {
print("!! Double Fault ");
}
void idt_int9(void) {
print("!! Coprocessor segment overrun ");
}
void idt_int10(void) {
print("!! Invalid TSS ");
}
void idt_int11(void) {
print("!! Segment not present ");
}
void idt_int12(void) {
print("!! Stack exception ");
}
void idt_int13(void) {
print("!! General protection exception ");
}
void idt_int14(void) {
print("!! Page fault ");
}
void idt_int15(void) {
print("!! Intel reserved int ");
}
void idt_int16(void) {
print("!! Coprocessor error ");
}
void idt_int17(void) {
print("!! Intel reserved (2) ");
}
void idt_int18(void) {
print("i18 ");
}


/* Used by Channel0 timer */
void idt_irq0(void) {
ticks++;
}
void idt_irq2(void) {
print("IRQ 2");
}
void idt_irq3(void) {
print("IRQ 3");
}
void idt_irq4(void) {
print("IRQ 4");
}
void idt_irq5(void) {
print("IRQ 5");
}
void idt_irq6(void) {
print("IRQ 6");
}
void idt_irq7(void) {
print("IRQ 7");
}
void idt_irq8(void) {
print("IRQ 8");
}


extern unsigned char kbdmap[];

/* Keyboard irq is 1 */
void kbd_int(void) {
unsigned char i;
do {
i=inb(0x64);
} while((i & 0x01) == 0);
i=inb(0x60);
i--;
if(i<0x80){
putcar(kbdmap[i*4]);
}
}


+ 73
- 0
kernel/boot/pic.c Parādīt failu

@@ -0,0 +1,73 @@
#include "klibc.h"

#define PIC_MASTER_ICW1 0x20
#define PIC_MASTER_ICW2 0x21

#define PIC_SLAVE_ICW1 0xA0
#define PIC_SLAVE_ICW2 0xA1


void init_pic(void)
{
/* MASTER */
outbp(PIC_MASTER_ICW1,0x11); // Init 8259A-1
/* ICW2 - start vector = 32 */
outbp(PIC_MASTER_ICW2,0x20); // IRQ 0-7 mapped to 0x20-0x27
/* IICW3 */
outbp(PIC_MASTER_ICW2,0x04); // 8259A-1 has slave
/* ICW4 */
outbp(PIC_MASTER_ICW2,0x01);
/* Int mask */
outbp(PIC_MASTER_ICW2,0xFF);
/* SLAVE */
outbp(PIC_SLAVE_ICW1,0x11);
/* ICW2 - start vector = 96 */
outbp(PIC_SLAVE_ICW2,0x70);
/* ICW3 */
outbp(PIC_SLAVE_ICW2,0x02);
/* ICW4 */
outbp(PIC_SLAVE_ICW2,0x01);
/* Int Mask */
outbp(PIC_SLAVE_ICW2,0xFF);
/* Unmask irqs */
outbp(0x21,0xFD);
}

static unsigned int cached_irq_mask = 0xffff;

#define __byte(x,y) (((unsigned char *)&(y))[x])
#define cached_21 (__byte(0,cached_irq_mask))
#define cached_A1 (__byte(1,cached_irq_mask))

void disable_interrupt(char irq)
{
unsigned int mask = 1 << irq;
cached_irq_mask |= mask;
if (irq & 8) {
outb(0xA1, cached_A1);
} else {
outb(0x21, cached_21);
}
}

void enable_interrupt(char irq)
{
unsigned int mask = ~(1 << irq);
cached_irq_mask &= mask;
if (irq & 8) {
outb(0xA1, cached_A1);
} else {
outb(0x21, cached_21);
}

}





+ 30
- 0
kernel/boot/stage2.c Parādīt failu

@@ -0,0 +1,30 @@
#include "kernel.h"
#include "klibc.h"

extern int kmain(void);


/* Entry point
* bootsect.asm loaded this file at 0x0100:0x0, which is mapped
* at 0x8:0x1000 (selector+8bytes, offset 1000 (0x100 + 0x0)
*/

/* 0x1000 */
void _start(void) {

clearscreen();
init_gdt();
print("Loading IDT\n");
init_idt();
print("Loading PIC\n");
init_pic();
print("Running kmain()\n");
sti;
kmain(); /* Call kernel's kmain() */
while(1) { /* Never return */
print("hlt;\n");
}
}


+ 1
- 0
kernel/boot/stage2.h Parādīt failu

@@ -0,0 +1 @@
extern int _start(void);

+ 56
- 0
kernel/drivers/floppy.c Parādīt failu

@@ -0,0 +1,56 @@

#include "kernel.h"
#include "klibc.h"
#include "floppy.h"


int floppy_get_info(struct floppy_info *floppy_info)
{
outb(0x70, 0x10);
unsigned char c = inb(0x71);
int a = c >> 4;
int b = c & 0xF;

char *drive_type[6] = {
"none",
"360kb 5.25in",
"1.2mb 5.25in",
"720kb 3.5in",
"1.44mb 3.5in",
"2.88mb 3.5in"
};

memcpy(floppy_info->drive[0].type, drive_type[a],
strlen(drive_type[a]) + 1);
memcpy(floppy_info->drive[1].type, drive_type[b],
strlen(drive_type[b]) + 1);

floppy_info->count = 0;
if (a != 0)
floppy_info->count++;
if (b != 0)
floppy_info->count++;

return 0;
}

void floppy_print_info(struct floppy_info *floppy_info)
{
printf("%d floppy drive(s)\n", floppy_info->count);
if (floppy_info->count)
{
printf("Floppy %d type %s\n", 0, floppy_info->drive[0].type);
if (floppy_info->count == 2)
{
printf("Floppy %d type %s\n", 1, floppy_info->drive[1].type);
}
}

}

int floppy_get_status(void)
{
unsigned char c = inb(0x1F7);
return c;
}

+ 14
- 0
kernel/drivers/floppy.h Parādīt failu

@@ -0,0 +1,14 @@
struct floppy_drive {
char type[16];
u8 status;
};

struct floppy_info {
int count;
struct floppy_drive drive[2];
};

int floppy_get_info(struct floppy_info *floppy_info);
void floppy_print_info(struct floppy_info *floppy_info);

int floppy_get_status(void);

+ 101
- 0
kernel/drivers/keyboard.c Parādīt failu

@@ -0,0 +1,101 @@
#include "kernel.h"

unsigned char kbdmap[] = {
0x1B, 0x1B, 0x1B, 0x1B, /* esc (0x01) */
'1', '!', '1', '1',
'2', '@', '2', '2',
'3', '#', '3', '3',
'4', '$', '4', '4',
'5', '%', '5', '5',
'6', '^', '6', '6',
'7', '&', '7', '7',
'8', '*', '8', '8',
'9', '(', '9', '9',
'0', ')', '0', '0',
'-', '_', '-', '-',
'=', '+', '=', '=',
0x08, 0x08, 0x7F, 0x08, /* backspace */
0x09, 0x09, 0x09, 0x09, /* tab */
'q', 'Q', 'q', 'q',
'w', 'W', 'w', 'w',
'e', 'E', 'e', 'e',
'r', 'R', 'r', 'r',
't', 'T', 't', 't',
'y', 'Y', 'y', 'y',
'u', 'U', 'u', 'u',
'i', 'I', 'i', 'i',
'o', 'O', 'o', 'o',
'p', 'P', 'p', 'p',
'[', '{', '[', '[',
']', '}', ']', ']',
0x0A, 0x0A, 0x0A, 0x0A, /* enter */
0xFF, 0xFF, 0xFF, 0xFF, /* ctrl */
'a', 'A', 'a', 'a',
's', 'S', 's', 's',
'd', 'D', 'd', 'd',
'f', 'F', 'f', 'f',
'g', 'G', 'g', 'g',
'h', 'H', 'h', 'h',
'j', 'J', 'j', 'j',
'k', 'K', 'k', 'k',
'l', 'L', 'l', 'l',
';', ':', ';', ';',
0x27, 0x22, 0x27, 0x27, /* '" */
'`', '~', '`', '`', /* `~ */
0xFF, 0xFF, 0xFF, 0xFF, /* Lshift (0x2a) */
'\\', '|', '\\', '\\',
'z', 'Z', 'z', 'z',
'x', 'X', 'x', 'x',
'c', 'C', 'c', 'c',
'v', 'V', 'v', 'v',
'b', 'B', 'b', 'b',
'n', 'N', 'n', 'n',
'm', 'M', 'm', 'm',
0x2C, 0x3C, 0x2C, 0x2C, /* ,< */
0x2E, 0x3E, 0x2E, 0x2E, /* .> */
0x2F, 0x3F, 0x2F, 0x2F, /* /? */
0xFF, 0xFF, 0xFF, 0xFF, /* Rshift (0x36) */
0xFF, 0xFF, 0xFF, 0xFF, /* (0x37) */
0xFF, 0xFF, 0xFF, 0xFF, /* (0x38) */
0xFF, 0xFF, 0xFF, 0xFF, /* (0x39) */
0xFF, 0xFF, 0xFF, 0xFF, /* (0x3a) */
0xFF, 0xFF, 0xFF, 0xFF, /* (0x3b) */
0xFF, 0xFF, 0xFF, 0xFF, /* (0x3c) */
0xFF, 0xFF, 0xFF, 0xFF, /* (0x3d) */
0xFF, 0xFF, 0xFF, 0xFF, /* (0x3e) */
0xFF, 0xFF, 0xFF, 0xFF, /* (0x3f) */
0xFF, 0xFF, 0xFF, 0xFF, /* (0x40) */
0xFF, 0xFF, 0xFF, 0xFF, /* (0x41) */
0xFF, 0xFF, 0xFF, 0xFF, /* (0x42) */
0xFF, 0xFF, 0xFF, 0xFF, /* (0x43) */
0xFF, 0xFF, 0xFF, 0xFF, /* (0x44) */
0xFF, 0xFF, 0xFF, 0xFF, /* (0x45) */
0xFF, 0xFF, 0xFF, 0xFF, /* (0x46) */
0xFF, 0xFF, 0xFF, 0xFF, /* (0x47) */
0xFF, 0xFF, 0xFF, 0xFF, /* (0x48) */
0xFF, 0xFF, 0xFF, 0xFF, /* (0x49) */
0xFF, 0xFF, 0xFF, 0xFF, /* (0x4a) */
0xFF, 0xFF, 0xFF, 0xFF, /* (0x4b) */
0xFF, 0xFF, 0xFF, 0xFF, /* (0x4c) */
0xFF, 0xFF, 0xFF, 0xFF, /* (0x4d) */
0xFF, 0xFF, 0xFF, 0xFF, /* (0x4e) */
0xFF, 0xFF, 0xFF, 0xFF, /* (0x4f) */
0xFF, 0xFF, 0xFF, 0xFF, /* (0x50) */
0xFF, 0xFF, 0xFF, 0xFF, /* (0x51) */
0xFF, 0xFF, 0xFF, 0xFF, /* (0x52) */
0xFF, 0xFF, 0xFF, 0xFF, /* (0x53) */
0xFF, 0xFF, 0xFF, 0xFF, /* (0x54) */
0xFF, 0xFF, 0xFF, 0xFF, /* (0x55) */
0xFF, 0xFF, 0xFF, 0xFF, /* (0x56) */
0xFF, 0xFF, 0xFF, 0xFF, /* (0x57) */
0xFF, 0xFF, 0xFF, 0xFF, /* (0x58) */
0xFF, 0xFF, 0xFF, 0xFF, /* (0x59) */
0xFF, 0xFF, 0xFF, 0xFF, /* (0x5a) */
0xFF, 0xFF, 0xFF, 0xFF, /* (0x5b) */
0xFF, 0xFF, 0xFF, 0xFF, /* (0x5c) */
0xFF, 0xFF, 0xFF, 0xFF, /* (0x5d) */
0xFF, 0xFF, 0xFF, 0xFF, /* (0x5e) */
0xFF, 0xFF, 0xFF, 0xFF, /* (0x5f) */
0xFF, 0xFF, 0xFF, 0xFF, /* (0x60) */
0xFF, 0xFF, 0xFF, 0xFF /* (0x61) */
};

+ 4
- 0
kernel/drivers/memory.c Parādīt failu

@@ -0,0 +1,4 @@
#include "kernel.h"
#include "klibc.h"
#include "memory.h"


+ 0
- 0
kernel/drivers/memory.h Parādīt failu


+ 50
- 0
kernel/drivers/processor.c Parādīt failu

@@ -0,0 +1,50 @@
/*
* processor.c
*
*
* Created by Jean-Yves Lamoureux on 12/19/09.
* Copyright 2009 Frob. All rights reserved.
*
*/
#include "kernel.h"
#include "klibc.h"
#include "processor.h"


int processor_get_info(struct processor_info *processor_info)
{
/* Vendor String */
int code = CPUID_GETVENDORSTRING;
unsigned int where[5];
char *s;
asm volatile ("cpuid":"=a" (*where), "=b"(*(where + 1)),
"=c"(*(where + 2)), "=d"(*(where + 3)):"0"(code));

s = (char *)where;

unsigned int a = 0;
unsigned int b = where[1];
unsigned int d = where[3];
unsigned int c = where[2];

where[0] = b;
where[1] = d;
where[2] = c;
where[3] = 0;

memcpy(processor_info->vendor, where, 13);

/* Features */
code = CPUID_GETFEATURES;
asm volatile ("cpuid":"=a" (a), "=d"(d):"0"(code):"ecx", "ebx");
processor_info->features = a;

return 0;
}

void processor_print_info(struct processor_info *processor_info)
{
printf("CPU%d\n", processor_info->id);
printf("Vendor ID : %s\n", processor_info->vendor);
printf("Features : 0x%x\n", processor_info->features);
}

+ 81
- 0
kernel/drivers/processor.h Parādīt failu

@@ -0,0 +1,81 @@

enum cpuid_requests {
CPUID_GETVENDORSTRING,
CPUID_GETFEATURES,
CPUID_GETTLB,
CPUID_GETSERIAL,
CPUID_INTELEXTENDED=0x80000000,
CPUID_INTELFEATURES,
CPUID_INTELBRANDSTRING,
CPUID_INTELBRANDSTRINGMORE,
CPUID_INTELBRANDSTRINGEND,
};

enum {
CPUID_FEAT_ECX_SSE3 = 1 << 0,
CPUID_FEAT_ECX_PCLMUL = 1 << 1,
CPUID_FEAT_ECX_DTES64 = 1 << 2,
CPUID_FEAT_ECX_MONITOR = 1 << 3,
CPUID_FEAT_ECX_DS_CPL = 1 << 4,
CPUID_FEAT_ECX_VMX = 1 << 5,
CPUID_FEAT_ECX_SMX = 1 << 6,
CPUID_FEAT_ECX_EST = 1 << 7,
CPUID_FEAT_ECX_TM2 = 1 << 8,
CPUID_FEAT_ECX_SSSE3 = 1 << 9,
CPUID_FEAT_ECX_CID = 1 << 10,
CPUID_FEAT_ECX_FMA = 1 << 12,
CPUID_FEAT_ECX_CX16 = 1 << 13,
CPUID_FEAT_ECX_ETPRD = 1 << 14,
CPUID_FEAT_ECX_PDCM = 1 << 15,
CPUID_FEAT_ECX_DCA = 1 << 18,
CPUID_FEAT_ECX_SSE4_1 = 1 << 19,
CPUID_FEAT_ECX_SSE4_2 = 1 << 20,
CPUID_FEAT_ECX_x2APIC = 1 << 21,
CPUID_FEAT_ECX_MOVBE = 1 << 22,
CPUID_FEAT_ECX_POPCNT = 1 << 23,
CPUID_FEAT_ECX_XSAVE = 1 << 26,
CPUID_FEAT_ECX_OSXSAVE = 1 << 27,
CPUID_FEAT_ECX_AVX = 1 << 28,
CPUID_FEAT_EDX_FPU = 1 << 0,
CPUID_FEAT_EDX_VME = 1 << 1,
CPUID_FEAT_EDX_DE = 1 << 2,
CPUID_FEAT_EDX_PSE = 1 << 3,
CPUID_FEAT_EDX_TSC = 1 << 4,
CPUID_FEAT_EDX_MSR = 1 << 5,
CPUID_FEAT_EDX_PAE = 1 << 6,
CPUID_FEAT_EDX_MCE = 1 << 7,
CPUID_FEAT_EDX_CX8 = 1 << 8,
CPUID_FEAT_EDX_APIC = 1 << 9,
CPUID_FEAT_EDX_SEP = 1 << 11,
CPUID_FEAT_EDX_MTRR = 1 << 12,
CPUID_FEAT_EDX_PGE = 1 << 13,
CPUID_FEAT_EDX_MCA = 1 << 14,
CPUID_FEAT_EDX_CMOV = 1 << 15,
CPUID_FEAT_EDX_PAT = 1 << 16,
CPUID_FEAT_EDX_PSE36 = 1 << 17,
CPUID_FEAT_EDX_PSN = 1 << 18,
CPUID_FEAT_EDX_CLF = 1 << 19,
CPUID_FEAT_EDX_DTES = 1 << 21,
CPUID_FEAT_EDX_ACPI = 1 << 22,
CPUID_FEAT_EDX_MMX = 1 << 23,
CPUID_FEAT_EDX_FXSR = 1 << 24,
CPUID_FEAT_EDX_SSE = 1 << 25,
CPUID_FEAT_EDX_SSE2 = 1 << 26,
CPUID_FEAT_EDX_SS = 1 << 27,
CPUID_FEAT_EDX_HTT = 1 << 28,
CPUID_FEAT_EDX_TM1 = 1 << 29,
CPUID_FEAT_EDX_IA64 = 1 << 30,
CPUID_FEAT_EDX_PBE = 1 << 31
};

struct processor_info {
int id;
char vendor[13];
unsigned int features;
};


int processor_get_info(struct processor_info *processor_info);
void processor_print_info(struct processor_info *processor_info);

+ 42
- 0
kernel/drivers/timer.c Parādīt failu

@@ -0,0 +1,42 @@

#include "kernel.h"
#include "klibc.h"
#include "timer.h"

u32 ticks = 0;

void timer_phase(int hz)
{
unsigned int divisor = 1193180 / hz; /* Calculate our divisor */
/*
0x43 is the Mode/Command register
From http://wiki.osdev.org/Programmable_Interval_Timer#Read_Back_Status_Byte :
Bits Usage
6 and 7 Select channel :
0 0 = Channel 0
0 1 = Channel 1
1 0 = Channel 2
1 1 = Read-back command (8254 only)
4 and 5 Access mode :
0 0 = Latch count value command
0 1 = Access mode: lobyte only
1 0 = Access mode: hibyte only
1 1 = Access mode: lobyte/hibyte
1 to 3 Operating mode :
0 0 0 = Mode 0 (interrupt on terminal count)
0 0 1 = Mode 1 (hardware re-triggerable one-shot)
0 1 0 = Mode 2 (rate generator)
0 1 1 = Mode 3 (square wave generator)
1 0 0 = Mode 4 (software triggered strobe)
1 0 1 = Mode 5 (hardware triggered strobe)
1 1 0 = Mode 2 (rate generator, same as 010b)
1 1 1 = Mode 3 (square wave generator, same as 011b)
0 BCD/Binary mode: 0 = 16-bit binary, 1 = four-digit BCD
*/
unsigned short command = 0b00110110;
outb(0x43, command);
outb(0x40, divisor & 0xFF); /* Set low byte of divisor */
outb(0x40, divisor >> 8); /* Set high byte of divisor */
}

+ 2
- 0
kernel/drivers/timer.h Parādīt failu

@@ -0,0 +1,2 @@
extern u32 ticks;
void timer_phase(int hz);

+ 47
- 374
kernel/kernel.c Parādīt failu

@@ -1,8 +1,8 @@
/*
* libcaca Canvas for ultrafast compositing of Unicode letters
/*
* libcaca
* libcaca Colour ASCII-Art library
* Copyright (c) 2006 Sam Hocevar <sam@hocevar.net>
* 2006 Jean-Yves Lamoureux <jylam@lnxscene.org>
* Copyright (c) 2006 Sam Hocevar <sam@zoy.org>
* 2006-2009 Jean-Yves Lamoureux <jylam@lnxscene.org>
* All Rights Reserved
*
* $Id$
@@ -14,388 +14,61 @@
* http://sam.zoy.org/wtfpl/COPYING for more details.
*/

/*
/*
* This file contains replacement functions for the standard C library
* that must be used when building libcaca and libcaca into a kernel.
*/

#include "config.h"

#include "caca_types.h"

#ifdef __KERNEL__

#define IS_DIGIT(x) (x>='0' && x<='9')
#define IS_ALPHA(x) (x>='A' && x<='z')
#define IS_UPPER(x) (x>='A' && x<='Z')
#define IS_LOWER(x) (x>='a' && x<='z')
#define UPPER(x) (IS_LOWER(x)?(x+('A'-'a')):x)
#define LOWER(x) (IS_UPPER(x)?(x-('a'-'A')):x)

/* Our default seed for random number generator */
static int seed = 0x68743284;

/* Our memory mapping */
static uint32_t *freemem = (uint32_t*) 0x00200000;

/* Multiboot kernel entry point */
void cmain(unsigned long int magic, unsigned long int addr)
{
static char const text[] = "Booting libcaca kernel...";
char const *ptr = text;
char *video = (char*)0xB8000;

char *argv[] = { NULL };
int argc = 0;

/* Print a text message to say hello */
while(*ptr)
*video = *ptr++; video += 2;

/* Launch the main program */
main(argc, argv);
}

/* stdlib.h functions */
void *malloc(size_t size)
{
uint32_t *p = freemem;
if(!size)
return NULL;
size = (size + 0x7) / 4;
*p = size;
freemem += size + 1;
return p + 1;
}

void free(void *ptr)
{
return;
}

void *realloc(void *ptr, size_t size)
{
uint32_t oldsize;
void *p;

if(!size)
return NULL;

if(!ptr)
oldsize = 0;
else
#include "klibc.h"
#include "boot/stage2.h"
#include "kernel.h"
#include "drivers/processor.h"
#include "drivers/floppy.h"
#include "drivers/timer.h"

extern char const * const * caca_get_display_driver_list(void);

/* C entry point, called from stage2 */
int kmain(void)
{
struct processor_info processor_info;
struct floppy_info floppy_info;
printf("_start at 0x%x\n", _start);
printf("kmain() at 0x%x\n", kmain);
processor_get_info(&processor_info);
processor_print_info(&processor_info);

floppy_get_info(&floppy_info);
floppy_print_info(&floppy_info);

enable_interrupt(1); // Enable Keyboard Interrupt (IRQ1)
enable_interrupt(0); // Enable IRQ0 (timer)
enable_interrupt(13);
timer_phase(100); // Fire IRQ0 each 1/100s
printf("Waiting 1s\n");
sleep(1);
printf("Waiting 2s\n");
sleep(2);
printf("Waiting 3s\n");
sleep(3);
printf("Ok\n");
//caca_get_display_driver_list();
while (1)
{
oldsize = ((uint32_t *)ptr)[-1];
if(oldsize >= size)
return ptr;
}

p = malloc(size);
memcpy(p, ptr, oldsize);
return p;
}

char *getenv(const char *name)
{
return NULL;
}

int getpid(void)
{
return 0x1337;
}

void srand(unsigned int s)
{
seed = rand();
}

int time(void *dummy)
{
return rand();
}

int rand(void)
{
seed = (seed * 0x7f32ba17) ^ 0xf893a735;
return seed % RAND_MAX;
}

int abs(int j)
{
if(j < 0)
return -j;
return j;
}

void exit(int status)
{
/* FIXME: reboot? */
while(1);
}

int atexit(void (*function)(void))
{
/* FIXME: register function */
return 0;
}

/* string.h functions */
void *memset(void *s, int c, size_t n)
{
uint8_t *ptr = s;

while(n--)
*ptr++ = c;

return s;
}

void *memcpy(void *dest, const void *src, size_t n)
{
uint8_t *destptr = dest;
uint8_t const *srcptr = src;

while(n--)
*destptr++ = *srcptr++;

return dest;
}

void *memmove(void *dest, const void *src, size_t n)
{
memcpy(freemem, src, n);
memcpy(dest, freemem, n);
return dest;
}

size_t strlen(const char *s)
{
int len = 0;

while(*s++)
len++;

return len;
}

int strcmp(const char *s1, const char *s2)
{
while(*s1 && *s1 == *s2)
{
s1++;
s2++;
}

return (int)*s1 - (int)*s2;
}

int strcasecmp(const char *s1, const char *s2)
{
while(*s1 && *s2 && UPPER(*s1) == UPPER(*s2))
{
s1++;
s2++;
}

return (int)UPPER(*s1) - (int)UPPER(*s2);
}

int memcmp(const void *_s1, const void *_s2, size_t n)
{
uint8_t const *s1 = _s1, *s2 = _s2;

while(n--)
{
if(*s1 != *s2)
return (int)*s1 - (int)*s2;
s1++;
s2++;
}
return 0;
}

char *strdup(const char *s)
{
char *new;
unsigned int len = strlen(s);

new = malloc(len + 1);
memcpy(new, s, len + 1);

return new;
}

char *strchr(const char *s, int c)
{
do
if(*s == c)
return (char *)(intptr_t)s;
while(*s++);

return NULL;
}

/* stdarg.h functions */
int vsnprintf(char *str, size_t size, const char *format, va_list ap)
{
/* FIXME */
return 0;
}

/* stdio.h functions */
FILE *fopen(const char *path, const char *mode)
{
/* FIXME */
return NULL;
}

int feof(FILE *stream)
{
/* FIXME */
return 0;
}

char *fgets(char *s, int size, FILE *stream)
{
/* FIXME */
return NULL;
}

size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)
{
return 0;
}

int fclose(FILE *fp)
{
/* FIXME */
return 0;
}

int printf(const char *format, ...)
{
/* FIXME */
return 0;
}

int fprintf(FILE *stream, const char *format, ...)
{
/* FIXME */
return 0;
}

int fflush(FILE *stream)
{
/* FIXME */
return 0;
}

int sprintf(char *str, const char *format, ...)
{
/* FIXME */
return 0;
}

int sscanf(const char *str, const char *format, ...)
{
/* FIXME */
return 0;
}

/* unistd.h functions */
void usleep(unsigned long usec)
{
/* FIXME */
return;
}

/* time.h functions */
int gettimeofday(struct timeval *tv, struct timezone *tz)
{
static int usec = 0;
static int sec = 0;

/* FIXME */
usec += 10000;
if(usec > 1000000)
{
sec++;
usec -= 1000000;
}

tv->tv_sec = sec;
tv->tv_usec = usec;

return 0;
}

/* math.h functions */
double cos(double x)
{
double ret = 0.0;
#ifdef HAVE_FSIN_FCOS
asm volatile("fcos" : "=t" (ret) : "0" (x));
#else
double x2;
double num = 1.0;
double fact = 1.0;
int i;

x = x - ((double)(int)(x / (2 * M_PI))) * (2 * M_PI);
x2 = x * x;

/* cos(x) = 1/0! - x^2/2! + x^4/4! - x^6/6! ... */
for(i = 0; i < 10; i++)
{
ret += num / fact;
num *= - x2;
fact *= (2 * i + 1) * (2 * i + 2);
}
#endif
return ret;
}

double sin(double x)
{
double ret = 0.0;
#ifdef HAVE_FSIN_FCOS
asm volatile("fsin" : "=t" (ret) : "0" (x));
#else
double x2;
double num;
double fact = 1.0;
int i;

x = x - ((double)(int)(x / (2 * M_PI))) * (2 * M_PI);
x2 = x * x;
num = x;

/* sin(x) = x/1! - x^3/3! + x^5/5! - x^7/7! ... */
for(i = 0; i < 10; i++)
{
ret += num / fact;
num *= - x2;
fact *= (2 * i + 2) * (2 * i + 3);
}
#endif
return ret;
}

double sqrt(double x)
{
double ret = x;
int i;

/* This is Newton's method */
for(i = 0; i < 10; i++)
ret = (ret * ret + x) / (ret * 2.0);

return ret;
}

/* errno.h stuff */

int errno = 0;

#endif /* __KERNEL__ */

+ 10
- 108
kernel/kernel.h Parādīt failu

@@ -1,7 +1,7 @@
/*
* libcaca Canvas for ultrafast compositing of Unicode letters
* libcaca Colour ASCII-Art library
* Copyright (c) 2006 Sam Hocevar <sam@hocevar.net>
* Copyright (c) 2006 Sam Hocevar <sam@zoy.org>
* All Rights Reserved
*
* $Id$
@@ -18,122 +18,24 @@
* that must be used when building libcaca and libcaca into a kernel.
*/

/* Various defines */
#define NULL ((void *)0)
#define EOF (-1)
#define BUFSIZ 4096
#define RAND_MAX ((unsigned int)0x8000000)
#define INT_MAX ((int)0x7fffffff)
#define M_PI 3.14159265358979323846
#define __BYTE_ORDER 1
#define __BIG_ENDIAN 2

/* Assembly code for outb and inb */
extern inline void outb(unsigned char val, unsigned short port);
extern inline unsigned char inb(unsigned short port);

extern inline void outb(unsigned char val, unsigned short port)
{
__asm__ __volatile__ ("outb %b0,%w1" : : "a" (val), "Nd" (port));
}

extern inline unsigned char inb(unsigned short port)
{
unsigned char tmp;
__asm__ __volatile__ ("inb %w1,%0" : "=a" (tmp) : "Nd" (port));
return tmp;
}
extern void init_gdt(void);
void init_pic(void);
void init_idt(void);
void putcar(unsigned char c);
void dump_gdt(void);

/* Various typedefs -- some are x86-specific */
#define CUSTOM_INTTYPES
typedef unsigned int size_t;
void disable_interrupt(char i);
void enable_interrupt(char i);

typedef struct file
{
void *mem;
} FILE;

struct timeval {
int tv_sec;
int tv_usec;
};
#define cli __asm__("cli"::)
#define sti __asm__("sti"::)

struct timezone {
int tz_minuteswest;
int tz_dsttime;
};

/* Multiboot kernel entry point */
void cmain(unsigned long int magic, unsigned long int addr);

/* The application's entry point */
int main(int argc, char *argv[]);

/* stdlib.h functions */
void *malloc(size_t size);
void free(void *ptr);
void *realloc(void *ptr, size_t size);
char *getenv(const char *name);
int rand(void);
int abs(int j);
void exit(int status);
void srand(unsigned int s);
int atexit(void (*function)(void));
FILE *stdin, *stdout, *stderr;

/* string.h functions */
void *memset(void *s, int c, size_t n);
void *memcpy(void *dest, const void *src, size_t n);
void *memmove(void *dest, const void *src, size_t n);
size_t strlen(const char *s);
int strcmp(const char *s1, const char *s2);
int strcasecmp(const char *s1, const char *s2);
int memcmp(const void *s1, const void *s2, size_t n);
char *strdup(const char *s);
char *strchr(const char *s, int c);

/* stdarg.h functions */
typedef void * va_list;
#define va_start(v,a) v = (void *)((uintptr_t)(&a) + sizeof(a))
#define va_end(v)
int vsnprintf(char *str, size_t size, const char *format, va_list ap);

/* stdio.h functions */
FILE *fopen(const char *path, const char *mode);
int feof(FILE *stream);
char *fgets(char *s, int size, FILE *stream);
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
int fclose(FILE *fp);
int printf(const char *format, ...);
int fprintf(FILE *stream, const char *format, ...);
int fflush(FILE *stream);
int sprintf(char *str, const char *format, ...);
int sscanf(const char *str, const char *format, ...);

/* unistd.h functions */
void usleep(unsigned long usec);
int getpid(void);

/* time.h functions */
int gettimeofday(struct timeval *tv, struct timezone *tz);
int time(void *);

/* math.h functions */
double cos(double x);
double sin(double x);
double sqrt(double x);

/* errno.h functions */
#define ENOENT 2 /* No such file or directory */
#define ENOMEM 12 /* Out of memory */
#define EBUSY 16 /* Device or resource busy */
#define ENODEV 19 /* No such device */
#define EINVAL 22 /* Invalid argument */
#define ENOTTY 25 /* Not a typewriter */
#define ENOSYS 38 /* Function not implemented */
extern int errno;

/* arpa/inet.h functions */
unsigned int htonl(unsigned int hostlong);
unsigned short htons(unsigned short hostlong);


+ 598
- 0
kernel/klibc.c Parādīt failu

@@ -0,0 +1,598 @@
#include "config.h"
#include "caca_types.h"

#include "klibc.h"
#include "drivers/timer.h"
#include "kernel.h"


void htoa(unsigned int value, char s[]);

#define IS_DIGIT(x) (x>='0' && x<='9')
#define IS_ALPHA(x) (x>='A' && x<='z')
#define IS_UPPER(x) (x>='A' && x<='Z')
#define IS_LOWER(x) (x>='a' && x<='z')
#define UPPER(x) (IS_LOWER(x)?(x+('A'-'a')):x)
#define LOWER(x) (IS_UPPER(x)?(x-('a'-'A')):x)

/* Our default seed for random number generator */
static int seed = 0x68743284;

/* Our memory mapping */
static uint32_t *freemem = (uint32_t*) 0x00200000;
int kX = 0;
int kY = 0;

void scroll(void)
{
unsigned char* video, *tmp;
for(video=(unsigned char*)0xB8000 ; video<(unsigned char*)0xB8FA0 ; video++){
tmp = (unsigned char*) (video+1*160);
if(tmp<(unsigned char*)0xB8FA0)
*video = *tmp;
else
*video = 0;
}
kY-=1;
if(kY<0)
kY=0;}

void putcar(unsigned char c)
{
unsigned char* video;
if(c==10){
kX=0;
kY++;
}
else{
video = (unsigned char*) (0xB8000+2*kX+160*kY);
*video = c;
*(video+1) = 0x07;
kX++;
if(kX>79){
kX = 0;
kY++;
}
if(kY >= 24) {
scroll();
}
}
}

void print(char *str)
{
char const *ptr = str;
while(*ptr) {
putcar(*ptr++);
}
}

void clearscreen(void)
{
int x, y;
kX = 0;
kY = 0;
for(y = 0; y < 25; y++)
for(x = 0; x < 80; x++) {
putcar(' ');
}
kX = 0;
kY = 0;
}

/* stdlib.h functions */
void *malloc(size_t size)
{
uint32_t *p = freemem;
if(!size)
return NULL;
size = (size + 0x7) / 4;
*p = size;
freemem += size + 1;
return p + 1;
}

void free(void *ptr)
{
return;
}

void *realloc(void *ptr, size_t size)
{
uint32_t oldsize;
void *p;
if(!size)
return NULL;
if(!ptr)
oldsize = 0;
else
{
oldsize = ((uint32_t *)ptr)[-1];
if(oldsize >= size)
return ptr;
}
p = malloc(size);
memcpy(p, ptr, oldsize);
return p;
}

char *getenv(const char *name)
{
return NULL;
}

int getpid(void)
{
return 0x1337;
}

void srand(unsigned int s)
{
seed = rand();
}

int time(void *dummy)
{
return rand();
}

int rand(void)
{
seed = (seed * 0x7f32ba17) ^ 0xf893a735;
return seed % RAND_MAX;
}

int abs(int j)
{
if(j < 0)
return -j;
return j;
}

void exit(int status)
{
/* FIXME: reboot? */
while(1);
}

int atexit(void (*function)(void))
{
/* FIXME: register function */
return 0;
}

/* string.h functions */
void *memset(void *s, int c, size_t n)
{
uint8_t *ptr = s;
while(n--)
*ptr++ = c;
return s;
}

void *memcpy(void *dest, const void *src, size_t n)
{
uint8_t *destptr = dest;
uint8_t const *srcptr = src;
while(n--)
*destptr++ = *srcptr++;
return dest;
}

void *memmove(void *dest, const void *src, size_t n)
{
memcpy(freemem, src, n);
memcpy(dest, freemem, n);
return dest;
}

size_t strlen(const char *s)
{
int len = 0;
while(*s++)
len++;
return len;
}

int strcmp(const char *s1, const char *s2)
{
while(*s1 && *s1 == *s2)
{
s1++;
s2++;
}
return (int)*s1 - (int)*s2;
}

int strcasecmp(const char *s1, const char *s2)
{
while(*s1 && *s2 && UPPER(*s1) == UPPER(*s2))
{
s1++;
s2++;
}
return (int)UPPER(*s1) - (int)UPPER(*s2);
}

int memcmp(const void *_s1, const void *_s2, size_t n)
{
uint8_t const *s1 = _s1, *s2 = _s2;
while(n--)
{
if(*s1 != *s2)
return (int)*s1 - (int)*s2;
s1++;
s2++;
}
return 0;
}

char *strdup(const char *s)
{
char *new;
unsigned int len = strlen(s);
new = malloc(len + 1);
memcpy(new, s, len + 1);
return new;
}

char *strchr(const char *s, int c)
{
do
if(*s == c)
return (char *)(intptr_t)s;
while(*s++);
return NULL;
}

/* stdarg.h functions */
int vsnprintf(char *str, size_t size, const char *format, va_list ap)
{
/* FIXME */
return 0;
}

/* stdio.h functions */
FILE *fopen(const char *path, const char *mode)
{
/* FIXME */
return NULL;
}

int feof(FILE *stream)
{
/* FIXME */
return 0;
}

char *fgets(char *s, int size, FILE *stream)
{
/* FIXME */
return NULL;
}

size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)
{
return 0;
}

int fclose(FILE *fp)
{
/* FIXME */
return 0;
}

int printf(const char *fmt, ...)
{
char str[200];
char tmp[100];
args_list args;
args_start(args, fmt);
char *s;
int ptr = 0;
int i = 0;
for (; fmt[i]; ++i) {
if ((fmt[i]!='%') && (fmt[i]!='\\')) {
str[ptr++] = fmt[i];
continue;
} else if (fmt[i] == '\\') {
switch (fmt[++i]) {
case 'a': str[ptr++] = '\a'; break;
case 'b': str[ptr++] = '\b'; break;
case 't': str[ptr++] = '\t'; break;
case 'n': str[ptr++] = '\n'; break;
case 'r': str[ptr++] = '\r'; break;
case '\\':str[ptr++] = '\\'; break;
}
continue;
}
switch (fmt[++i]) {
case 's':
s = (char *)args_next(args, char *);
while (*s)
str[ptr++] = *s++;
break;
case 'c':
str[ptr++] = (char)args_next(args, int);
break;
case 'p':
case 'x':
htoa((unsigned long)args_next(args, unsigned long), tmp);
memcpy(&str[ptr], tmp, strlen(tmp));
ptr+=strlen(tmp);
break;
case 'd':
itoa((unsigned long)args_next(args, unsigned long), tmp);
memcpy(&str[ptr], tmp, strlen(tmp));
ptr+=strlen(tmp);
break;
case '%':
str[ptr++] = '%';
break;
default:
str[ptr++] = fmt[i];
break;
}
}
str[ptr] = '\0';
args_end(args);
print(str);
return 0;
}

int fprintf(FILE *stream, const char *format, ...)
{
/* FIXME */
return 0;
}

int fflush(FILE *stream)
{
/* FIXME */
return 0;
}

int sprintf(char *str, const char *fmt, ...)
{
char tmp[100];
args_list args;
args_start(args, fmt);
char *s;
int ptr = 0;
int i = 0;
for (; fmt[i]; ++i) {
if ((fmt[i]!='%') && (fmt[i]!='\\')) {
str[ptr++] = fmt[i];
continue;
} else if (fmt[i] == '\\') {
switch (fmt[++i]) {
case 'a': str[ptr++] = '\a'; break;
case 'b': str[ptr++] = '\b'; break;
case 't': str[ptr++] = '\t'; break;
case 'n': str[ptr++] = '\n'; break;
case 'r': str[ptr++] = '\r'; break;
case '\\':str[ptr++] = '\\'; break;
}
continue;
}
switch (fmt[++i]) {
case 's':
s = (char *)args_next(args, char *);
while (*s)
str[ptr++] = *s++;
break;
case 'c':
str[ptr++] = (char)args_next(args, int);
break;
case 'p':
case 'x':
htoa((unsigned long)args_next(args, unsigned long), tmp);
memcpy(&str[ptr], tmp, strlen(tmp));
ptr+=strlen(tmp);
break;
case 'd':
itoa((unsigned long)args_next(args, unsigned long), tmp);
memcpy(&str[ptr], tmp, strlen(tmp));
ptr+=strlen(tmp);
break;
case '%':
str[ptr++] = '%';
break;
default:
str[ptr++] = fmt[i];
break;
}
}

str[ptr] = '\0';
args_end(args);

return 0;
}

int sscanf(const char *str, const char *format, ...)
{
/* FIXME */
return 0;
}

/* unistd.h functions */
void usleep(unsigned long usec)
{
u32 start = ticks;
signed int diff = 0;
while(1) {
diff = (signed int)(ticks - start);
if(diff >= (signed int)(usec/20)) break;
}
}

void sleep(unsigned long sec)
{
usleep(sec*1000);
}

/* time.h functions */
u64 rdtsc() {
u64 x;
__asm__ volatile ("rdtsc" : "=A" (x));
return x;
}

int gettimeofday(struct timeval *tv, struct timezone *tz)
{
static int usec = 0;
static int sec = 0;
/* FIXME */
usec += 10000;
if(usec > 1000000)
{
sec++;
usec -= 1000000;
}
tv->tv_sec = sec;
tv->tv_usec = usec;
return 0;
}

/* math.h functions */
double cos(double x)
{
double ret = 0.0;
#ifdef HAVE_FSIN_FCOS
asm volatile("fcos" : "=t" (ret) : "0" (x));
#else
double x2;
double num = 1.0;
double fact = 1.0;
int i;
x = x - ((double)(int)(x / (2 * M_PI))) * (2 * M_PI);
x2 = x * x;
/* cos(x) = 1/0! - x^2/2! + x^4/4! - x^6/6! ... */
for(i = 0; i < 10; i++)
{
ret += num / fact;
num *= - x2;
fact *= (2 * i + 1) * (2 * i + 2);
}
#endif
return ret;
}

double sin(double x)
{
double ret = 0.0;
#ifdef HAVE_FSIN_FCOS
asm volatile("fsin" : "=t" (ret) : "0" (x));
#else
double x2;
double num;
double fact = 1.0;
int i;
x = x - ((double)(int)(x / (2 * M_PI))) * (2 * M_PI);
x2 = x * x;
num = x;
/* sin(x) = x/1! - x^3/3! + x^5/5! - x^7/7! ... */
for(i = 0; i < 10; i++)
{
ret += num / fact;
num *= - x2;
fact *= (2 * i + 2) * (2 * i + 3);
}
#endif
return ret;
}

double sqrt(double x)
{
double ret = x;
int i;
/* This is Newton's method */
for(i = 0; i < 10; i++)
ret = (ret * ret + x) / (ret * 2.0);
return ret;
}


/* reverse: reverse string s in place */
void reverse(char s[])
{
int i, j;
char c;
for (i = 0, j = strlen(s)-1; i<j; i++, j--) {
c = s[i];
s[i] = s[j];
s[j] = c;
}
}


/* itoa implementation, by Kernighan and Ritchie's The C Programming Language */
void itoa(int n, char s[])
{
int i, sign;
if ((sign = n) < 0) /* record sign */
n = -n; /* make n positive */
i = 0;
do { /* generate digits in reverse order */
s[i++] = n % 10 + '0'; /* get next digit */
} while ((n /= 10) > 0); /* delete it */
if (sign < 0)
s[i++] = '-';
s[i] = '\0';
reverse(s);
}

void htoa(unsigned int value, char s[]) {
int i = 8;
int ptr = 0;
while (i-- > 0) {
s[ptr++] = "0123456789abcdef"[(value>>(i*4))&0xf];
}
s[ptr] = 0;
}


/* errno.h stuff */
int errno = 0;

+ 125
- 0
kernel/klibc.h Parādīt failu

@@ -0,0 +1,125 @@
/* Various typedefs -- some are x86-specific */
#define CUSTOM_INTTYPES

#define outb(port,value) __asm__ __volatile__ ("outb %%al,%%dx"::"d" (port), "a" (value));
#define outbp(port,value) __asm __volatile__ ("outb %%al,%%dx; jmp 1f; 1:"::"d" (port), "a" (value));
#define inb(port) ({unsigned char _v; __asm__ __volatile__ ("inb %%dx,%%al" : "=a" (_v) : "d" (port)); _v; })


/* Various defines */
#define NULL ((void *)0)
#define EOF (-1)
#define BUFSIZ 4096
#define RAND_MAX ((unsigned int)0x8000000)
#define INT_MAX ((int)0x7fffffff)
#define M_PI 3.14159265358979323846
#define __BYTE_ORDER 1
#define __BIG_ENDIAN 2

typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
typedef unsigned long int u64;

#ifndef size_t
typedef unsigned int size_t;
#endif
typedef struct file
{
void *mem;
} FILE;

struct timeval {
int tv_sec;
int tv_usec;
};

struct timezone {
int tz_minuteswest;
int tz_dsttime;
};

/* stdlib.h functions */
void *malloc(size_t size);
void free(void *ptr);
void *realloc(void *ptr, size_t size);
char *getenv(const char *name);
int rand(void);
int abs(int j);
void exit(int status);
void srand(unsigned int s);
int atexit(void (*function)(void));
FILE *stdin, *stdout, *stderr;

/* string.h functions */
void *memset(void *s, int c, size_t n);
void *memcpy(void *dest, const void *src, size_t n);
void *memmove(void *dest, const void *src, size_t n);
size_t strlen(const char *s);
int strcmp(const char *s1, const char *s2);
int strcasecmp(const char *s1, const char *s2);
int memcmp(const void *s1, const void *s2, size_t n);
char *strdup(const char *s);
char *strchr(const char *s, int c);

/* stdarg.h functions */
typedef void * va_list;
#define va_start(v,a) v = (void *)((uintptr_t)(&a) + sizeof(a))
#define va_end(v)
int vsnprintf(char *str, size_t size, const char *format, va_list ap);
/* va_arg*/
#define args_list char *
#define _arg_stack_size(type) (((sizeof(type)-1)/sizeof(int)+1)*sizeof(int))
#define args_start(ap, fmt) do { \
ap = (char *)((unsigned int)&fmt + _arg_stack_size(&fmt)); \
} while (0)
#define args_end(ap)
#define args_next(ap, type) (((type *)(ap+=_arg_stack_size(type)))[-1])

/* stdio.h functions */
FILE *fopen(const char *path, const char *mode);
int feof(FILE *stream);
char *fgets(char *s, int size, FILE *stream);
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
int fclose(FILE *fp);

int printf(const char *format, ...);

int fprintf(FILE *stream, const char *format, ...);
int fflush(FILE *stream);
int sprintf(char *str, const char *format, ...);
int sscanf(const char *str, const char *format, ...);
void itoa(int n, char s[]);

void clearscreen(void);

/* unistd.h functions */
void usleep(unsigned long usec);
void sleep(unsigned long sec);
int getpid(void);

/* time.h functions */
u64 rdtsc(void);
int gettimeofday(struct timeval *tv, struct timezone *tz);
int time(void *);

/* math.h functions */
double cos(double x);
double sin(double x);
double sqrt(double x);

/* errno.h functions */
#define ENOENT 2 /* No such file or directory */
#define ENOMEM 12 /* Out of memory */
#define EBUSY 16 /* Device or resource busy */
#define ENODEV 19 /* No such device */
#define EINVAL 22 /* Invalid argument */
#define ENOTTY 25 /* Not a typewriter */
#define ENOSYS 38 /* Function not implemented */
extern int errno;

/* arpa/inet.h functions */
unsigned int htonl(unsigned int hostlong);
unsigned short htons(unsigned short hostlong);

void print(char *str);

+ 0
- 73
kernel/multiboot.S Parādīt failu

@@ -1,73 +0,0 @@
/* boot.S - bootstrap the kernel */
/* Copyright (C) 1999 Free Software Foundation, Inc.

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */

#define ASM 1
#include <multiboot.h>
.text

.code32
.globl start, _start

/* This entry is not used actually. */
start:
_start:
jmp multiboot_entry

/* Align 32 bits boundary. */
.align 4
/* Multiboot header. */
multiboot_header:
/* magic */
.long MULTIBOOT_HEADER_MAGIC
/* flags */
.long MULTIBOOT_HEADER_FLAGS
/* checksum */
.long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)
/* header_addr */
.long multiboot_header
/* load_addr */
.long _start
/* load_end_addr */
.long _edata
/* bss_end_addr */
.long _end
/* entry_addr */
.long multiboot_entry

multiboot_entry:
/* Initialize the stack pointer. */
movl $(stack + STACK_SIZE), %esp

/* Reset EFLAGS. */
pushl $0
popf

/* Push the pointer to the Multiboot information structure. */
pushl %ebx
/* Push the magic value. */
pushl %eax

/* Now enter the C main function... */
call EXT_C(cmain)

loop: hlt
jmp loop

/* Our stack area. */
.comm stack, STACK_SIZE

Notiek ielāde…
Atcelt
Saglabāt