can read character from keyboard now

This commit is contained in:
2024-12-04 17:17:53 +09:00
parent f18775bfdd
commit 4580d576a8
25 changed files with 729 additions and 371 deletions

View File

@@ -1,19 +1,25 @@
include ../*.inc
SDIR ?= ../
BDIR ?= ./
PROG=boot
CSRCS= $(wildcard *.c)
SSRCS= $(wildcard *.S)
OBJS = $(SSRCS:.S=.o) $(CSRCS:.c=.o)
PROG = boot
SRCS = srt0.S gdt.S boot.c
OBJS = srt0.o gdt.o boot.o
CFLAGS+=-c -fno-pie
CPPFLAGS+=-nostdinc -DLOADADDR=$(LOADADDR) -DLINKADDR=$(LINKADDR) -DBOOTMAGIC=$(BOOTMAGIC)
LDFLAGS+= -s -T ld.script -Ttext=$(LINKADDR) --no-omagic -M
ESRCS = console.c print.c a20.c
OBJS += $(ESRCS:.c=.o)
include $(SDIR)/Makefile.inc
CFLAGS += -no-pie
CPPFLAGS += -DLOADADDR=$(LOADADDR) -DLINKADDR=$(LINKADDR) -DBOOTMAGIC=$(BOOTMAGIC) -DBOOTSTACKOFF=$(BOOTSTACKOFF)
CPPFLAGS += -I $(SDIR)
LDFLAGS += -s -Ttext=$(LINKADDR) -T ld.script --no-omagic -M
${PROG}: $(OBJS)
@rm -f $(PROG)
$(LD) $(LDFLAGS) -o $(BDIR)/$(PROG) $(OBJS)
$(OBJS): conf.h pio.h
$(OBJS): $(SDIR)/u.h def.h dat.h fn.h
clean:
rm -f $(PROG) $(PROG).bin *.o
rm -f $(PROG) $(OBJS)

View File

@@ -1,18 +1,7 @@
#define elem(x) (sizeof(x)/sizeof((x)[0]))
#include <u.h>
#include "fn.h"
// IO Port Access Type Purpose
// 0x60 Read/Write Data Port
// 0x64 Read Status Register
// 0x64 Write Command Register
typedef struct{
char *name;
void (**probes)(void);
int cnt;
}BootProbe;
// for high memory
static void
void
a20up(void)
{
struct{
@@ -43,25 +32,4 @@ a20up(void)
;
while(inb(i8042.sport) & i8042.dib)
inb(i8042.dport);
}
static void (*probe1[])(void) = {
a20up,
};
static void (*probe2[])(void) = {
};
static BootProbe probes[] = {
{"probing", probe1, elem(probe1) },
{"disk", probe2, elem(probe2) },
};
static void
machdep(void)
{
for(int i = 0; i < elem(probes); ++i){
BootProbe bp = probes[i];
for(int j = 0; j < bp.cnt; ++j)
bp.probes[j]();
}
}
}

View File

@@ -1,50 +1,58 @@
#include <u.h>
#include "dat.h"
#include "fn.h"
typedef unsigned short u16;
typedef unsigned char u8;
typedef int dev_t;
#include "pio.h"
#include "conf.h"
void (*probe1[])(void) = {
a20up,
};
void (*probe2[])(void) = {
};
#define VGA_WIDTH 80
#define VGA_LENGTH 25
BootProbe probes[] = {
{"probing", probe1, elem(probe1) },
{"disk", probe2, elem(probe2) },
};
char*
memcpy(char *a, char *b, int l)
ConDev condev = {
.getc = pcgetc,
.putc = pcputc,
};
// https://wiki.osdev.org/BIOS
void
machdep(void)
{
for(int i = 0; i < l; ++i)
a[i] = b[i];
return a;
for(int i = 0; i < elem(probes); ++i){
BootProbe bp = probes[i];
for(int j = 0; j < bp.cnt; ++j)
bp.probes[j]();
}
}
int
strlen(char *s)
static void
puts(char *s)
{
int i = 0;
for(; s[i]; ++i)
;
return i;
}
char*
itostr(int n, char *s)
{
char buf[16];
char *p = buf;
do {
*p++ = n%16;
}while((n/=16) != 0);
while(p > buf){
*s++ = "0123456789abcdef"[(int)*--p];
}
return s;
for(;*s;++s)
putchar(*s);
}
void
boot(dev_t bootdev)
boot(int bootdev)
{
machdep();
for(;;);
char buf[8192];
machdep();
putchar('\n');
for(;;){
int i=0, c=0;
puts("\nboot >> ");
do{
c = getchar();
buf[i++] = c;
}while(c != '\n' && i < sizeof(buf) - 1);
buf[i-1] = 0;
puts(buf);
}
}

26
boot/console.c Normal file
View File

@@ -0,0 +1,26 @@
#include <u.h>
#include "fn.h"
// https://stanislavs.org/helppc/int_16.html
void
pcputc(int dev, int c)
{
__asm volatile("int $0x30" : : "a" (c | 0xe00), "b" (1) : "%ecx", "%edx", "cc" );
}
int
pcgetc(int dev)
{
register int rv;
// wait for available
do{
__asm volatile("int $0x36; setnz %b0" : "=a" (rv) :
"0" (0x100) : "%ecx", "%edx", "cc" );
}while((rv & 0xff) == 0);
__asm volatile("int $0x36" : "=a" (rv) :
"0" (0x000) : "%ecx", "%edx", "cc" );
return rv&0xff;
}

38
boot/dat.h Normal file
View File

@@ -0,0 +1,38 @@
// IO Port Access Type Purpose
// 0x60 Read/Write Data Port
// 0x64 Read Status Register
// 0x64 Write Command Register
struct BIOSreg{
u32 ax;
u32 cx;
u32 dx;
u32 bx;
u32 bp;
u32 si;
u32 di;
u32 ds;
u32 es;
}__attribute__((packed));
typedef struct{
char *name;
void (**probes)(void);
int cnt;
}BootProbe;
typedef struct{
int (*getc)(int);
void (*putc)(int, int);
int dev;
}ConDev;
// gdt.S
extern volatile struct BIOSreg BIOSreg;
// boot.c
extern void (*probe1[])(void);
extern void (*probe2[])(void);
extern BootProbe probes[];
extern ConDev condev;

47
boot/def.h Normal file
View File

@@ -0,0 +1,47 @@
// Trap
#define T_PRIVINFLT 0 /* privileged instruction */
#define T_BPTFLT 1 /* breakpoint trap */
#define T_ARITHTRAP 2 /* arithmetic trap */
#define T_RESERVED 3 /* reserved fault base */
#define T_PROTFLT 4 /* protection fault */
#define T_TRCTRAP 5 /* trace trap */
#define T_PAGEFLT 6 /* page fault */
#define T_ALIGNFLT 7 /* alignment fault */
#define T_DIVIDE 8 /* integer divide fault */
#define T_NMI 9 /* non-maskable interrupt */
#define T_OFLOW 10 /* overflow trap */
#define T_BOUND 11 /* bounds check fault */
#define T_DNA 12 /* device not available fault */
#define T_DOUBLEFLT 13 /* double fault */
#define T_FPOPFLT 14 /* fp coprocessor operand fetch fault (![P]Pro)*/
#define T_TSSFLT 15 /* invalid tss fault */
#define T_SEGNPFLT 16 /* segment not present fault */
#define T_STKFLT 17 /* stack fault */
#define T_MACHK 18 /* machine check ([P]Pro) */
#define T_XFTRAP 19 /* SIMD FP exception */
/* memory segment types */
#define SDT_MEMRO 16 /* memory read only */
#define SDT_MEMROA 17 /* memory read only accessed */
#define SDT_MEMRW 18 /* memory read write */
#define SDT_MEMRWA 19 /* memory read write accessed */
#define SDT_MEMROD 20 /* memory read only expand dwn limit */
#define SDT_MEMRODA 21 /* memory read only expand dwn limit accessed */
#define SDT_MEMRWD 22 /* memory read write expand dwn limit */
#define SDT_MEMRWDA 23 /* memory read write expand dwn limit acessed */
#define SDT_MEME 24 /* memory execute only */
#define SDT_MEMEA 25 /* memory execute only accessed */
#define SDT_MEMER 26 /* memory execute read */
#define SDT_MEMERA 27 /* memory execute read accessed */
#define SDT_MEMEC 28 /* memory execute only conforming */
#define SDT_MEMEAC 29 /* memory execute only accessed conforming */
#define SDT_MEMERC 30 /* memory execute read conforming */
#define SDT_MEMERAC 31 /* memory execute read accessed conforming */
#define S16TEXT 0x18 // segment selector of text section
#define S16DATA 0x20
#define S32TEXT 0x08 // segment selector of text section
#define S32DATA 0x10
#define SDT_SYS386TGT 15 /* system 386 trap gate */
#define CR0_PE 0x01 // protected mode enable

