Index: src/platform/linux/platform_conf.h
===================================================================
--- src/platform/linux/platform_conf.h	(revision 0)
+++ src/platform/linux/platform_conf.h	(revision 0)
@@ -0,0 +1,66 @@
+// eLua platform configuration
+
+#ifndef __PLATFORM_CONF_H__
+#define __PLATFORM_CONF_H__
+
+#include "auxmods.h"
+#include "type.h"
+#include "stacks.h"
+
+// *****************************************************************************
+// Define here what components you want for this platform
+
+#define BUILD_SHELL
+#define BUILD_ROMFS
+#define BUILD_CON_GENERIC
+#define BUILD_TERM
+
+#define TERM_LINES    25
+#define TERM_COLS     80
+
+// *****************************************************************************
+// Auxiliary libraries that will be compiled for this platform
+
+#define LUA_PLATFORM_LIBS_ROM\
+  _ROM( AUXLIB_PD, luaopen_pd, pd_map )\
+  _ROM( LUA_MATHLIBNAME, luaopen_math, math_map )\
+  _ROM( AUXLIB_TERM, luaopen_term, term_map )
+
+// Bogus defines for common.c
+#define CON_UART_ID           0
+#define CON_TIMER_ID          0
+
+// *****************************************************************************
+// Configuration data
+
+// Virtual timers (0 if not used)
+#define VTMR_NUM_TIMERS       0
+
+// Number of resources (0 if not available/not implemented)
+#define NUM_PIO               0
+#define NUM_SPI               0
+#define NUM_UART              0
+#define NUM_TIMER             0
+#define NUM_PWM               0
+#define NUM_ADC               0
+
+// CPU frequency (needed by the CPU module, 0 if not used)
+#define CPU_FREQUENCY         0
+
+// PIO prefix ('0' for P0, P1, ... or 'A' for PA, PB, ...)
+#define PIO_PREFIX            'A'
+// Pins per port configuration:
+// #define PIO_PINS_PER_PORT (n) if each port has the same number of pins, or
+// #define PIO_PIN_ARRAY { n1, n2, ... } to define pins per port in an array
+// Use #define PIO_PINS_PER_PORT 0 if this isn't needed
+#define PIO_PINS_PER_PORT     0
+
+// Allocator data: define your free memory zones here in two arrays
+// (start address and end address)
+extern void *memory_start_address;
+extern void *memory_end_address;
+#define MEM_LENGTH (64 * 1024)
+#define MEM_START_ADDRESS     { ( void* )memory_start_address }
+#define MEM_END_ADDRESS       { ( void* )memory_end_address }
+
+#endif // #ifndef __PLATFORM_CONF_H__

Property changes on: src/platform/linux/platform_conf.h
___________________________________________________________________
Added: svn:eol-style
   + native

Index: src/platform/linux/kb.h
===================================================================
--- src/platform/linux/kb.h	(revision 0)
+++ src/platform/linux/kb.h	(revision 0)
@@ -0,0 +1,9 @@
+// Keyboard handler
+
+#ifndef __KB_H__
+#define __KB_H__
+
+void keyboard_install();
+int keyboard_getch();
+
+#endif

Property changes on: src/platform/linux/kb.h
___________________________________________________________________
Added: svn:eol-style
   + native

Index: src/platform/linux/isr.h
===================================================================
--- src/platform/linux/isr.h	(revision 0)
+++ src/platform/linux/isr.h	(revision 0)
@@ -0,0 +1,39 @@
+//
+// isr.h -- Interface and structures for high level interrupt service routines.
+//          Part of this code is modified from Bran's kernel development tutorials.
+//          Rewritten for JamesM's kernel development tutorials.
+//
+
+#include "common.h"
+
+// A few defines to make life a little easier
+#define IRQ0 32
+#define IRQ1 33
+#define IRQ2 34
+#define IRQ3 35
+#define IRQ4 36
+#define IRQ5 37
+#define IRQ6 38
+#define IRQ7 39
+#define IRQ8 40
+#define IRQ9 41
+#define IRQ10 42
+#define IRQ11 43
+#define IRQ12 44
+#define IRQ13 45
+#define IRQ14 46
+#define IRQ15 47
+
+typedef struct registers
+{
+    u32int ds;                  // Data segment selector
+    u32int edi, esi, ebp, esp, ebx, edx, ecx, eax; // Pushed by pusha.
+    u32int int_no, err_code;    // Interrupt number and error code (if applicable)
+    u32int eip, cs, eflags, useresp, ss; // Pushed by the processor automatically.
+} registers_t;
+
+// Enables registration of callbacks for interrupts or IRQs.
+// For IRQs, to ease confusion, use the #defines above as the
+// first parameter.
+typedef void (*isr_t)(registers_t);
+void register_interrupt_handler(u8int n, isr_t handler);

Property changes on: src/platform/linux/isr.h
___________________________________________________________________
Added: svn:eol-style
   + native

