can read character from keyboard now
This commit is contained in:
parent
f18775bfdd
commit
4580d576a8
3
Makefile
3
Makefile
@ -2,6 +2,7 @@ BDIR = build
|
||||
SUBDIRS = biosboot boot mbr installboot installmbr
|
||||
|
||||
all: $(BDIR) $(SUBDIRS)
|
||||
cp installboot/filecopy.sh $(BDIR)/
|
||||
|
||||
$(BDIR):
|
||||
mkdir -p $(BDIR)
|
||||
@ -10,6 +11,6 @@ clean: $(SUBDIRS)
|
||||
rm -rf $(BDIR)
|
||||
|
||||
$(SUBDIRS):
|
||||
@make -sC $@ $(MAKECMDGOALS) BDIR=$(PWD)/$(BDIR) IDIR=$(PWD)
|
||||
@make -C $@ $(MAKECMDGOALS) BDIR=$(PWD)/$(BDIR) SDIR=$(PWD)
|
||||
|
||||
.PHONY: biosboot boot installboot mbr installmbr
|
||||
|
||||
15
Makefile.inc
15
Makefile.inc
@ -1,13 +1,14 @@
|
||||
|
||||
LINKADDR = 0x40120
|
||||
LOADADDR = 0x40000
|
||||
BOOTMAGIC = 0xc001d00d
|
||||
BOOTREL = 0x60000
|
||||
BOOTSEG = 0x7c0
|
||||
BOOTRELOCSEG = 0x7a0
|
||||
MBRSTACKOFF = 0xfffc
|
||||
BOOTSTACKOFF = 0xfffc
|
||||
|
||||
CC=cc
|
||||
CFLAGS=-m32 -Wall -Werror -march=i386 -O0 -fno-stack-protector -ffreestanding -fno-builtin
|
||||
#CFLAGS=-m32 -march=i386 -O0 -fno-stack-protector -ffreestanding -fno-builtin
|
||||
CFLAGS= -m32 -march=i386 -Wall -Werror -march=i386 -O0 -fno-stack-protector -ffreestanding -fno-builtin -fno-builtin-function -fno-gnu-unique
|
||||
CPPFLAGS=-nostdinc
|
||||
LD=ld
|
||||
AS=as
|
||||
ASFLAGS=-Wa,-O0,--32
|
||||
LDFLAGS=-melf_i386 -O0 -nostdlib -x -N -Bstatic -znorelro -no-pie
|
||||
ASFLAGS=-Wa,--32,-O0
|
||||
LDFLAGS=-O0 -melf_i386 -nostdlib -x -N -Bstatic -znorelro -no-pie
|
||||
|
||||
@ -1,18 +1,20 @@
|
||||
include ../*.inc
|
||||
SDIR ?= ../
|
||||
BDIR ?= ./
|
||||
|
||||
PROG=biosboot
|
||||
SRCS=$(wildcard *.S)
|
||||
OBJS=$(SRCS:.S=.o)
|
||||
PROG = biosboot
|
||||
SRCS = biosboot.S
|
||||
OBJS = biosboot.o
|
||||
|
||||
CFLAGS+=-c -fno-pie
|
||||
LDFLAGS+=-Ttext 0 -T ld.script
|
||||
CPPFLAGS+=-nostdinc -DLOADADDR=$(LOADADDR) -DLINKADDR=$(LINKADDR) -DBOOTMAGIC=$(BOOTMAGIC)
|
||||
CPPFLAGS+=-I $(IDIR)
|
||||
include $(SDIR)/Makefile.inc
|
||||
|
||||
CFLAGS += -c -fno-pie
|
||||
LDFLAGS += -Ttext 0 -T ld.script
|
||||
CPPFLAGS += -DLOADADDR=$(LOADADDR) -DLINKADDR=$(LINKADDR) -DBOOTMAGIC=$(BOOTMAGIC) -DBOOTSEG=$(BOOTSEG)
|
||||
|
||||
$(PROG): $(OBJS)
|
||||
$(LD) $(LDFLAGS) -o $(BDIR)/$(PROG) $(OBJS)
|
||||
|
||||
$(OBJS): ../def.h
|
||||
$(OBJS): $(SDIR)/Makefile.inc
|
||||
|
||||
clean:
|
||||
rm -f $(PROG) $(OBJS)
|
||||
|
||||
@ -1,13 +1,14 @@
|
||||
.file "biosboot.S"
|
||||
|
||||
#include "def.h"
|
||||
|
||||
// 0x00000 -> 0x07BFF our stack (to 31k)
|
||||
// 0x07A00 -> 0x07BFF typical MBR loc (at 30k5)
|
||||
// 0x07C00 -> 0x07DFF our code biosboot (at 31k)
|
||||
// 0x07E00 -> ... /boot inode block (at 31k5)
|
||||
// 0x07E00 -> ... (indirect block if nec)
|
||||
// 0x40000 -> ... /boot (at 256k)
|
||||
// 0x07E00 -> ... FAT table (at 31k5)
|
||||
// 0x40000 -> ... "boot" file (at 256k)
|
||||
|
||||
#define ELFMAGIC 0x464c457f /* ELFMAGIC ("\7fELF") */
|
||||
#define FATSEG 0x07e0 /* FAT table segment */
|
||||
#define BOOTSTACKOFF ((BOOTSEG << 4) - 4) /* stack starts here, grows down */
|
||||
|
||||
#define PBR_READ_ERROR 'R'
|
||||
#define PBR_CANT_BOOT 'X'
|
||||
@ -71,7 +72,7 @@ main:
|
||||
load_boot:
|
||||
start_cluster = .+1
|
||||
movw $0x9090, %ax
|
||||
movw $LOADSEG, %bx // destination
|
||||
movw $(LOADADDR >> 4), %bx // destination
|
||||
movw %bx, %di
|
||||
movw $FATSEG, %cx
|
||||
movw %cx, %es
|
||||
@ -158,7 +159,7 @@ Lchr:
|
||||
ret
|
||||
|
||||
done_load:
|
||||
movw $LOADSEG, %ax
|
||||
movw $(LOADADDR >> 4), %ax
|
||||
movw %ax, %es
|
||||
cmpl $ELFMAGIC, %es:0(,1)
|
||||
je exec_boot
|
||||
@ -202,4 +203,4 @@ err_id: .ascii "?"
|
||||
crlf: .asciz "\r\n"
|
||||
|
||||
. = 0x200 - 2
|
||||
.word DOSMBR_SIGNATURE
|
||||
.word 0xaa55
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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]();
|
||||
}
|
||||
}
|
||||
}
|
||||
82
boot/boot.c
82
boot/boot.c
@ -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
26
boot/console.c
Normal 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
38
boot/dat.h
Normal 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
47
boot/def.h
Normal 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
|
||||
@ -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;
|
||||
};
|
||||
}
|
||||
394
boot/gdt.S
394
boot/gdt.S
@ -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
|
||||
|
||||
@ -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
70
boot/print.c
Normal 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);
|
||||
}
|
||||
13
boot/srt0.S
13
boot/srt0.S
@ -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
|
||||
|
||||
12
btld_conf.h
Normal file
12
btld_conf.h
Normal file
@ -0,0 +1,12 @@
|
||||
#define FAT16_MAX (0x40000)
|
||||
#define DOSPTYP_UNUSED 0x00
|
||||
#define DOSPTYP_FAT16 0x06
|
||||
#define DOSPARTOFF 446
|
||||
#define DOSDISKOFF 444
|
||||
#define NDOSPART 4
|
||||
#define DOSACTIVE 0x80
|
||||
#define DOSMBR_SIGNATURE 0xAA55
|
||||
#define BOOT_MAGIC 0xf1abde3f
|
||||
#define DOSMBR_SIGNATURE_OFF 0x1fe
|
||||
|
||||
#define PARTSZ 16
|
||||
@ -1,21 +1,3 @@
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <limits.h>
|
||||
#include <assert.h>
|
||||
#include "def.h"
|
||||
|
||||
#define elem(x) ((int)(sizeof(x)/sizeof((x)[0])))
|
||||
|
||||
typedef uint8_t u8;
|
||||
typedef uint16_t u16;
|
||||
typedef uint32_t u32;
|
||||
typedef uint64_t u64;
|
||||
typedef unsigned int uint;
|
||||
|
||||
typedef struct{
|
||||
u64 cyl;
|
||||
u64 head;
|
||||
22
def.h
22
def.h
@ -1,22 +0,0 @@
|
||||
#define FAT16_MAX (0x40000)
|
||||
#define DOSPTYP_UNUSED 0x00
|
||||
#define DOSPTYP_FAT16 0x06
|
||||
#define DOSPARTOFF 446
|
||||
#define DOSDISKOFF 444
|
||||
#define NDOSPART 4
|
||||
#define DOSACTIVE 0x80
|
||||
#define DOSMBR_SIGNATURE 0xAA55
|
||||
#define BOOT_MAGIC 0xf1abde3f
|
||||
#define DOSMBR_SIGNATURE_OFF 0x1fe
|
||||
|
||||
#define BOOTSEG 0x7c0
|
||||
#define BOOTRELOCSEG 0x7a0
|
||||
#define MBRSTACKOFF 0xfffc
|
||||
#define PARTSZ 16
|
||||
#define LOADSEG (LOADADDR >> 4)
|
||||
#define FATSEG 0x07e0 /* FAT table segment */
|
||||
|
||||
#define BOOTSTACKOFF ((BOOTSEG << 4) - 4) /* stack starts here, grows down */
|
||||
#define LFMAGIC 0x464c /* LFMAGIC (last two bytes of \7fELF) */
|
||||
#define ELFMAGIC 0x464c457f /* ELFMAGIC ("\7fELF") */
|
||||
|
||||
@ -1,15 +1,17 @@
|
||||
PROG=installboot
|
||||
SRCS=$(wildcard *.c)
|
||||
OBJS=$(SRCS:.c=.o)
|
||||
SDIR ?= ../
|
||||
BDIR ?= ./
|
||||
|
||||
PROG = installboot
|
||||
SRCS = installboot.c
|
||||
OBJS = installboot.o
|
||||
|
||||
CFLAGS = -g -Wall -Werror
|
||||
CPPFLAGS = -I $(IDIR)
|
||||
CPPFLAGS = -I $(SDIR)
|
||||
|
||||
${PROG}: $(OBJS)
|
||||
$(CC) $(CFLAGS) -o $(BDIR)/$(PROG) $^
|
||||
cp filecopy.sh $(BDIR)
|
||||
$(CC) $(CFLAGS) -o $(BDIR)/$(PROG) $(OBJS)
|
||||
|
||||
$(OBJS): ../dat.h
|
||||
$(OBJS): $(SDIR)/u.h $(SDIR)/btld_conf.h $(SDIR)/btld_disk.h elf32.h
|
||||
|
||||
clean:
|
||||
rm -rf $(PROG) *.o
|
||||
rm -rf $(PROG) $(OBJS)
|
||||
|
||||
@ -1,12 +1,18 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/sysmacros.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/wait.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include "dat.h"
|
||||
#include <u.h>
|
||||
#include "btld_conf.h"
|
||||
#include "btld_disk.h"
|
||||
#include "elf32.h"
|
||||
|
||||
static char *devpath;
|
||||
@ -39,21 +45,21 @@ static struct{
|
||||
{"and_magic", 2},
|
||||
};
|
||||
|
||||
void
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
fprintf(stderr, "usgae: ./installboot device [bin]\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int
|
||||
static int
|
||||
streq(char *a, char *b)
|
||||
{
|
||||
int la = strlen(a);
|
||||
return la==strlen(b) && memcmp(a, b, la)==0;
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
loadelf(char *fname)
|
||||
{
|
||||
int fd;
|
||||
@ -96,7 +102,7 @@ found:
|
||||
close(fd);
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
symset(char *name, u32 val)
|
||||
{
|
||||
for(int i = 0; i < elem(syms); ++i){
|
||||
@ -108,7 +114,7 @@ symset(char *name, u32 val)
|
||||
assert(0 && "symbol not exist");
|
||||
}
|
||||
|
||||
uint
|
||||
static uint
|
||||
tou32(u8 *str, int i)
|
||||
{
|
||||
uint x = 0;
|
||||
@ -120,7 +126,7 @@ tou32(u8 *str, int i)
|
||||
return x;
|
||||
}
|
||||
|
||||
u16
|
||||
static u16
|
||||
exponent(u16 x)
|
||||
{
|
||||
switch(x){
|
||||
@ -138,7 +144,7 @@ exponent(u16 x)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
emit(u64 off)
|
||||
{
|
||||
for(int i = 0; i < elem(syms); ++i){
|
||||
@ -161,7 +167,7 @@ emit(u64 off)
|
||||
sizeof(btcode)-0x3c);
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
setbootparam(int ino, int off, int sec)
|
||||
{
|
||||
u8 buf[512];
|
||||
@ -189,18 +195,7 @@ setbootparam(int ino, int off, int sec)
|
||||
symset("and_magic", bps-1);
|
||||
}
|
||||
|
||||
void
|
||||
catpath(char *dst, char *s1, char *s2)
|
||||
{
|
||||
while(*s1)
|
||||
*dst++ = *s1++;
|
||||
*dst++ = '/';
|
||||
while(*s2)
|
||||
*dst++ = *s2++;
|
||||
*dst = '\0';
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
install(void)
|
||||
{
|
||||
char *args[] = {shpath, devpath, NULL};
|
||||
|
||||
@ -1,15 +1,17 @@
|
||||
PROG=installmbr
|
||||
SRCS=$(wildcard *.c)
|
||||
OBJS=$(SRCS:.c=.o)
|
||||
SDIR ?= ../
|
||||
BDIR ?= ./
|
||||
|
||||
CFLAGS = -g
|
||||
CPPFLAGS = -I $(IDIR)
|
||||
PROG = installmbr
|
||||
SRCS = installmbr.c
|
||||
OBJS = installmbr.o
|
||||
|
||||
CFLAGS = -g -Wall -Werror
|
||||
CPPFLAGS = -I $(SDIR)
|
||||
|
||||
${PROG}: $(OBJS)
|
||||
@rm -f $(PROG)
|
||||
$(CC) $(CFLAGS) -o $(BDIR)/$(PROG) $^
|
||||
$(CC) $(CFLAGS) -o $(BDIR)/$(PROG) $(OBJS)
|
||||
|
||||
$(OBJS): ../dat.h
|
||||
$(OBJS): $(SDIR)/u.h $(SDIR)/btld_conf.h $(SDIR)/btld_disk.h
|
||||
|
||||
clean:
|
||||
rm -rf $(PROG) $(OBJS)
|
||||
rm -f $(PROG) $(OBJS)
|
||||
|
||||
@ -1,17 +1,24 @@
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <linux/fs.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <stdio.h>
|
||||
#include <limits.h>
|
||||
#include <endian.h>
|
||||
#include <stdlib.h>
|
||||
#include "dat.h"
|
||||
#include <assert.h>
|
||||
#include <u.h>
|
||||
#include "btld_conf.h"
|
||||
#include "btld_disk.h"
|
||||
|
||||
static char *binpath = "build/mbr";
|
||||
static char bootcode[DOSPARTOFF];
|
||||
static Disk dsk;
|
||||
|
||||
void
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
fprintf(stderr, "usage: ./mkmbr device\n");
|
||||
@ -34,7 +41,7 @@ secwrite(void *buf, u64 sec, u32 cnt, Disk *dsk)
|
||||
return wc;
|
||||
}
|
||||
|
||||
char*
|
||||
static char*
|
||||
secread(u64 sec, u32 cnt, Disk *dsk)
|
||||
{
|
||||
char *buf;
|
||||
@ -53,7 +60,7 @@ secread(u64 sec, u32 cnt, Disk *dsk)
|
||||
return buf;
|
||||
}
|
||||
|
||||
int
|
||||
static int
|
||||
diskwrite(void *buf, u64 sec, u64 sz, Disk *dsk)
|
||||
{
|
||||
char *secbuf;
|
||||
@ -68,7 +75,7 @@ diskwrite(void *buf, u64 sec, u64 sz, Disk *dsk)
|
||||
return wc;
|
||||
}
|
||||
|
||||
Part
|
||||
static Part
|
||||
dospt2pt(DOSpart dpt, u64 self, u64 ext)
|
||||
{
|
||||
Part pt={0,};
|
||||
@ -90,7 +97,7 @@ dospt2pt(DOSpart dpt, u64 self, u64 ext)
|
||||
// H = (LBA / SPT) % HPC
|
||||
// S = (LBA / SPT) + 1
|
||||
|
||||
CHS
|
||||
static CHS
|
||||
lba2chs(u64 lba, u64 spt, u64 hpc)
|
||||
{
|
||||
CHS c = {0,};
|
||||
@ -101,7 +108,7 @@ lba2chs(u64 lba, u64 spt, u64 hpc)
|
||||
return c;
|
||||
}
|
||||
|
||||
CHS
|
||||
static CHS
|
||||
lba2chsbeg(Part pt)
|
||||
{
|
||||
if(pt.ns == 0 || pt.id == DOSPTYP_UNUSED)
|
||||
@ -109,7 +116,7 @@ lba2chsbeg(Part pt)
|
||||
return lba2chs(pt.bs, dsk.spt, dsk.hpc);
|
||||
}
|
||||
|
||||
CHS
|
||||
static CHS
|
||||
lba2chsend(Part pt)
|
||||
{
|
||||
if(pt.ns == 0 || pt.id == DOSPTYP_UNUSED)
|
||||
@ -117,7 +124,7 @@ lba2chsend(Part pt)
|
||||
return lba2chs(pt.bs+pt.ns-1, dsk.spt, dsk.hpc);
|
||||
}
|
||||
|
||||
CHS
|
||||
static CHS
|
||||
chsnorm(u8 id, CHS c)
|
||||
{
|
||||
if(c.head > 254 || c.sec > 63 || c.cyl > 1023){
|
||||
@ -131,7 +138,7 @@ chsnorm(u8 id, CHS c)
|
||||
return c;
|
||||
}
|
||||
|
||||
DOSpart
|
||||
static DOSpart
|
||||
pt2dospt(Part pt, u64 self, u64 ext)
|
||||
{
|
||||
DOSpart d={0,};
|
||||
@ -158,7 +165,7 @@ pt2dospt(Part pt, u64 self, u64 ext)
|
||||
return d;
|
||||
}
|
||||
|
||||
DOSmbr
|
||||
static DOSmbr
|
||||
mbr2dosmbr(MBR m)
|
||||
{
|
||||
DOSmbr d={0,};
|
||||
@ -174,7 +181,7 @@ mbr2dosmbr(MBR m)
|
||||
return d;
|
||||
}
|
||||
|
||||
MBR
|
||||
static MBR
|
||||
mbrinit(void)
|
||||
{
|
||||
MBR m = {0,};
|
||||
@ -198,7 +205,7 @@ mbrinit(void)
|
||||
return m;
|
||||
}
|
||||
|
||||
int
|
||||
static int
|
||||
mbrwrite(MBR m)
|
||||
{
|
||||
DOSmbr d;
|
||||
@ -209,7 +216,7 @@ mbrwrite(MBR m)
|
||||
return wc;
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
read512(char *path)
|
||||
{
|
||||
int fd;
|
||||
|
||||
29
mbr/Makefile
29
mbr/Makefile
@ -1,19 +1,24 @@
|
||||
PROG=mbr
|
||||
SRCS=$(wildcard *.S)
|
||||
OBJS=$(SRCS:.S=.o)
|
||||
SDIR ?= ../
|
||||
BDIR ?= ./
|
||||
|
||||
LDFLAGS = -Ttext 0 -e 0
|
||||
CPPFLAGS = -I $(IDIR)
|
||||
PROG = mbr
|
||||
SRCS = mbr.S
|
||||
OBJS = mbr.o
|
||||
|
||||
include $(SDIR)/Makefile.inc
|
||||
|
||||
CFLAGS += -c -fno-pie
|
||||
LDFLAGS += -Ttext 0 -e 0
|
||||
CPPFLAGS += -DBOOTSEG=$(BOOTSEG) -DBOOTRELOCSEG=$(BOOTRELOCSEG) -DMBRSTACKOFF=$(MBRSTACKOFF)
|
||||
CPPFLAGS += -I $(SDIR)/
|
||||
|
||||
${PROG}: $(OBJS)
|
||||
@rm -f $(PROG)
|
||||
$(LD) $(LDFLAGS) -o $(PROG) $(OBJS)
|
||||
objcopy -O binary mbr mbr.new
|
||||
dd if=mbr.new of=mbr bs=512 count=1
|
||||
rm -rf mbr.new
|
||||
mv $(PROG) $(BDIR)
|
||||
objcopy -S -O binary mbr mbr.new
|
||||
dd if=mbr.new of=$(BDIR)/mbr bs=512 count=1
|
||||
rm -f mbr.new
|
||||
|
||||
$(OBJS): ../def.h
|
||||
$(OBJS): $(SDIR)/Makefile.inc $(SDIR)/btld_conf.h
|
||||
|
||||
clean:
|
||||
rm -f *.o *.bin $(PROG)
|
||||
rm -f $(OBJS) $(PROG)
|
||||
20
mbr/mbr.S
20
mbr/mbr.S
@ -1,6 +1,6 @@
|
||||
.file "mbr.S"
|
||||
|
||||
#include "def.h"
|
||||
#include "btld_conf.h"
|
||||
|
||||
#define CHAR_LBA_READ '.'
|
||||
#define CHAR_R 'R'
|
||||
@ -8,7 +8,6 @@
|
||||
#define CHAR_L 'L'
|
||||
#define CHAR_B 'B'
|
||||
#define CHAR_G 'G'
|
||||
#define DBGMSG(c) movb $c, %al; call Lchr
|
||||
#define puts(s) movw $s, %si; call Lmessage
|
||||
|
||||
// 0x07C00 - 0x07DFF BIOS load us here
|
||||
@ -32,7 +31,6 @@ start:
|
||||
|
||||
// set up data segment
|
||||
movw %ax, %ds
|
||||
DBGMSG(CHAR_S)
|
||||
|
||||
// relocate for PBR
|
||||
// copy to 0x07a0
|
||||
@ -48,13 +46,12 @@ start:
|
||||
ljmp $BOOTRELOCSEG, $reloc
|
||||
|
||||
reloc:
|
||||
DBGMSG(CHAR_R)
|
||||
|
||||
pushw %ds
|
||||
popw %es
|
||||
pushw %cs
|
||||
popw %ds
|
||||
testb $DOSACTIVE, %dl
|
||||
testb $0x80, %dl
|
||||
jnz drive_ok
|
||||
puts(efdmbr)
|
||||
jmp stay_stopped
|
||||
@ -64,11 +61,10 @@ drive_ok:
|
||||
movw $NDOSPART, %cx
|
||||
|
||||
find_active:
|
||||
DBGMSG(CHAR_L)
|
||||
movb (%si), %al
|
||||
cmpb $DOSACTIVE, %al
|
||||
cmpb $0x80, %al
|
||||
je found
|
||||
addw $PARTSZ, %si
|
||||
addw $16, %si //add partion size
|
||||
loop find_active
|
||||
|
||||
no_part:
|
||||
@ -83,7 +79,6 @@ stay_stopped:
|
||||
jmp stay_stopped
|
||||
|
||||
found:
|
||||
DBGMSG(CHAR_B)
|
||||
movb %dl, %al
|
||||
andb $0x0f, %al
|
||||
addb $'0', %al
|
||||
@ -178,16 +173,15 @@ eread: .asciz "\r\nRead error\r\n"
|
||||
enoos: .asciz "No O/S\r\n"
|
||||
enoboot: .ascii "No active partion"
|
||||
crlf: .asciz "\r\n"
|
||||
|
||||
endofcode:
|
||||
nop
|
||||
|
||||
// partion table
|
||||
. = DOSPARTOFF // partion table start address
|
||||
pt: .fill 0x40,1,0
|
||||
pt:
|
||||
.fill 0x40,1,0
|
||||
|
||||
. = 0x1fe
|
||||
signature:
|
||||
.short DOSMBR_SIGNATURE
|
||||
.short 0xaa55
|
||||
. = 0x200
|
||||
|
||||
|
||||
21
u.h
Normal file
21
u.h
Normal file
@ -0,0 +1,21 @@
|
||||
#define elem(x) ((int)(sizeof(x)/sizeof((x)[0])))
|
||||
#define nil ((void*)0)
|
||||
|
||||
typedef unsigned short ushort;
|
||||
typedef unsigned char uchar;
|
||||
typedef unsigned long ulong;
|
||||
typedef unsigned int uint;
|
||||
typedef signed char schar;
|
||||
typedef long long vlong;
|
||||
typedef unsigned long long uvlong;
|
||||
typedef long iptr;
|
||||
typedef unsigned long uptr;
|
||||
typedef unsigned long usize;
|
||||
typedef unsigned char u8;
|
||||
typedef unsigned short u16;
|
||||
typedef unsigned int u32;
|
||||
typedef unsigned long long u64;
|
||||
typedef signed char i8;
|
||||
typedef signed short i16;
|
||||
typedef signed int i32;
|
||||
typedef signed long long i64;
|
||||
Loading…
Reference in New Issue
Block a user