View File

@@ -1,3 +1,15 @@
// console.c
int pcgetc(int dev);
void pcputc(int dev, int c);
// print.c
void putchar(int c);
int getchar(void);
// a20.c
void a20up(void);
static __inline void
outb(int port, u8 data)
{
@@ -11,4 +23,4 @@ inb(int port)
__asm volatile("inb %w1,%0" : "=a" (data) : "d" (port));
return data;
};
}

View File

@@ -1,71 +1,95 @@
.file "gdt.S"
// Trap
#define T_PRIVINFLT 0 /* privileged instruction */
#define T_BPTFLT 1 /* breakpoint trap */
#define T_ARITHTRAP 2 /* arithmetic trap */
#define T_RESERVED 3 /* reserved fault base */
#define T_PROTFLT 4 /* protection fault */
#define T_TRCTRAP 5 /* trace trap */
#define T_PAGEFLT 6 /* page fault */
#define T_ALIGNFLT 7 /* alignment fault */
#define T_DIVIDE 8 /* integer divide fault */
#define T_NMI 9 /* non-maskable interrupt */
#define T_OFLOW 10 /* overflow trap */
#define T_BOUND 11 /* bounds check fault */
#define T_DNA 12 /* device not available fault */
#define T_DOUBLEFLT 13 /* double fault */
#define T_FPOPFLT 14 /* fp coprocessor operand fetch fault (![P]Pro)*/
#define T_TSSFLT 15 /* invalid tss fault */
#define T_SEGNPFLT 16 /* segment not present fault */
#define T_STKFLT 17 /* stack fault */
#define T_MACHK 18 /* machine check ([P]Pro) */
#define T_XFTRAP 19 /* SIMD FP exception */
#include "def.h"
/* memory segment types */
#define SDT_MEMRO 16 /* memory read only */
#define SDT_MEMROA 17 /* memory read only accessed */
#define SDT_MEMRW 18 /* memory read write */
#define SDT_MEMRWA 19 /* memory read write accessed */
#define SDT_MEMROD 20 /* memory read only expand dwn limit */
#define SDT_MEMRODA 21 /* memory read only expand dwn limit accessed */
#define SDT_MEMRWD 22 /* memory read write expand dwn limit */
#define SDT_MEMRWDA 23 /* memory read write expand dwn limit acessed */
#define SDT_MEME 24 /* memory execute only */
#define SDT_MEMEA 25 /* memory execute only accessed */
#define SDT_MEMER 26 /* memory execute read */
#define SDT_MEMERA 27 /* memory execute read accessed */
#define SDT_MEMEC 28 /* memory execute only conforming */
#define SDT_MEMEAC 29 /* memory execute only accessed conforming */
#define SDT_MEMERC 30 /* memory execute read conforming */
#define SDT_MEMERAC 31 /* memory execute read accessed conforming */
#define GEN_LABEL(n) X##n
#define S32TEXT 0x08 // segment selector of text section
#define SDT_SYS386TGT 15 /* system 386 trap gate */
// idt entry
#define idte(e) \
movl $GEN_LABEL(e), %eax ; \
call entry
#define IPROC(n) X##n
#define idte(e) \
movl $IPROC(e), %eax ; call entry_idt
// idt bios entry
#define idtbe(b) idte(emu##b)
#define IENTRY_ERR(name,err) \
IPROC(name): \
pushl $err ; \
jmp 1f
#define GEN_TRAP(name, err) \
GEN_LABEL(name): \
pushl $err; \
jmp 1f
#define GEN_EMU(n) \
GEN_LABEL(emu##n): \
pushl $n; \
jmp 1f
#define prot2real \
ljmp $S16TEXT, $1f - LINKADDR; \
1: \
.code16; \
movw $S16DATA, %ax; \
movw %ax, %ds; \
movw %ax, %es; \
\
movl %cr0, %eax; \
andl $~CR0_PE, %eax; \
movl %eax, %cr0; \
\
data32 ljmp $(LINKADDR >> 4), $1f - LINKADDR; \
1: \
movw %cs, %ax; \
movw %ax, %ds; \
movw %ax, %es; \
xorw %ax, %ax; \
movw %ax, %ss; \
data32 addr32 lidt (Idtr_real - LINKADDR);
#define real2prot \
movw $LINKADDR >> 4, %ax; \
movw %ax, %ds; \
data32 addr32 lgdt (Gdtr - LINKADDR); \
\
movl %cr0, %eax; \
orl $CR0_PE, %eax; \
movl %eax, %cr0; \
\
data32 ljmp $S32TEXT, $1f; \
1: \
.code32; \
mov $S32DATA, %eax; \
mov %ax, %ds; \
mov %ax, %ss; \
mov %ax, %es; \
\
lidt Idtr;
.text
.globl BIOSreg
BIOSreg:
BIOS_AX: .long 0
BIOS_CX: .long 0
BIOS_DX: .long 0
BIOS_BX: .long 0
BIOS_BP: .long 0
BIOS_SI: .long 0
BIOS_DI: .long 0
BIOS_DS: .long 0
BIOS_ES: .long 0
.text
.code32
.globl pmm_init
.globl pmode_init
entry_idt:
// Table
// IDTR offset + 0 : entry 0
// IDTR offset + 8 : entry 1
//
// IDTR offset + 0 : entry 0
// IDTR offset + 8 : entry 1
//
// Gate Descriptor
// 63 ~ 48 : offset low
// 47 ~ 32 : info
// 31 ~ 16 : segment selector
// 15 ~ 0 : offset high
// 63 ~ 48 : offset low
// 47 ~ 32 : info
// 31 ~ 16 : segment selector
// 15 ~ 0 : offset high
entry:
movw %ax, (%ebx)
movw $S32TEXT, 2(%ebx)
movw $((0x80|SDT_SYS386TGT) << 8), 4(%ebx)
@@ -74,8 +98,9 @@ entry_idt:
addl $8, %ebx
ret
// init IDT for protected mode
.align 8, 0x90
pmm_init:
pmode_init:
movl $idt, %ebx
movl $Idtr, %eax
movw $(640 - 1), (%eax)
@@ -88,6 +113,15 @@ pmm_init:
idte(xx); idte(xx); idte(xx); idte(xx); idte(xx); idte(xx)
idte(xx); idte(xx); idte(xx); idte(xx); idte(xx); idte(xx)
idte(xx)
/* BIOS interrupt call (32-63) */
idtbe(0); idtbe(1); idtbe(2); idtbe(3); idtbe(4); idtbe(5)
idtbe(6); idtbe(7); idtbe(8); idtbe(9); idtbe(10); idtbe(11)
idtbe(12); idtbe(13); idtbe(14); idtbe(15); idtbe(16); idtbe(17)
idtbe(18); idtbe(19); idtbe(20); idtbe(21); idtbe(22); idtbe(23)
idtbe(24); idtbe(25); idtbe(26); idtbe(27); idtbe(28); idtbe(29)
idtbe(30); idtbe(31); idtbe(32); idtbe(33); idtbe(34); idtbe(35)
idtbe(36); idtbe(37); idtbe(38); idtbe(39); idtbe(40); idtbe(41)
idtbe(42); idtbe(43); idtbe(44); idtbe(45); idtbe(46); idtbe(47)
lidt Idtr
ret
@@ -105,86 +139,204 @@ Idtr:
.text
.align 8
gdt:
/* 0x00 : null */
.space 8
/* 0x08 : flat code */
.word 0xFFFF # lolimit
.word 0 # lobase
.byte 0 # midbase
.byte SDT_MEMERAC | 0 | 0x80 # RXAC, dpl = 0, present
.byte 0xf | 0 | 0x40 | 0x80 # hilimit, xx, 32bit, 4k granularity
.byte 0 # hibase
/* 0x10 : flat data */
.word 0xFFFF # lolimit
.word 0 # lobase
.byte 0 # midbase
.byte SDT_MEMRWA | 0 | 0x80 # RWA, dpl = 0, present
.byte 0xf | 0 | 0x40 | 0x80 # hilimit, xx, 32bit, 4k granularity
.byte 0 # hibase
/* 0x18 : 16 bit code */
.word 0xFFFF # lolimit
.word (LINKADDR & 0xffff) # lobase
.byte (LINKADDR >> 16) & 0xff # midbase
.byte SDT_MEMERAC | 0 | 0x80 # RXAC, dpl = 0, present
.byte 0x0 | 0 | 0 | 0 # hilimit, xx, 16bit, byte granularity
.byte (LINKADDR >> 20) & 0xff # hibase
/* 0x20 : 16 bit data */
.word 0xFFFF # lolimit
.word (LINKADDR & 0xffff) # lobase
.byte (LINKADDR >> 16) & 0xff # midbase
.byte SDT_MEMRWA | 0 | 0x80 # RWA, dpl = 0, present
.byte 0x0 | 0 | 0 | 0 # hilimit, xx, 16bit, byte granularity
.byte (LINKADDR >> 20) & 0xff # hibase
.globl Idtr_real
Idtr_real:
.word 1023 // 256 entry, 1k
.long 0
.word 0
.align 8
gdt:
/* 0x00 : null */
.space 8
/* 0x08 : flat code */
.word 0xFFFF // lolimit
.word 0 // lobase
.byte 0 // midbase
.byte SDT_MEMERAC | 0 | 0x80 // RXAC, dpl = 0, present
.byte 0xf | 0 | 0x40 | 0x80 // hilimit, xx, 32bit, 4k granularity
.byte 0 // hibase
/* 0x10 : flat data */
.word 0xFFFF // lolimit
.word 0 // lobase
.byte 0 // midbase
.byte SDT_MEMRWA | 0 | 0x80 // RWA, dpl = 0, present
.byte 0xf | 0 | 0x40 | 0x80 // hilimit, xx, 32bit, 4k granularity
.byte 0 // hibase
/* 0x18 : 16 bit code */
.word 0xFFFF // lolimit
.word (LINKADDR & 0xffff) // lobase
.byte (LINKADDR >> 16) & 0xff // midbase
.byte SDT_MEMERAC | 0 | 0x80 // RXAC, dpl = 0, present
.byte 0x0 | 0 | 0 | 0 // hilimit, xx, 16bit, byte granularity
.byte (LINKADDR >> 20) & 0xff // hibase
/* 0x20 : 16 bit data */
.word 0xFFFF // lolimit
.word (LINKADDR & 0xffff) // lobase
.byte (LINKADDR >> 16) & 0xff // midbase
.byte SDT_MEMRWA | 0 | 0x80 // RWA, dpl = 0, present
.byte 0x0 | 0 | 0 | 0 // hilimit, xx, 16bit, byte granularity
.byte (LINKADDR >> 20) & 0xff // hibase
// Register GDT
.globl Gdtr
Gdtr:
.word . - gdt -1
.word . - gdt - 1
.long gdt
.word 0
// ENTRY Reserved
IPROC(xx):
GEN_LABEL(xx):
pushl $1
pushl $T_RESERVED
jmp 1f
// trap entry points
IENTRY_ERR(de,T_DIVIDE) /* #DE divide by zero */
IENTRY_ERR(db,T_TRCTRAP) /* #DB debug */
IENTRY_ERR(nmi,T_NMI) /* NMI */
IENTRY_ERR(bp,T_BPTFLT) /* #BP breakpoint */
IENTRY_ERR(of,T_OFLOW) /* #OF overflow */
IENTRY_ERR(br,T_BOUND) /* #BR BOUND range exceeded */
IENTRY_ERR(ud,T_PRIVINFLT) /* #UD invalid opcode */
IENTRY_ERR(nm,T_DNA) /* #NM device not available */
IENTRY_ERR(df,T_DOUBLEFLT) /* #DF double fault */
IENTRY_ERR(fo,T_FPOPFLT) /* #FO coprocessor segment overrun */
IENTRY_ERR(ts,T_TSSFLT) /* #TS invalid TSS */
IENTRY_ERR(np,T_SEGNPFLT) /* #NP segment not present */
IENTRY_ERR(ss,T_STKFLT) /* #SS stack fault */
IENTRY_ERR(gp,T_PROTFLT) /* #GP general protection */
IENTRY_ERR(pf,T_PAGEFLT) /* #PF page fault */
IENTRY_ERR(mf,T_ARITHTRAP) /* #MF floating point error */
IENTRY_ERR(ac,T_ALIGNFLT) /* #AC alignment check */
IENTRY_ERR(mc,T_MACHK) /* #MC machine check */
GEN_TRAP(de,T_DIVIDE) /* DE divide by zero */
GEN_TRAP(db,T_TRCTRAP) /* DB debug */
GEN_TRAP(nmi,T_NMI) /* NMI */
GEN_TRAP(bp,T_BPTFLT) /* BP breakpoint */
GEN_TRAP(of,T_OFLOW) /* OF overflow */
GEN_TRAP(br,T_BOUND) /* BR BOUND range exceeded */
GEN_TRAP(ud,T_PRIVINFLT) /* UD invalid opcode */
GEN_TRAP(nm,T_DNA) /* NM device not available */
GEN_TRAP(df,T_DOUBLEFLT) /* DF double fault */
GEN_TRAP(fo,T_FPOPFLT) /* FO coprocessor segment overrun */
GEN_TRAP(ts,T_TSSFLT) /* TS invalid TSS */
GEN_TRAP(np,T_SEGNPFLT) /* NP segment not present */
GEN_TRAP(ss,T_STKFLT) /* SS stack fault */
GEN_TRAP(gp,T_PROTFLT) /* GP general protection */
GEN_TRAP(pf,T_PAGEFLT) /* PF page fault */
GEN_TRAP(mf,T_ARITHTRAP) /* MF floating point error */
GEN_TRAP(ac,T_ALIGNFLT) /* AC alignment check */
GEN_TRAP(mc,T_MACHK) /* MC machine check */
1:
jmp alltraps
// in boot mode don't want handle trap
alltraps:
popl %ecx // what trap
hlt
iret
jmp 1b
GEN_EMU(0); GEN_EMU(1); GEN_EMU(2); GEN_EMU(3)
GEN_EMU(4); GEN_EMU(5); GEN_EMU(6); GEN_EMU(7)
GEN_EMU(8); GEN_EMU(9); GEN_EMU(10); GEN_EMU(11)
GEN_EMU(12); GEN_EMU(13); GEN_EMU(14); GEN_EMU(15)
GEN_EMU(16); GEN_EMU(17); GEN_EMU(18); GEN_EMU(19)
GEN_EMU(20); GEN_EMU(21); GEN_EMU(22); GEN_EMU(23)
GEN_EMU(24); GEN_EMU(25); GEN_EMU(26); GEN_EMU(27)
GEN_EMU(28); GEN_EMU(29); GEN_EMU(30); GEN_EMU(31)
GEN_EMU(32); GEN_EMU(33); GEN_EMU(34); GEN_EMU(35)
GEN_EMU(36); GEN_EMU(37); GEN_EMU(38); GEN_EMU(39)
GEN_EMU(40); GEN_EMU(41); GEN_EMU(42); GEN_EMU(43)
GEN_EMU(44); GEN_EMU(45); GEN_EMU(46); GEN_EMU(47)
1: jmp EMUh
// bios interrupt entry point
// switch to real to protected mode and emulate 16bit mode
// switch to real to protected mode and emulate 16bit mode
.globl EMUh
.align 8, 0x90
EMUh:
pushl %eax
EMUh: // build stack for real mode
mov %eax, 5f // save number to code segment not in the data segment
pop %eax
.end
pusha
push %ds
push %es
push %fs
push %gs
movb %al, intno // save BIOS int vector
// BIOS_regs is area for saving the contents of registers returned by the BIOS during a BIOS CALL
movl BIOS_ES, %eax
movl $0x00, %eax
mov %eax, 7f
movl BIOS_DS, %eax
movl $0x00, %eax
mov %eax, 6f
prot2real
// save ds to stack and rewrite es, ds
push %ds
// data32 movl $Leax, %eax
.byte 0x66, 0xb8
7: .long 0x90909090
mov %ax, %es
// data32 movl $Leax, %eax
.byte 0x66, 0xb8
6: .long 0x90909090
mov %ax, %ds
// data32 movl $Leax, %eax => now ax is holding interrupt nummber
.byte 0x66, 0xb8
5: .long 0x90909090
;sti
int $0 // do interrupt
intno = . -1;
cli;
// restore register
// preserve bx,es for protected mode
pop %ds
addr32 movl %eax, (2f - LINKADDR)
movl %ebx, %eax
addr32 movl %eax, (4f - LINKADDR)
movl %es, %eax
addr32 movl %eax, (3f- LINKADDR)
addr32 movl (2f - LINKADDR), %eax
// save eflags to bh
movb %ah, %bh
lahf
xchgb %ah, %bh
// preserve ax for protected mode
addr32 movl %eax, (2f - LINKADDR)
real2prot
// movl $Leax, %eax
.byte 0xb8
4: .long 0x90909090
mov %eax, BIOS_BX
// movl $Leax, %eax
.byte 0xb8
3: .long 0x90909090
mov %eax, BIOS_ES
// movl $Leax, %eax
.byte 0xb8
2: .long 0x90909090
// pass BIOS return values back to caller
movl %eax, 0xb*4(%esp)
movl %ecx, 0xa*4(%esp)
movl %edx, 0x9*4(%esp)
movb %bh, 0xe*4(%esp) // restore eflags
// save register into BIOSREG
.code32
movl %eax, BIOS_AX
movl %ecx, BIOS_CX
movl %edx, BIOS_DX
movl %ebp, BIOS_BP
movl %esi, BIOS_SI
movl %edi, BIOS_DI
// clear NT(Nested Task Flag: 14) flag in eflag
// if 1 : interrupting
pushf
pop %eax
and $0xffffbfff, %eax
push %eax
popf
pop %ds
pop %es
pop %fs
pop %gs
popa
iret

View File

@@ -1,27 +1,54 @@
OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
OUTPUT_ARCH(i386)
PHDRS
PHDRS
{
text PT_LOAD;
}
SECTIONS
{
.text : {
KEEP(srt0.o(.text))
*(.text)
} :text
etext = .;
.data : { *(.data) } :text
.rodata : { *(.rodata) } :text
edata = .;
.bss : { *(.bss) } :text
ebss = .;
end = .;
/DISCARD/ :
.text :
{
start = . ;
_start = . ;
__start = . ;
*(.text)
etext = . ;
} :text
.data :
{
__data_start__ = . ;
*(.data)
__data_end__ = . ;
__rdata_start__ = . ;
*(.rdata)
__rdata_end__ = . ;
*(.pdata)
*(.edata)
} :text
.bss :
{
edata = . ;
_edata = . ;
__edata = . ;
__bss_start__ = . ;
*(.bss)
__common_start__ = . ;
*(COMMON)
__bss_end__ = . ;
end = . ;
_end = . ;
__end = . ;
} :text
.stab :
{
*(.stab)
}
.stabstr :
{
*(.stabstr)
} :text
/DISCARD/ :
{
*(.note.gnu.property)
*(.comment)
}
}

70
boot/print.c Normal file
View File

@@ -0,0 +1,70 @@
#include <u.h>
#include "dat.h"
#include "fn.h"
#define TABWIDTH 8
#define DEL '\177'
static void conputc(int c);
static int congetc(void);
static int pos = 0;
int
getchar(void)
{
int c;
c = congetc();
if( c == '\r')
c = '\n';
if((c < ' ' && c != '\n') || c == DEL)
return c;
putchar(c);
return c;
}
void
putchar(int c)
{
switch(c){
case DEL:
conputc('\b');
conputc(' ');
case '\b':
conputc('\b');
if(pos)
--pos;
break;
case '\t':
do{
conputc(' ');
}while(++pos % TABWIDTH);
break;
case '\n':
case '\r':
conputc(c);
pos = 0;
break;
default:
conputc(c);
++pos;
break;
}
}
static void
conputc(int c)
{
if(c){
condev.putc(condev.dev, c);
if(c == '\n')
condev.putc(condev.dev, '\r');
}
}
static int
congetc(void)
{
return condev.getc(condev.dev);
}

View File

@@ -1,13 +1,12 @@
.file "srt0.S"
#define BOOTSTACK 0xfffc
#define CR0_PE 0x00000001 /* Protected mode Enable */
#include "def.h"
.globl end
.globl edata
.globl Gdtr
.globl boot
.globl pmm_init
.globl pmode_init
.text
.code16
@@ -20,14 +19,16 @@ _start:
1:
popl %edx
// load GDT
cli
pushl %cs
popl %ds
addr32 data32 lgdt (Gdtr - LINKADDR)
movl %cr0, %eax
// enable protected mode
orl $CR0_PE, %eax
data32 movl %eax, %cr0
data32 ljmp $8, $1f
data32 ljmp $S32TEXT, $1f
1:
.code32
@@ -37,7 +38,7 @@ _start:
mov %ax, %es
mov %ax, %fs
mov %ax, %gs
movl $BOOTSTACK, %esp
movl $BOOTSTACKOFF, %esp
pushl %edx
// fill 0 .bss
@@ -48,5 +49,5 @@ _start:
cld
rep; stosb
call pmm_init
call pmode_init
call boot