Index: src/platform/linux/i386.ld
===================================================================
--- src/platform/linux/i386.ld	(revision 0)
+++ src/platform/linux/i386.ld	(revision 0)
@@ -0,0 +1,40 @@
+/* Link.ld -- Linker script for the kernel - ensure everything goes in the */
+/*            Correct place.  */
+/*            Original file taken from Bran's Kernel Development */
+/*            tutorials: http://www.osdever.net/bkerndev/index.php. */
+
+SECTIONS
+{
+
+    .text 0x100000 :
+    {
+	KEEP(*(.header))
+        code = .; _code = .; __code = .;
+        PROVIDE(stext = .);
+        *(.text .text.*)
+        *(.rodata .rodata.*)        
+        *(.gnu.linkonce.r.*)    
+        *(.gnu.linkonce.t.*)                    
+        . = ALIGN(4096);
+        PROVIDE(etext = .);
+    }
+
+    .data :
+    {
+        data = .; _data = .; __data = .;
+        *(.data .data.*)
+        *(.gnu.linkonce.d.*)        
+        . = ALIGN(4096);
+    }
+
+    .bss :
+    {
+        bss = .; _bss = .; __bss = .;
+        *(.bss .bss.*)
+        *(.gnu.linkonce.b.*)        
+        *(COMMON)        
+        . = ALIGN(4096);
+    }
+
+    end = .; _end = .; __end = .;
+}
Index: src/platform/linux/descriptor_tables.c
===================================================================
--- src/platform/linux/descriptor_tables.c	(revision 0)
+++ src/platform/linux/descriptor_tables.c	(revision 0)
@@ -0,0 +1,158 @@
+//
+// descriptor_tables.c - Initialises the GDT and IDT, and defines the 
+//                       default ISR and IRQ handler.
+//                       Based on code from Bran's kernel development tutorials.
+//                       Rewritten for JamesM's kernel development tutorials.
+//
+
+#include "common.h"
+#include "descriptor_tables.h"
+#include "isr.h"
+#include <string.h>
+
+#if 0
+// Lets us access our ASM functions from our C code.
+extern void gdt_flush(u32int);
+extern void idt_flush(u32int);
+
+// Internal function prototypes.
+static void init_gdt();
+static void init_idt();
+static void gdt_set_gate(s32int,u32int,u32int,u8int,u8int);
+static void idt_set_gate(u8int,u32int,u16int,u8int);
+
+gdt_entry_t gdt_entries[5];
+gdt_ptr_t   gdt_ptr;
+idt_entry_t idt_entries[256];
+idt_ptr_t   idt_ptr;
+
+// Extern the ISR handler array so we can nullify them on startup.
+extern isr_t interrupt_handlers[];
+#endif
+
+// Initialisation routine - zeroes all the interrupt service routines,
+// initialises the GDT and IDT.
+void init_descriptor_tables()
+{
+#if 0
+    // Initialise the global descriptor table.
+    init_gdt();
+    // Initialise the interrupt descriptor table.
+    init_idt();
+    // Nullify all the interrupt handlers.
+    memset(&interrupt_handlers, 0, sizeof(isr_t)*256);
+#endif
+}
+
+#if 0
+static void init_gdt()
+{
+    gdt_ptr.limit = (sizeof(gdt_entry_t) * 5) - 1;
+    gdt_ptr.base  = (u32int)&gdt_entries;
+
+    gdt_set_gate(0, 0, 0, 0, 0);                // Null segment
+    gdt_set_gate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF); // Code segment
+    gdt_set_gate(2, 0, 0xFFFFFFFF, 0x92, 0xCF); // Data segment
+    gdt_set_gate(3, 0, 0xFFFFFFFF, 0xFA, 0xCF); // User mode code segment
+    gdt_set_gate(4, 0, 0xFFFFFFFF, 0xF2, 0xCF); // User mode data segment
+
+    gdt_flush((u32int)&gdt_ptr);
+}
+
+// Set the value of one GDT entry.
+static void gdt_set_gate(s32int num, u32int base, u32int limit, u8int access, u8int gran)
+{
+    gdt_entries[num].base_low    = (base & 0xFFFF);
+    gdt_entries[num].base_middle = (base >> 16) & 0xFF;
+    gdt_entries[num].base_high   = (base >> 24) & 0xFF;
+
+    gdt_entries[num].limit_low   = (limit & 0xFFFF);
+    gdt_entries[num].granularity = (limit >> 16) & 0x0F;
+    
+    gdt_entries[num].granularity |= gran & 0xF0;
+    gdt_entries[num].access      = access;
+}
+
+static void init_idt()
+{
+    idt_ptr.limit = sizeof(idt_entry_t) * 256 -1;
+    idt_ptr.base  = (u32int)&idt_entries;
+
+    memset(&idt_entries, 0, sizeof(idt_entry_t)*256);
+
+    // Remap the irq table.
+    outb(0x20, 0x11);
+    outb(0xA0, 0x11);
+    outb(0x21, 0x20);
+    outb(0xA1, 0x28);
+    outb(0x21, 0x04);
+    outb(0xA1, 0x02);
+    outb(0x21, 0x01);
+    outb(0xA1, 0x01);
+    outb(0x21, 0x0);
+    outb(0xA1, 0x0);
+
+    idt_set_gate( 0, (u32int)isr0 , 0x08, 0x8E);
+    idt_set_gate( 1, (u32int)isr1 , 0x08, 0x8E);
+    idt_set_gate( 2, (u32int)isr2 , 0x08, 0x8E);
+    idt_set_gate( 3, (u32int)isr3 , 0x08, 0x8E);
+    idt_set_gate( 4, (u32int)isr4 , 0x08, 0x8E);
+    idt_set_gate( 5, (u32int)isr5 , 0x08, 0x8E);
+    idt_set_gate( 6, (u32int)isr6 , 0x08, 0x8E);
+    idt_set_gate( 7, (u32int)isr7 , 0x08, 0x8E);
+    idt_set_gate( 8, (u32int)isr8 , 0x08, 0x8E);
+    idt_set_gate( 9, (u32int)isr9 , 0x08, 0x8E);
+    idt_set_gate(10, (u32int)isr10, 0x08, 0x8E);
+    idt_set_gate(11, (u32int)isr11, 0x08, 0x8E);
+    idt_set_gate(12, (u32int)isr12, 0x08, 0x8E);
+    idt_set_gate(13, (u32int)isr13, 0x08, 0x8E);
+    idt_set_gate(14, (u32int)isr14, 0x08, 0x8E);
+    idt_set_gate(15, (u32int)isr15, 0x08, 0x8E);
+    idt_set_gate(16, (u32int)isr16, 0x08, 0x8E);
+    idt_set_gate(17, (u32int)isr17, 0x08, 0x8E);
+    idt_set_gate(18, (u32int)isr18, 0x08, 0x8E);
+    idt_set_gate(19, (u32int)isr19, 0x08, 0x8E);
+    idt_set_gate(20, (u32int)isr20, 0x08, 0x8E);
+    idt_set_gate(21, (u32int)isr21, 0x08, 0x8E);
+    idt_set_gate(22, (u32int)isr22, 0x08, 0x8E);
+    idt_set_gate(23, (u32int)isr23, 0x08, 0x8E);
+    idt_set_gate(24, (u32int)isr24, 0x08, 0x8E);
+    idt_set_gate(25, (u32int)isr25, 0x08, 0x8E);
+    idt_set_gate(26, (u32int)isr26, 0x08, 0x8E);
+    idt_set_gate(27, (u32int)isr27, 0x08, 0x8E);
+    idt_set_gate(28, (u32int)isr28, 0x08, 0x8E);
+    idt_set_gate(29, (u32int)isr29, 0x08, 0x8E);
+    idt_set_gate(30, (u32int)isr30, 0x08, 0x8E);
+    idt_set_gate(31, (u32int)isr31, 0x08, 0x8E);
+    idt_set_gate(32, (u32int)irq0, 0x08, 0x8E);
+    idt_set_gate(33, (u32int)irq1, 0x08, 0x8E);
+    idt_set_gate(34, (u32int)irq2, 0x08, 0x8E);
+    idt_set_gate(35, (u32int)irq3, 0x08, 0x8E);
+    idt_set_gate(36, (u32int)irq4, 0x08, 0x8E);
+    idt_set_gate(37, (u32int)irq5, 0x08, 0x8E);
+    idt_set_gate(38, (u32int)irq6, 0x08, 0x8E);
+    idt_set_gate(39, (u32int)irq7, 0x08, 0x8E);
+    idt_set_gate(40, (u32int)irq8, 0x08, 0x8E);
+    idt_set_gate(41, (u32int)irq9, 0x08, 0x8E);
+    idt_set_gate(42, (u32int)irq10, 0x08, 0x8E);
+    idt_set_gate(43, (u32int)irq11, 0x08, 0x8E);
+    idt_set_gate(44, (u32int)irq12, 0x08, 0x8E);
+    idt_set_gate(45, (u32int)irq13, 0x08, 0x8E);
+    idt_set_gate(46, (u32int)irq14, 0x08, 0x8E);
+    idt_set_gate(47, (u32int)irq15, 0x08, 0x8E);
+
+    idt_flush((u32int)&idt_ptr);
+}
+
+static void idt_set_gate(u8int num, u32int base, u16int sel, u8int flags)
+{
+    idt_entries[num].base_lo = base & 0xFFFF;
+    idt_entries[num].base_hi = (base >> 16) & 0xFFFF;
+
+    idt_entries[num].sel     = sel;
+    idt_entries[num].always0 = 0;
+    // We must uncomment the OR below when we get to using user-mode.
+    // It sets the interrupt gate's privilege level to 3.
+    idt_entries[num].flags   = flags /* | 0x60 */;
+}
+#endif

Property changes on: src/platform/linux/descriptor_tables.c
___________________________________________________________________
Added: svn:eol-style
   + native

Index: src/platform/linux/host.c
===================================================================
--- src/platform/linux/host.c	(revision 0)
+++ src/platform/linux/host.c	(revision 0)
@@ -0,0 +1,77 @@
+#include "host.h"
+
+#define __NR_read     3
+#define __NR_write      4
+#define __NR_mmap2    192
+
+int host_errno = 0;
+
+#define __syscall_return(type, res) do { \
+	if((unsigned long)(res) >= (unsigned long)(-125)) { \
+		host_errno = -(res); \
+		res = -1; \
+	} \
+	return (type) (res); \
+} while(0)
+
+#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
+type host_##name(type1 arg1,type2 arg2,type3 arg3) \
+{ \
+long __res; \
+__asm__ volatile ("int $0x80" \
+        : "=a" (__res) \
+        : "0" (__NR_##name),"b" ((long)(arg1)),"c" ((long)(arg2)), \
+                  "d" ((long)(arg3))); \
+__syscall_return(type,__res); \
+}
+
+#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
+          type5,arg5,type6,arg6) \
+type host_##name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,type6 arg6) \
+{ \
+long __res; \
+__asm__ volatile ("push %%ebp ; movl %%eax,%%ebp ; movl %1,%%eax ; int $0x80 ; pop %%ebp" \
+        : "=a" (__res) \
+        : "i" (__NR_##name),"b" ((long)(arg1)),"c" ((long)(arg2)), \
+          "d" ((long)(arg3)),"S" ((long)(arg4)),"D" ((long)(arg5)), \
+          "0" ((long)(arg6))); \
+	__syscall_return(type, __res); \
+}
+
+_syscall3(ssize_t, read, int, fd, void *, buf, size_t, count);
+_syscall3(ssize_t, write, int, fd, const void *, buf, size_t, count);
+_syscall6(void *,mmap2, void *,addr, size_t, length, int, prot, int, flags, int, fd, off_t, offset);
+
+#if 0
+void *host_mmap2(void *addr, size_t length, int prot, int flags, int fd, off_t pgoffset) {
+	long res;
+	__asm__ __volatile__ (
+		"  push %%ebp\n"
+		"  movl %%eax, %%ebp\n"
+		"  movl %1, %%eax\n"
+  	"  int  $0x80\n"
+  	"  pop %%ebp\n"
+		: "=a" (res)
+		: "i" (__NR_mmap2), "b" (addr), "c" (length), "d" (prot), "S" (flags),
+		"D" (fd), "0" (pgoffset)
+	);
+	return (void *)res;
+}
+#endif
+
+int host_putchar(int c) {
+	unsigned char ch = (unsigned char)c;
+	if(host_write(STDOUT_FILENO, &ch, 1) != 1) {
+		return EOF;
+	}
+	return (int)ch;
+}
+
+int host_getchar() {
+	unsigned char ch = 0;
+	if(host_read(STDIN_FILENO, &ch, 1) != 1) {
+		return EOF;
+	}
+	return (int)ch;
+}
+

Property changes on: src/platform/linux/host.c
___________________________________________________________________
Added: svn:eol-style
   + native

Index: src/platform/linux/descriptor_tables.h
===================================================================
--- src/platform/linux/descriptor_tables.h	(revision 0)
+++ src/platform/linux/descriptor_tables.h	(revision 0)
@@ -0,0 +1,113 @@
+// 
+// descriptor_tables.h - Defines the interface for initialising the GDT and IDT.
+//                       Also defines needed structures.
+//                       Based on code from Bran's kernel development tutorials.
+//                       Rewritten for JamesM's kernel development tutorials.
+//
+
+#include "common.h"
+
+// Initialisation function is publicly accessible.
+void init_descriptor_tables();
+
+#if 0
+// This structure contains the value of one GDT entry.
+// We use the attribute 'packed' to tell GCC not to change
+// any of the alignment in the structure.
+struct gdt_entry_struct
+{
+    u16int limit_low;           // The lower 16 bits of the limit.
+    u16int base_low;            // The lower 16 bits of the base.
+    u8int  base_middle;         // The next 8 bits of the base.
+    u8int  access;              // Access flags, determine what ring this segment can be used in.
+    u8int  granularity;
+    u8int  base_high;           // The last 8 bits of the base.
+} __attribute__((packed));
+
+typedef struct gdt_entry_struct gdt_entry_t;
+
+// This struct describes a GDT pointer. It points to the start of
+// our array of GDT entries, and is in the format required by the
+// lgdt instruction.
+struct gdt_ptr_struct
+{
+    u16int limit;               // The upper 16 bits of all selector limits.
+    u32int base;                // The address of the first gdt_entry_t struct.
+} __attribute__((packed));
+
+typedef struct gdt_ptr_struct gdt_ptr_t;
+
+// A struct describing an interrupt gate.
+struct idt_entry_struct
+{
+    u16int base_lo;             // The lower 16 bits of the address to jump to when this interrupt fires.
+    u16int sel;                 // Kernel segment selector.
+    u8int  always0;             // This must always be zero.
+    u8int  flags;               // More flags. See documentation.
+    u16int base_hi;             // The upper 16 bits of the address to jump to.
+} __attribute__((packed));
+
+typedef struct idt_entry_struct idt_entry_t;
+
+// A struct describing a pointer to an array of interrupt handlers.
+// This is in a format suitable for giving to 'lidt'.
+struct idt_ptr_struct
+{
+    u16int limit;
+    u32int base;                // The address of the first element in our idt_entry_t array.
+} __attribute__((packed));
+
+typedef struct idt_ptr_struct idt_ptr_t;
+
+// These extern directives let us access the addresses of our ASM ISR handlers.
+extern void isr0 ();
+extern void isr1 ();
+extern void isr2 ();
+extern void isr3 ();
+extern void isr4 ();
+extern void isr5 ();
+extern void isr6 ();
+extern void isr7 ();
+extern void isr8 ();
+extern void isr9 ();
+extern void isr10();
+extern void isr11();
+extern void isr12();
+extern void isr13();
+extern void isr14();
+extern void isr15();
+extern void isr16();
+extern void isr17();
+extern void isr18();
+extern void isr19();
+extern void isr20();
+extern void isr21();
+extern void isr22();
+extern void isr23();
+extern void isr24();
+extern void isr25();
+extern void isr26();
+extern void isr27();
+extern void isr28();
+extern void isr29();
+extern void isr30();
+extern void isr31();
+extern void irq0 ();
+extern void irq1 ();
+extern void irq2 ();
+extern void irq3 ();
+extern void irq4 ();
+extern void irq5 ();
+extern void irq6 ();
+extern void irq7 ();
+extern void irq8 ();
+extern void irq9 ();
+extern void irq10();
+extern void irq11();
+extern void irq12();
+extern void irq13();
+extern void irq14();
+extern void irq15();
+
+
+#endif

Property changes on: src/platform/linux/descriptor_tables.h
___________________________________________________________________
Added: svn:eol-style
   + native

Index: src/platform/linux/timer.c
===================================================================
--- src/platform/linux/timer.c	(revision 0)
+++ src/platform/linux/timer.c	(revision 0)
@@ -0,0 +1,42 @@
+// timer.c -- Initialises the PIT, and handles clock updates.
+//            Written for JamesM's kernel development tutorials.
+
+#include "timer.h"
+#include "isr.h"
+#include "monitor.h"
+
+#if 0
+u32int tick = 0;
+
+static void timer_callback(registers_t regs)
+{
+    tick++;
+    monitor_write("Tick: ");
+    monitor_write_dec(tick);
+    monitor_write("\n");
+}
+#endif
+
+void init_timer(u32int frequency)
+{
+#if 0
+    // Firstly, register our timer callback.
+    register_interrupt_handler(IRQ0, &timer_callback);
+
+    // The value we send to the PIT is the value to divide it's input clock
+    // (1193180 Hz) by, to get our required frequency. Important to note is
+    // that the divisor must be small enough to fit into 16-bits.
+    u32int divisor = 1193180 / frequency;
+
+    // Send the command byte.
+    outb(0x43, 0x36);
+
+    // Divisor has to be sent byte-wise, so split here into upper/lower bytes.
+    u8int l = (u8int)(divisor & 0xFF);
+    u8int h = (u8int)( (divisor>>8) & 0xFF );
+
+    // Send the frequency divisor.
+    outb(0x40, l);
+    outb(0x40, h);
+#endif
+}

Property changes on: src/platform/linux/timer.c
___________________________________________________________________
Added: svn:eol-style
   + native

Index: src/platform/linux/host.h
===================================================================
--- src/platform/linux/host.h	(revision 0)
+++ src/platform/linux/host.h	(revision 0)
@@ -0,0 +1,34 @@
+// host.h -- Defines syscall wrappers to access host OS.
+
+#ifndef _HOST_H
+#define _HOST_H
+
+#include <stddef.h>
+#include <sys/types.h>
+
+extern int host_errno;
+
+#define EOF (-1)
+#define STDIN_FILENO 0
+#define STDOUT_FILENO 1
+
+ssize_t host_read( int fd, void * buf, size_t count);
+ssize_t host_write( int fd, const void * buf, size_t count);
+int host_putchar(int c);
+int host_getchar();
+
+#define PROT_READ 0x1   /* Page can be read.  */
+#define PROT_WRITE  0x2   /* Page can be written.  */
+#define PROT_EXEC 0x4   /* Page can be executed.  */
+#define PROT_NONE 0x0   /* Page can not be accessed.  */
+
+#define MAP_SHARED  0x01    /* Share changes.  */
+#define MAP_PRIVATE 0x02    /* Changes are private.  */
+#define MAP_FIXED 0x10    /* Interpret addr exactly.  */
+#define MAP_ANONYMOUS  0x20    /* Don't use a file.  */
+
+#define MAP_FAILED (void *)(-1)
+
+void *host_mmap2(void *addr, size_t length, int prot, int flags, int fd, off_t pgoffset);
+
+#endif // _HOST_H

Property changes on: src/platform/linux/host.h
___________________________________________________________________
Added: svn:eol-style
   + native

Index: src/platform/linux/multiboot.h
===================================================================
--- src/platform/linux/multiboot.h	(revision 0)
+++ src/platform/linux/multiboot.h	(revision 0)
@@ -0,0 +1,123 @@
+/* multiboot.h - the header for Multiboot */
+/* Copyright (C) 1999, 2001  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. */
+
+/* Macros. */
+
+#if 0
+
+/* The magic number for the Multiboot header. */
+#define MULTIBOOT_HEADER_MAGIC          0x1BADB002
+
+/* The flags for the Multiboot header. */
+#ifdef __ELF__
+# define MULTIBOOT_HEADER_FLAGS         0x00000003
+#else
+# define MULTIBOOT_HEADER_FLAGS         0x00010003
+#endif
+
+/* The magic number passed by a Multiboot-compliant boot loader. */
+#define MULTIBOOT_BOOTLOADER_MAGIC      0x2BADB002
+
+/* The size of our stack (16KB). */
+#define STACK_SIZE                      0x4000
+
+/* C symbol format. HAVE_ASM_USCORE is defined by configure. */
+#ifdef HAVE_ASM_USCORE
+# define EXT_C(sym)                     _ ## sym
+#else
+# define EXT_C(sym)                     sym
+#endif
+
+#ifndef ASM
+/* Do not include here in boot.S. */
+
+/* Types. */
+
+/* The Multiboot header. */
+typedef struct multiboot_header
+{
+  unsigned long magic;
+  unsigned long flags;
+  unsigned long checksum;
+  unsigned long header_addr;
+  unsigned long load_addr;
+  unsigned long load_end_addr;
+  unsigned long bss_end_addr;
+  unsigned long entry_addr;
+} multiboot_header_t;
+
+/* The symbol table for a.out. */
+typedef struct aout_symbol_table
+{
+  unsigned long tabsize;
+  unsigned long strsize;
+  unsigned long addr;
+  unsigned long reserved;
+} aout_symbol_table_t;
+
+/* The section header table for ELF. */
+typedef struct elf_section_header_table
+{
+  unsigned long num;
+  unsigned long size;
+  unsigned long addr;
+  unsigned long shndx;
+} elf_section_header_table_t;
+
+/* The Multiboot information. */
+typedef struct multiboot_info
+{
+  unsigned long flags;
+  unsigned long mem_lower;
+  unsigned long mem_upper;
+  unsigned long boot_device;
+  unsigned long cmdline;
+  unsigned long mods_count;
+  unsigned long mods_addr;
+  union
+  {
+    aout_symbol_table_t aout_sym;
+    elf_section_header_table_t elf_sec;
+  } u;
+  unsigned long mmap_length;
+  unsigned long mmap_addr;
+} multiboot_info_t;
+
+/* The module structure. */
+typedef struct module
+{
+  unsigned long mod_start;
+  unsigned long mod_end;
+  unsigned long string;
+  unsigned long reserved;
+} module_t;
+
+/* The memory map. Be careful that the offset 0 is base_addr_low
+  but no size. */
+typedef struct memory_map
+{
+  unsigned long size;
+  unsigned long base_addr_low;
+  unsigned long base_addr_high;
+  unsigned long length_low;
+  unsigned long length_high;
+  unsigned long type;
+} memory_map_t;
+
+#endif /* ! ASM */
+
+#endif

Property changes on: src/platform/linux/multiboot.h
___________________________________________________________________
Added: svn:eol-style
   + native

Index: src/platform/linux/boot.s
===================================================================
--- src/platform/linux/boot.s	(revision 0)
+++ src/platform/linux/boot.s	(revision 0)
@@ -0,0 +1,27 @@
+;
+; boot.s -- Kernel start location. Also defines multiboot header.
+;           Based on Bran's kernel development tutorial file start.asm
+;
+
+[BITS 32]                       ; All instructions should be 32-bit.
+
+[EXTERN code]                   ; Start of the '.text' section.
+[EXTERN bss]                    ; Start of the .bss section.
+[EXTERN end]                    ; End of the last loadable section.
+[SECTION .header]
+
+[GLOBAL start]                  ; Kernel entry point.
+[EXTERN main]                   ; This is the entry point of our C code
+[EXTERN platform_ll_init]       ; Low level initializatin function
+[SECTION .text]
+    
+start:
+
+    push ebx
+    call platform_ll_init
+
+    ; Execute the kernel:
+    call main                   ; call our main() function.
+    jmp $                       ; Enter an infinite loop, to stop the processor
+                                ; executing whatever rubbish is in the memory
+                                ; after our kernel!
Index: src/platform/linux/platform.c
===================================================================
--- src/platform/linux/platform.c	(revision 0)
+++ src/platform/linux/platform.c	(revision 0)
@@ -0,0 +1,171 @@
+// Platform-dependent functions
+
+#include "platform.h"
+#include "platform_conf.h"
+#include "type.h"
+#include "devman.h"
+#include "genstd.h"
+#include <reent.h>
+#include <errno.h>
+#include <string.h>
+#include <ctype.h>
+#include "term.h"
+
+// Platform specific includes
+#include "monitor.h"
+#include "descriptor_tables.h"
+#include "kb.h"
+#include "host.h"
+
+// ****************************************************************************
+// Terminal support code
+
+#ifdef BUILD_TERM
+
+static void i386_term_out( u8 data )
+{
+  monitor_put( data );
+}
+
+static int i386_term_in( int mode )
+{
+  if( mode == TERM_INPUT_DONT_WAIT )
+    return -1;
+  else
+    return keyboard_getch();
+}
+
+static int i386_term_translate( int data )
+{
+  int newdata = data;
+
+  if( data == 0 )
+    return KC_UNKNOWN;
+  else switch( data )
+  {
+    case '\n':
+      newdata = KC_ENTER;
+      break;
+
+    case '\t':
+      newdata = KC_TAB;
+      break;
+
+    case '\b':
+      newdata = KC_BACKSPACE;
+      break;
+  }
+  return newdata;
+}
+
+#endif // #ifdef BUILD_TERM
+
+// *****************************************************************************
+// std functions
+static void scr_write( int fd, char c )
+{
+  fd = fd;
+  monitor_put( c );
+}
+
+static int kb_read( s32 to )
+{
+  int res;
+
+  if( to != STD_INFINITE_TIMEOUT )
+    return -1;
+  else
+  {
+    while( ( res = keyboard_getch() ) >= TERM_FIRST_KEY );
+    return res;
+  }
+}
+
+// ****************************************************************************
+// Platform initialization (low-level and full)
+
+void *memory_start_address = 0;
+void *memory_end_address = 0;
+
+void platform_ll_init()
+{
+#if 0
+  // Initialise all the ISRs and segmentation
+  init_descriptor_tables();
+#endif
+    
+  // Initialise the screen (by clearing it)
+  monitor_clear();        
+
+	// Initialise heap memory region.
+	memory_start_address =
+		host_mmap2(0, MEM_LENGTH, (PROT_READ|PROT_WRITE), (MAP_PRIVATE|MAP_ANONYMOUS), -1, 0);
+	memory_end_address = memory_start_address + MEM_LENGTH;
+}
+
+int platform_init()
+{ 
+#if 0
+  // We can start interrupts now
+  asm volatile("sti");    
+  
+  // And install the keyboard handler
+  keyboard_install();
+#endif
+
+	if(memory_start_address == MAP_FAILED) {
+    monitor_write( "platform_init(): mmap failed\n" );
+		return PLATFORM_ERR;
+	}
+  // Set the std input/output functions
+  // Set the send/recv functions                          
+  std_set_send_func( scr_write );
+  std_set_get_func( kb_read );       
+
+  // Set term functions
+#ifdef BUILD_TERM  
+  term_init( TERM_LINES, TERM_COLS, i386_term_out, i386_term_in, i386_term_translate );
+#endif
+ 
+  // All done
+  return PLATFORM_OK;
+}
+
+// ****************************************************************************
+// "Dummy" UART functions
+
+u32 platform_uart_setup( unsigned id, u32 baud, int databits, int parity, int stopbits )
+{
+  return 0;
+}
+
+void platform_uart_send( unsigned id, u8 data )
+{
+}
+
+int platform_s_uart_recv( unsigned id, s32 timeout )
+{
+  return -1;
+}
+
+// ****************************************************************************
+// "Dummy" timer functions
+
+void platform_s_timer_delay( unsigned id, u32 delay_us )
+{
+}
+
+u32 platform_s_timer_op( unsigned id, int op, u32 data )
+{
+  return 0;
+}
+
+// ****************************************************************************
+// Allocator support
+
+#if 0
+u32 platform_get_lastmem()
+{
+  return lastmem;
+}
+#endif

Property changes on: src/platform/linux/platform.c
___________________________________________________________________
Added: svn:eol-style
   + native

Index: src/platform/linux/timer.h
===================================================================
--- src/platform/linux/timer.h	(revision 0)
+++ src/platform/linux/timer.h	(revision 0)
@@ -0,0 +1,11 @@
+// timer.h -- Defines the interface for all PIT-related functions.
+//            Written for JamesM's kernel development tutorials.
+
+#ifndef TIMER_H
+#define TIMER_H
+
+#include "common.h"
+
+void init_timer(u32int frequency);
+
+#endif

Property changes on: src/platform/linux/timer.h
___________________________________________________________________
Added: svn:eol-style
   + native

Index: src/platform/linux/type.h
===================================================================
--- src/platform/linux/type.h	(revision 0)
+++ src/platform/linux/type.h	(revision 0)
@@ -0,0 +1,30 @@
+#ifndef __TYPE_H__
+#define __TYPE_H__
+
+#ifndef NULL
+#define NULL    ((void *)0)
+#endif
+
+#ifndef FALSE
+#define FALSE   (0)
+#endif
+
+#ifndef TRUE
+#define TRUE    (1)
+#endif
+
+typedef unsigned char  BYTE;
+typedef unsigned short WORD;
+typedef unsigned long  DWORD;
+typedef unsigned int   BOOL;
+
+typedef unsigned char u8;
+typedef signed char s8;
+typedef unsigned short u16;
+typedef signed short s16;
+typedef unsigned long u32;
+typedef signed long s32;
+typedef unsigned long long u64;
+typedef signed long long s64;
+
+#endif

Property changes on: src/platform/linux/type.h
___________________________________________________________________
Added: svn:eol-style
   + native

Index: src/platform/linux/monitor.c
===================================================================
--- src/platform/linux/monitor.c	(revision 0)
+++ src/platform/linux/monitor.c	(revision 0)
@@ -0,0 +1,358 @@
+// monitor.c -- Defines functions for writing to the monitor.
+//             heavily based on Bran's kernel development tutorials,
+//             but rewritten for JamesM's kernel tutorials.
+
+#include "monitor.h"
+#include <ctype.h>
+#include <string.h>
+#include <stdio.h>
+#include "term.h"
+#include "utils.h"
+#include "host.h"
+
+#if 0
+// The VGA framebuffer starts at 0xB8000.
+u16int *video_memory = (u16int *)0xB8000;
+// Stores the cursor position.
+u8int cursor_x = 0;
+u8int cursor_y = 0;
+#endif
+
+// Updates the hardware cursor.
+#if 0
+static void move_cursor()
+{
+    cursor_y = UMIN( cursor_y, 24 );
+    cursor_x = UMIN( cursor_x, 79 );
+    // The screen is 80 characters wide...
+    u16int cursorLocation = cursor_y * 80 + cursor_x;
+    outb(0x3D4, 14);                  // Tell the VGA board we are setting the high cursor byte.
+    outb(0x3D5, cursorLocation >> 8); // Send the high cursor byte.
+    outb(0x3D4, 15);                  // Tell the VGA board we are setting the low cursor byte.
+    outb(0x3D5, cursorLocation);      // Send the low cursor byte.
+}
+#endif
+
+#if 0
+// Scrolls the text on the screen up by one line.
+static void scroll()
+{
+    // Get a space character with the default colour attributes.
+    u8int attributeByte = (0 /*black*/ << 4) | (15 /*white*/ & 0x0F);
+    u16int blank = 0x20 /* space */ | (attributeByte << 8);
+
+    // Row 25 is the end, this means we need to scroll up
+    if(cursor_y >= 25)
+    {
+        // Move the current text chunk that makes up the screen
+        // back in the buffer by a line
+        int i;
+        for (i = 0*80; i < 24*80; i++)
+        {
+            video_memory[i] = video_memory[i+80];
+        }
+
+        // The last line should now be blank. Do this by writing
+        // 80 spaces to it.
+        for (i = 24*80; i < 25*80; i++)
+        {
+            video_memory[i] = blank;
+        }
+        // The cursor should now be on the last line.
+        cursor_y = 24;
+    }
+}
+#endif
+
+#if 0
+// ANSI 'state machine'
+static int monitor_reading_ansi;
+static int monitor_ansi_count;
+static char monitor_ansi_inbuf[ TERM_MAX_ANSI_SIZE + 1 ];
+
+// ANSI operations and structure data
+enum
+{
+  ANSI_SEQ_CLRSCR,
+  ANSI_SEQ_CLREOL,
+  ANSI_SEQ_GOTOXY,
+  ANSI_SEQ_UP,
+  ANSI_SEQ_DOWN,
+  ANSI_SEQ_RIGHT,
+  ANSI_SEQ_LEFT
+};
+
+typedef struct
+{
+  int op;
+  int p1, p2; 
+} ansi_op;
+
+// Convert an ASCII escape sequence to an operation we can understand
+static int monitor_cvt_escape( const char* inbuf, ansi_op* res )
+{
+  const char *p = inbuf;
+  char last = inbuf[ strlen( inbuf ) - 1 ];
+
+  if( *p++ != '\x1B' )
+    return 0;
+  if( *p++ != '[' )
+    return 0;
+  res->op = res->p1 = res->p2 = 0;
+  switch( last )
+  {
+    case 'J': // clrscr
+      if( *p != '2' )
+        return 0;
+      res->op = ANSI_SEQ_CLRSCR;
+      break;
+
+    case 'K': // clreol
+      res->op = ANSI_SEQ_CLREOL;
+      break;
+
+    case 'H': // gotoxy
+      res->op = ANSI_SEQ_GOTOXY;
+      if( *p != 'H' )
+        sscanf( p, "%d;%d", &res->p1, &res->p2 );
+      break;
+
+    case 'A': // up
+    case 'B': // down
+    case 'C': // right
+    case 'D': // left
+      res->op = last - 'A' + ANSI_SEQ_UP;
+      sscanf( p, "%d", &res->p1 );
+      break;
+  }
+  return 1;
+}
+#endif
+
+void monitor_clear();
+// Writes a single character out to the screen.
+void monitor_put(char c)
+{
+	host_putchar(c);
+#if 0
+    // The background colour is black (0), the foreground is white (15).
+    u8int backColour = 0;
+    u8int foreColour = 15;
+
+    // Take care of the ANSI state machine
+    if( c == '\x1B' )
+    {
+      monitor_reading_ansi = 1;
+      monitor_ansi_count = 0;
+      monitor_ansi_inbuf[ monitor_ansi_count ++ ] = c; 
+      return;
+    }
+
+    // The attribute byte is made up of two nibbles - the lower being the 
+    // foreground colour, and the upper the background colour.
+    u8int  attributeByte = (backColour << 4) | (foreColour & 0x0F);
+    // The attribute byte is the top 8 bits of the word we have to send to the
+    // VGA board.
+    u16int attribute = attributeByte << 8;
+    u16int *location;
+    u8int prev;
+
+    if( monitor_reading_ansi )
+    {
+      monitor_ansi_inbuf[ monitor_ansi_count ++ ] = c;
+      if( isalpha( c ) )
+      {
+        monitor_ansi_inbuf[ monitor_ansi_count ] = '\0';
+        ansi_op op;
+        if( monitor_cvt_escape( monitor_ansi_inbuf, &op ) )
+        {
+          // Interpret out sequence
+          switch( op.op )
+          {
+            case ANSI_SEQ_CLRSCR:
+              monitor_clear();
+              break;
+
+            case ANSI_SEQ_CLREOL:
+              prev = cursor_x;
+              while( cursor_x++ < 80 )
+              {
+                location = video_memory + (cursor_y*80 + cursor_x);      
+                *location = ' ' | attribute;
+              }
+              cursor_x = prev;
+              break;
+
+            case ANSI_SEQ_GOTOXY:
+              cursor_y = ( u8int )op.p1 - 1;
+              cursor_x = ( u8int )op.p2 - 1;
+              move_cursor();
+              break;
+
+            case ANSI_SEQ_UP:
+            case ANSI_SEQ_LEFT:
+            case ANSI_SEQ_RIGHT:
+            case ANSI_SEQ_DOWN:
+              {
+                int xm = op.op == ANSI_SEQ_LEFT ? -1 : op.op == ANSI_SEQ_RIGHT ? 1 : 0;
+                int ym = op.op == ANSI_SEQ_UP ? -1 : op.op == ANSI_SEQ_DOWN ? 1 : 0;
+                cursor_x += xm * op.p1;
+                cursor_y += ym * op.p1;
+                move_cursor();
+                break;
+              }
+           }
+        }
+        monitor_reading_ansi = 0;
+      }
+      return;
+    }
+
+    // Handle a backspace, by moving the cursor back one space
+    if (c == 0x08 && cursor_x)
+    {
+        cursor_x--;
+    }
+
+    // Handle a tab by increasing the cursor's X, but only to a point
+    // where it is divisible by 2.
+    else if (c == 0x09)
+    {
+        cursor_x = (cursor_x+2) & ~(2-1);
+    }
+
+    // Handle carriage return
+    else if (c == '\r')
+    {
+        cursor_x = 0;
+    }
+
+    // Handle newline by moving cursor back to left and increasing the row
+    else if (c == '\n')
+    {
+        cursor_x = 0;
+        cursor_y++;
+    }
+    // Handle any other printable character.
+    else if(c >= ' ')
+    {
+        location = video_memory + (cursor_y*80 + cursor_x);
+        *location = c | attribute;
+        cursor_x++;
+    }
+
+    // Check if we need to insert a new line because we have reached the end
+    // of the screen.
+    if (cursor_x >= 80)
+    {
+        cursor_x = 0;
+        cursor_y ++;
+    }
+
+    // Scroll the screen if needed.
+    scroll();
+    // Move the hardware cursor.
+    move_cursor();
+#endif
+}
+
+// Clears the screen, by copying lots of spaces to the framebuffer.
+void monitor_clear()
+{
+#if 0
+    // Make an attribute byte for the default colours
+    u8int attributeByte = (0 /*black*/ << 4) | (15 /*white*/ & 0x0F);
+    u16int blank = 0x20 /* space */ | (attributeByte << 8);
+
+    int i;
+    for (i = 0; i < 80*25; i++)
+    {
+        video_memory[i] = blank;
+    }
+
+    // Move the hardware cursor back to the start.
+    cursor_x = 0;
+    cursor_y = 0;
+    move_cursor();
+#endif
+}
+
+// Outputs a null-terminated ASCII string to the monitor.
+void monitor_write(char *c)
+{
+    int i = 0;
+    while (c[i])
+    {
+        monitor_put(c[i++]);
+    }
+}
+
+void monitor_write_hex(u32int n)
+{
+    s32int tmp;
+
+    char noZeroes = 1;
+
+    int i;
+    for (i = 28; i > 0; i -= 4)
+    {
+        tmp = (n >> i) & 0xF;
+        if (tmp == 0 && noZeroes != 0)
+        {
+            continue;
+        }
+    
+        if (tmp >= 0xA)
+        {
+            noZeroes = 0;
+            monitor_put (tmp-0xA+'a' );
+        }
+        else
+        {
+            noZeroes = 0;
+            monitor_put( tmp+'0' );
+        }
+    }
+  
+    tmp = n & 0xF;
+    if (tmp >= 0xA)
+    {
+        monitor_put (tmp-0xA+'a');
+    }
+    else
+    {
+        monitor_put (tmp+'0');
+    }
+
+}
+
+void monitor_write_dec(u32int n)
+{
+
+    if (n == 0)
+    {
+        monitor_put('0');
+        return;
+    }
+
+    s32int acc = n;
+    char c[32];
+    int i = 0;
+    while (acc > 0)
+    {
+        c[i] = '0' + acc%10;
+        acc /= 10;
+        i++;
+    }
+    c[i] = 0;
+
+    char c2[32];
+    c2[i--] = 0;
+    int j = 0;
+    while(i >= 0)
+    {
+        c2[i--] = c[j++];
+    }
+    monitor_write(c2);
+
+}

Property changes on: src/platform/linux/monitor.c
___________________________________________________________________
Added: svn:eol-style
   + native

Index: src/platform/linux/common.c
===================================================================
--- src/platform/linux/common.c	(revision 0)
+++ src/platform/linux/common.c	(revision 0)
@@ -0,0 +1,33 @@
+// common.c -- Defines some global functions.
+//             From JamesM's kernel development tutorials.
+
+#include "common.h"
+
+// Write a byte out to the specified port.
+void outb(u16int port, u8int value)
+{
+#if 0
+    asm volatile ("outb %1, %0" : : "dN" (port), "a" (value));
+#endif
+}
+
+u8int inb(u16int port)
+{
+#if 0
+    u8int ret;
+    asm volatile("inb %1, %0" : "=a" (ret) : "dN" (port));
+    return ret;
+#endif
+	return 0;
+}
+
+u16int inw(u16int port)
+{
+#if 0
+    u16int ret;
+    asm volatile ("inw %1, %0" : "=a" (ret) : "dN" (port));
+    return ret;
+#endif
+	return 0;
+}
+

Property changes on: src/platform/linux/common.c
___________________________________________________________________
Added: svn:eol-style
   + native

Index: src/platform/linux/conf.py
===================================================================
--- src/platform/linux/conf.py	(revision 0)
+++ src/platform/linux/conf.py	(revision 0)
@@ -0,0 +1,25 @@
+# Configuration file for the i386 backend
+
+specific_files = "boot.s common.c descriptor_tables.c isr.c kb.c monitor.c timer.c platform.c host.c"
+ldscript = "i386.ld"
+  
+# override default optimize settings (-Os is broken right now)
+opt = " -g -O0 "
+
+# Prepend with path
+specific_files = " ".join( [ "src/platform/%s/%s" % ( platform, f ) for f in specific_files.split() ] )
+ldscript = "src/platform/%s/%s" % ( platform, ldscript )
+
+# Toolset data
+tools[ 'linux' ] = {}
+tools[ 'linux' ][ 'cccom' ] = "%s %s $_CPPINCFLAGS -march=i386 -mfpmath=387 -m32 -ffunction-sections -fdata-sections -fno-builtin -fno-stack-protector %s -Wall -c $SOURCE -o $TARGET" % ( toolset[ 'compile' ], opt, cdefs )
+tools[ 'linux' ][ 'linkcom' ] = "%s -nostartfiles -nostdlib -march=i386 -mfpmath=387 -m32 -T %s -Wl,--gc-sections -Wl,-e,start -Wl,--allow-multiple-definition -o $TARGET $SOURCES -lc -lgcc -lm %s" % ( toolset[ 'compile' ], ldscript, local_libs )
+tools[ 'linux' ][ 'ascom' ] = "%s -felf $SOURCE" % toolset[ 'asm' ]
+
+# Programming function for i386 (not needed, empty function)
+def progfunc_i386( target, source, env ):
+  outname = output + ".elf"
+  os.system( "%s %s" % ( toolset[ 'size' ], outname ) )
+  print "Visit http://www.eluaproject.net for instructions on how to use your eLua ELF file"
+  
+tools[ 'linux' ][ 'progfunc' ] = progfunc_i386
Index: src/platform/linux/monitor.h
===================================================================
--- src/platform/linux/monitor.h	(revision 0)
+++ src/platform/linux/monitor.h	(revision 0)
@@ -0,0 +1,18 @@
+// monitor.h -- Defines the interface for monitor.h
+//              From JamesM's kernel development tutorials.
+
+#ifndef MONITOR_H
+#define MONITOR_H
+
+#include "common.h"
+
+// Write a single character out to the screen.
+void monitor_put(char c);
+
+// Clear the screen to all black.
+void monitor_clear();
+
+// Output a null-terminated ASCII string to the monitor.
+void monitor_write(char *c);
+
+#endif // MONITOR_H

Property changes on: src/platform/linux/monitor.h
___________________________________________________________________
Added: svn:eol-style
   + native

Index: src/platform/linux/kb.c
===================================================================
--- src/platform/linux/kb.c	(revision 0)
+++ src/platform/linux/kb.c	(revision 0)
@@ -0,0 +1,205 @@
+/* bkerndev - Bran's Kernel Development Tutorial
+*  By:   Brandon F. (friesenb@gmail.com)
+*  Desc: Keyboard driver
+*
+*  Notes: No warranty expressed or implied. Use at own risk. */
+#include "common.h"
+#include "monitor.h"
+#include "isr.h"
+#include "type.h"
+#include "utils.h"
+#include "term.h"
+#include "host.h"
+#include <stdio.h>
+
+#if 0
+#define RSHIFT 0x36
+#define LSHIFT 0x2A
+#define CTRL   0x1D
+static int shift_pressed, ctrl_pressed;
+
+/* KBDUS means US Keyboard Layout. This is a scancode table
+*  used to layout a standard US keyboard. I have left some
+*  comments in to give you an idea of what key is what, even
+*  though I set it's array index to 0. You can change that to
+*  whatever you want using a macro, if you wish! */
+const unsigned char kbdus[128] =
+{
+    0,  27, '1', '2', '3', '4', '5', '6', '7', '8', /* 9 */
+  '9', '0', '-', '=', '\b', /* Backspace */
+  '\t',     /* Tab */
+  'q', 'w', 'e', 'r', /* 19 */
+  't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\n',   /* Enter key */
+    0,      /* 29   - Control */
+  'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', /* 39 */
+ '\'', '`',   0,    /* Left shift */
+ '\\', 'z', 'x', 'c', 'v', 'b', 'n',      /* 49 */
+  'm', ',', '.', '/',   0,          /* Right shift */
+  '*',
+    0,  /* Alt */
+  ' ',  /* Space bar */
+    0,  /* Caps lock */
+    0,  /* 59 - F1 key ... > */
+    0,   0,   0,   0,   0,   0,   0,   0,
+    0,  /* < ... F10 */
+    0,  /* 69 - Num lock*/
+    0,  /* Scroll Lock */
+    0,  /* Home key */
+    0,  /* Up Arrow */
+    0,  /* Page Up */
+  '-',
+    0,  /* Left Arrow */
+    0,
+    0,  /* Right Arrow */
+  '+',
+    0,  /* 79 - End key*/
+    0,  /* Down Arrow */
+    0,  /* Page Down */
+    0,  /* Insert Key */
+    0,  /* Delete Key */
+    0,   0,   0,
+    0,  /* F11 Key */
+    0,  /* F12 Key */
+    0,  /* All other keys are undefined */
+};
+
+const unsigned char shift_kbdus[128] =
+{
+  0,  27, '!', '@', '#', '$', '%', '^', '&', '*', /* 9 */
+  '(', ')', '_', '+', '\b', /* Backspace */
+  '\t',     /* Tab */
+  'Q', 'W', 'E', 'R', /* 19 */
+  'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', '\n',   /* Enter key */
+  0,      /* 29   - Control */
+  'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', /* 39 */
+  '"', '~',   0,    /* Left shift */
+  '|', 'Z', 'X', 'C', 'V', 'B', 'N',      /* 49 */
+  'M', '<', '>', '?',   0,          /* Right shift */
+  '*',
+  0,  /* Alt */
+  ' ',  /* Space bar */
+  0,  /* Caps lock */
+  0,  /* 59 - F1 key ... > */
+  0,   0,   0,   0,   0,   0,   0,   0,
+  0,  /* < ... F10 */
+  0,  /* 69 - Num lock*/
+  0,  /* Scroll Lock */
+  0,  /* Home key */
+  0,  /* Up Arrow */
+  0,  /* Page Up */
+  '-',
+  0,  /* Left Arrow */
+  0,
+  0,  /* Right Arrow */
+  '+',
+  0,  /* 79 - End key*/
+  0,  /* Down Arrow */
+  0,  /* Page Down */
+  0,  /* Insert Key */
+  0,  /* Delete Key */
+  0,   0,   0,
+  0,  /* F11 Key */
+  0,  /* F12 Key */
+  0,  /* All other keys are undefined */
+};
+
+// Keyboard buffer
+#define KBUF_SIZE     64
+static int kb_buffer[ KBUF_SIZE ];
+static u8 r_ptr;
+static volatile u8 w_ptr;
+
+// Special keys lookup
+static const unsigned char skeys[] = { 0x48, 0x50, 0x4b, 0x4d, 0x47, 0x4f, 0x49, 0x51, 0, 0, 0, 1 };
+
+/* Handles the keyboard interrupt */
+void keyboard_handler(registers_t regs)
+{
+    unsigned char scancode;
+    int i;
+
+    /* Read from the keyboard's data buffer */
+    /* Ignore 0xE0 (extended indication) */
+    if( ( scancode = inb( 0x60 ) ) == 0xE0 )
+     return;
+
+    /* If the top bit of the byte we read from the keyboard is
+    *  set, that means that a key has just been released */
+    if (scancode & 0x80)
+    {
+        /* You can use this one to see if the user released the
+        *  shift, alt, or control keys... */
+      scancode &= 0x7F;
+      if( ( scancode == RSHIFT ) || ( scancode == LSHIFT ) )
+        shift_pressed = 0;
+      else if ( scancode == CTRL )
+        ctrl_pressed = 0;
+    }
+    else
+    {
+
+      /* Check if this is a special key (will be used by the term module) */    
+      for( i = 0; i < sizeof( skeys ) / sizeof( unsigned char ); i ++ )
+        if( skeys[ i ] == scancode )
+        {
+            kb_buffer[ w_ptr ] = TERM_FIRST_KEY + i;
+            w_ptr = ( w_ptr + 1 ) % KBUF_SIZE;
+            return;
+        }
+
+      /* Here, a key was just pressed. Please note that if you
+      *  hold a key down, you will get repeated key press
+      *  interrupts. */
+
+      /* Just to show you how this works, we simply translate
+      *  the keyboard scancode into an ASCII value, and then
+      *  display it to the screen. You can get creative and
+      *  use some flags to see if a shift is pressed and use a
+      *  different layout, or you can add another 128 entries
+      *  to the above layout to correspond to 'shift' being
+      *  held. If shift is held using the larger lookup table,
+      *  you would add 128 to the scancode when you look for it */
+      if( ( scancode == RSHIFT ) || ( scancode == LSHIFT ) )
+        shift_pressed = 1;
+      else if( scancode == CTRL )
+        ctrl_pressed = 1;
+      else      
+      {
+        if( ( ( w_ptr + 1 ) % KBUF_SIZE ) != r_ptr )
+        {
+          unsigned char thechar = shift_pressed ? shift_kbdus[scancode] : kbdus[scancode];
+          if( ctrl_pressed ) // Look for CTRL+Z (EOF)
+            thechar = ( thechar == 'z' || thechar == 'Z' ) ? STD_CTRLZ_CODE : 0;
+          if( thechar != 0 )
+          {
+            kb_buffer[ w_ptr ] = thechar;
+            w_ptr = ( w_ptr + 1 ) % KBUF_SIZE;
+          }
+        }
+      }
+    }
+}
+#endif
+
+/* Installs the keyboard handler into IRQ1 */
+void keyboard_install()
+{
+#if 0
+  register_interrupt_handler(IRQ1, keyboard_handler);
+#endif
+}
+
+// Return a key from the keyboard (blocking!)
+int keyboard_getch()
+{
+	return host_getchar();
+#if 0
+  int c;
+  
+  while( r_ptr == w_ptr );
+  c = kb_buffer[ r_ptr ];
+  r_ptr = ( r_ptr + 1 ) % KBUF_SIZE;
+  return c; 
+#endif
+}
+

Property changes on: src/platform/linux/kb.c
___________________________________________________________________
Added: svn:eol-style
   + native

Index: src/platform/linux/common.h
===================================================================
--- src/platform/linux/common.h	(revision 0)
+++ src/platform/linux/common.h	(revision 0)
@@ -0,0 +1,22 @@
+// common.h -- Defines typedefs and some global functions.
+//             From JamesM's kernel development tutorials.
+
+#ifndef COMMON_H
+#define COMMON_H
+
+#include "multiboot.h"
+
+// Some nice typedefs, to standardise sizes across platforms.
+// These typedefs are written for 32-bit X86.
+typedef unsigned int   u32int;
+typedef          int   s32int;
+typedef unsigned short u16int;
+typedef          short s16int;
+typedef unsigned char  u8int;
+typedef          char  s8int;
+
+void outb(u16int port, u8int value);
+u8int inb(u16int port);
+u16int inw(u16int port);
+
+#endif // COMMON_H

Property changes on: src/platform/linux/common.h
___________________________________________________________________
Added: svn:eol-style
   + native

Index: src/platform/linux/isr.c
===================================================================
--- src/platform/linux/isr.c	(revision 0)
+++ src/platform/linux/isr.c	(revision 0)
@@ -0,0 +1,58 @@
+//
+// isr.c -- High level interrupt service routines and interrupt request handlers.
+//          Part of this code is modified from Bran's kernel development tutorials.
+//          Rewritten for JamesM's kernel development tutorials.
+//
+
+#include "common.h"
+#include "isr.h"
+#include "monitor.h"
+
+#if 0
+isr_t interrupt_handlers[256];
+extern void monitor_write_dec(u32int n);
+#endif
+
+void register_interrupt_handler(u8int n, isr_t handler)
+{
+#if 0
+    interrupt_handlers[n] = handler;
+#endif
+}
+
+#if 0
+// This gets called from our ASM interrupt handler stub.
+void isr_handler(registers_t regs)
+{
+    monitor_write("recieved interrupt: ");
+    monitor_write_dec(regs.int_no);
+    monitor_put('\n');
+
+    if (interrupt_handlers[regs.int_no] != 0)
+    {
+        isr_t handler = interrupt_handlers[regs.int_no];
+        handler(regs);
+    }
+}
+
+// This gets called from our ASM interrupt handler stub.
+void irq_handler(registers_t regs)
+{
+    // Send an EOI (end of interrupt) signal to the PICs.
+    // If this interrupt involved the slave.
+    if (regs.int_no >= 40)
+    {
+        // Send reset signal to slave.
+        outb(0xA0, 0x20);
+    }
+    // Send reset signal to master. (As well as slave, if necessary).
+    outb(0x20, 0x20);
+
+    if (interrupt_handlers[regs.int_no] != 0)
+    {
+        isr_t handler = interrupt_handlers[regs.int_no];
+        handler(regs);
+    }
+
+}
+#endif

Property changes on: src/platform/linux/isr.c
___________________________________________________________________
Added: svn:eol-style
   + native

Index: src/platform/linux/stacks.h
===================================================================
--- src/platform/linux/stacks.h	(revision 0)
+++ src/platform/linux/stacks.h	(revision 0)
@@ -0,0 +1,9 @@
+// Stack size definitions
+
+#ifndef __STACKS_H__
+#define __STACKS_H__
+
+#define  STACK_SIZE_TOTAL 32768
+
+#endif
+

Property changes on: src/platform/linux/stacks.h
___________________________________________________________________
Added: svn:eol-style
   + native

Index: SConstruct
===================================================================
--- SConstruct	(revision 282)
+++ SConstruct	(working copy)
@@ -57,6 +57,7 @@
   'lm3s' : { 'cpus' : [ 'LM3S8962', 'LM3S6965', 'LM3S6918' ], 'toolchains' : [ 'arm-gcc', 'codesourcery', 'devkitarm', 'arm-eabi-gcc' ] },
   'str9' : { 'cpus' : [ 'STR912FAW44' ], 'toolchains' : [ 'arm-gcc', 'codesourcery', 'devkitarm', 'arm-eabi-gcc' ] },
   'i386' : { 'cpus' : [ 'I386' ], 'toolchains' : [ 'i686-gcc' ] },
+  'linux' : { 'cpus' : [ 'LINUX' ], 'toolchains' : [ 'i686-gcc' ] },
   'lpc288x' : { 'cpus' : [ 'LPC2888' ], 'toolchains' : [ 'arm-gcc', 'codesourcery', 'devkitarm', 'arm-eabi-gcc' ] },
   'str7' : { 'cpus' : [ 'STR711FR2' ], 'toolchains' : [ 'arm-gcc', 'codesourcery', 'devkitarm', 'arm-eabi-gcc' ] },
   'stm32' : { 'cpus' : [ 'STM32F103ZE', 'STM32F103RE' ], 'toolchains' : [ 'arm-gcc', 'codesourcery', 'devkitarm', 'arm-eabi-gcc' ] },
@@ -69,6 +70,7 @@
                'EK-LM3S6965' : [ 'LM3S6965' ],
                'STR9-COMSTICK' : [ 'STR912FAW44' ],
                'PC' : [ 'I386' ],
+               'LINUX' : [ 'LINUX' ],
                'LPC-H2888' : [ 'LPC2888' ],
                'MOD711' : [ 'STR711FR2' ],
                'STM3210E-EVAL' : [ 'STM32F103ZE' ],
@@ -104,6 +106,7 @@
               'EK-LM3S6965' : [ 'bisect', 'hangman', 'lhttpd', 'pong', 'led', 'piano', 'pwmled', 'tvbgone', 'hello', 'info', 'morse', 'adcscope','adcpoll' ],
               'STR9-COMSTICK' : [ 'bisect', 'hangman', 'led', 'hello', 'info' ],
               'PC' : [ 'bisect', 'hello', 'info', 'life', 'hangman' ],
+              'LINUX' : [ 'bisect', 'hello', 'info', 'life', 'hangman' ],
               'LPC-H2888' : [ 'bisect', 'hangman', 'led', 'hello', 'info' ],
               'MOD711' : [ 'bisect', 'hangman', 'led', 'hello', 'info', 'dualpwm' ],
               'STM3210E-EVAL' : [ 'bisect', 'hello', 'info' ],
