can read character from keyboard now

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

View File

@ -2,6 +2,7 @@ BDIR = build
SUBDIRS = biosboot boot mbr installboot installmbr SUBDIRS = biosboot boot mbr installboot installmbr
all: $(BDIR) $(SUBDIRS) all: $(BDIR) $(SUBDIRS)
cp installboot/filecopy.sh $(BDIR)/
$(BDIR): $(BDIR):
mkdir -p $(BDIR) mkdir -p $(BDIR)
@ -10,6 +11,6 @@ clean: $(SUBDIRS)
rm -rf $(BDIR) rm -rf $(BDIR)
$(SUBDIRS): $(SUBDIRS):
@make -sC $@ $(MAKECMDGOALS) BDIR=$(PWD)/$(BDIR) IDIR=$(PWD) @make -C $@ $(MAKECMDGOALS) BDIR=$(PWD)/$(BDIR) SDIR=$(PWD)
.PHONY: biosboot boot installboot mbr installmbr .PHONY: biosboot boot installboot mbr installmbr

View File

@ -1,13 +1,14 @@
LINKADDR = 0x40120 LINKADDR = 0x40120
LOADADDR = 0x40000 LOADADDR = 0x40000
BOOTMAGIC = 0xc001d00d BOOTMAGIC = 0xc001d00d
BOOTREL = 0x60000 BOOTSEG = 0x7c0
BOOTRELOCSEG = 0x7a0
MBRSTACKOFF = 0xfffc
BOOTSTACKOFF = 0xfffc
CC=cc CC=cc
CFLAGS=-m32 -Wall -Werror -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
#CFLAGS=-m32 -march=i386 -O0 -fno-stack-protector -ffreestanding -fno-builtin
CPPFLAGS=-nostdinc CPPFLAGS=-nostdinc
LD=ld ASFLAGS=-Wa,--32,-O0
AS=as LDFLAGS=-O0 -melf_i386 -nostdlib -x -N -Bstatic -znorelro -no-pie
ASFLAGS=-Wa,-O0,--32
LDFLAGS=-melf_i386 -O0 -nostdlib -x -N -Bstatic -znorelro -no-pie

View File

@ -1,18 +1,20 @@
include ../*.inc SDIR ?= ../
BDIR ?= ./
PROG=biosboot PROG = biosboot
SRCS=$(wildcard *.S) SRCS = biosboot.S
OBJS=$(SRCS:.S=.o) OBJS = biosboot.o
CFLAGS+=-c -fno-pie include $(SDIR)/Makefile.inc
LDFLAGS+=-Ttext 0 -T ld.script
CPPFLAGS+=-nostdinc -DLOADADDR=$(LOADADDR) -DLINKADDR=$(LINKADDR) -DBOOTMAGIC=$(BOOTMAGIC) CFLAGS += -c -fno-pie
CPPFLAGS+=-I $(IDIR) LDFLAGS += -Ttext 0 -T ld.script
CPPFLAGS += -DLOADADDR=$(LOADADDR) -DLINKADDR=$(LINKADDR) -DBOOTMAGIC=$(BOOTMAGIC) -DBOOTSEG=$(BOOTSEG)
$(PROG): $(OBJS) $(PROG): $(OBJS)
$(LD) $(LDFLAGS) -o $(BDIR)/$(PROG) $(OBJS) $(LD) $(LDFLAGS) -o $(BDIR)/$(PROG) $(OBJS)
$(OBJS): ../def.h $(OBJS): $(SDIR)/Makefile.inc
clean: clean:
rm -f $(PROG) $(OBJS) rm -f $(PROG) $(OBJS)

View File

@ -1,13 +1,14 @@
.file "biosboot.S" .file "biosboot.S"
#include "def.h"
// 0x00000 -> 0x07BFF our stack (to 31k) // 0x00000 -> 0x07BFF our stack (to 31k)
// 0x07A00 -> 0x07BFF typical MBR loc (at 30k5) // 0x07A00 -> 0x07BFF typical MBR loc (at 30k5)
// 0x07C00 -> 0x07DFF our code biosboot (at 31k) // 0x07C00 -> 0x07DFF our code biosboot (at 31k)
// 0x07E00 -> ... /boot inode block (at 31k5) // 0x07E00 -> ... FAT table (at 31k5)
// 0x07E00 -> ... (indirect block if nec) // 0x40000 -> ... "boot" file (at 256k)
// 0x40000 -> ... /boot (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_READ_ERROR 'R'
#define PBR_CANT_BOOT 'X' #define PBR_CANT_BOOT 'X'
@ -71,7 +72,7 @@ main:
load_boot: load_boot:
start_cluster = .+1 start_cluster = .+1
movw $0x9090, %ax movw $0x9090, %ax
movw $LOADSEG, %bx // destination movw $(LOADADDR >> 4), %bx // destination
movw %bx, %di movw %bx, %di
movw $FATSEG, %cx movw $FATSEG, %cx
movw %cx, %es movw %cx, %es
@ -158,7 +159,7 @@ Lchr:
ret ret
done_load: done_load:
movw $LOADSEG, %ax movw $(LOADADDR >> 4), %ax
movw %ax, %es movw %ax, %es
cmpl $ELFMAGIC, %es:0(,1) cmpl $ELFMAGIC, %es:0(,1)
je exec_boot je exec_boot
@ -202,4 +203,4 @@ err_id: .ascii "?"
crlf: .asciz "\r\n" crlf: .asciz "\r\n"
. = 0x200 - 2 . = 0x200 - 2
.word DOSMBR_SIGNATURE .word 0xaa55

View File

@ -1,19 +1,25 @@
include ../*.inc SDIR ?= ../
BDIR ?= ./
PROG=boot PROG = boot
CSRCS= $(wildcard *.c) SRCS = srt0.S gdt.S boot.c
SSRCS= $(wildcard *.S) OBJS = srt0.o gdt.o boot.o
OBJS = $(SSRCS:.S=.o) $(CSRCS:.c=.o)
CFLAGS+=-c -fno-pie ESRCS = console.c print.c a20.c
CPPFLAGS+=-nostdinc -DLOADADDR=$(LOADADDR) -DLINKADDR=$(LINKADDR) -DBOOTMAGIC=$(BOOTMAGIC) OBJS += $(ESRCS:.c=.o)
LDFLAGS+= -s -T ld.script -Ttext=$(LINKADDR) --no-omagic -M
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) ${PROG}: $(OBJS)
@rm -f $(PROG) @rm -f $(PROG)
$(LD) $(LDFLAGS) -o $(BDIR)/$(PROG) $(OBJS) $(LD) $(LDFLAGS) -o $(BDIR)/$(PROG) $(OBJS)
$(OBJS): conf.h pio.h $(OBJS): $(SDIR)/u.h def.h dat.h fn.h
clean: 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 void
// 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
a20up(void) a20up(void)
{ {
struct{ struct{
@ -43,25 +32,4 @@ a20up(void)
; ;
while(inb(i8042.sport) & i8042.dib) while(inb(i8042.sport) & i8042.dib)
inb(i8042.dport); 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" void (*probe1[])(void) = {
#include "conf.h" a20up,
};
void (*probe2[])(void) = {
};
#define VGA_WIDTH 80 BootProbe probes[] = {
#define VGA_LENGTH 25 {"probing", probe1, elem(probe1) },
{"disk", probe2, elem(probe2) },
};
char* ConDev condev = {
memcpy(char *a, char *b, int l) .getc = pcgetc,
.putc = pcputc,
};
// https://wiki.osdev.org/BIOS
void
machdep(void)
{ {
for(int i = 0; i < l; ++i) for(int i = 0; i < elem(probes); ++i){
a[i] = b[i]; BootProbe bp = probes[i];
return a; for(int j = 0; j < bp.cnt; ++j)
bp.probes[j]();
}
} }
int static void
strlen(char *s) puts(char *s)
{ {
int i = 0; for(;*s;++s)
for(; s[i]; ++i) putchar(*s);
;
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;
} }
void void
boot(dev_t bootdev) boot(int bootdev)
{ {
machdep(); char buf[8192];
for(;;);
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 static __inline void
outb(int port, u8 data) outb(int port, u8 data)
{ {
@ -11,4 +23,4 @@ inb(int port)
__asm volatile("inb %w1,%0" : "=a" (data) : "d" (port)); __asm volatile("inb %w1,%0" : "=a" (data) : "d" (port));
return data; return data;
}; }

View File

@ -1,71 +1,95 @@
.file "gdt.S" .file "gdt.S"
// Trap #include "def.h"
#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 GEN_LABEL(n) X##n
#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 S32TEXT 0x08 // segment selector of text section // idt entry
#define SDT_SYS386TGT 15 /* system 386 trap gate */ #define idte(e) \
movl $GEN_LABEL(e), %eax ; \
call entry
#define IPROC(n) X##n // idt bios entry
#define idte(e) \ #define idtbe(b) idte(emu##b)
movl $IPROC(e), %eax ; call entry_idt
#define IENTRY_ERR(name,err) \ #define GEN_TRAP(name, err) \
IPROC(name): \ GEN_LABEL(name): \
pushl $err ; \ pushl $err; \
jmp 1f 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 .text
.code32 .code32
.globl pmm_init .globl pmode_init
entry_idt:
// Table // Table
// IDTR offset + 0 : entry 0 // IDTR offset + 0 : entry 0
// IDTR offset + 8 : entry 1 // IDTR offset + 8 : entry 1
// //
// Gate Descriptor // Gate Descriptor
// 63 ~ 48 : offset low // 63 ~ 48 : offset low
// 47 ~ 32 : info // 47 ~ 32 : info
// 31 ~ 16 : segment selector // 31 ~ 16 : segment selector
// 15 ~ 0 : offset high // 15 ~ 0 : offset high
entry:
movw %ax, (%ebx) movw %ax, (%ebx)
movw $S32TEXT, 2(%ebx) movw $S32TEXT, 2(%ebx)
movw $((0x80|SDT_SYS386TGT) << 8), 4(%ebx) movw $((0x80|SDT_SYS386TGT) << 8), 4(%ebx)
@ -74,8 +98,9 @@ entry_idt:
addl $8, %ebx addl $8, %ebx
ret ret
// init IDT for protected mode
.align 8, 0x90 .align 8, 0x90
pmm_init: pmode_init:
movl $idt, %ebx movl $idt, %ebx
movl $Idtr, %eax movl $Idtr, %eax
movw $(640 - 1), (%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); 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 lidt Idtr
ret ret
@ -105,86 +139,204 @@ Idtr:
.text .text
.align 8 .align 8
gdt: .globl Idtr_real
/* 0x00 : null */ Idtr_real:
.space 8 .word 1023 // 256 entry, 1k
/* 0x08 : flat code */ .long 0
.word 0xFFFF # lolimit .word 0
.word 0 # lobase
.byte 0 # midbase .align 8
.byte SDT_MEMERAC | 0 | 0x80 # RXAC, dpl = 0, present gdt:
.byte 0xf | 0 | 0x40 | 0x80 # hilimit, xx, 32bit, 4k granularity /* 0x00 : null */
.byte 0 # hibase .space 8
/* 0x10 : flat data */ /* 0x08 : flat code */
.word 0xFFFF # lolimit .word 0xFFFF // lolimit
.word 0 # lobase .word 0 // lobase
.byte 0 # midbase .byte 0 // midbase
.byte SDT_MEMRWA | 0 | 0x80 # RWA, dpl = 0, present .byte SDT_MEMERAC | 0 | 0x80 // RXAC, dpl = 0, present
.byte 0xf | 0 | 0x40 | 0x80 # hilimit, xx, 32bit, 4k granularity .byte 0xf | 0 | 0x40 | 0x80 // hilimit, xx, 32bit, 4k granularity
.byte 0 # hibase .byte 0 // hibase
/* 0x18 : 16 bit code */ /* 0x10 : flat data */
.word 0xFFFF # lolimit .word 0xFFFF // lolimit
.word (LINKADDR & 0xffff) # lobase .word 0 // lobase
.byte (LINKADDR >> 16) & 0xff # midbase .byte 0 // midbase
.byte SDT_MEMERAC | 0 | 0x80 # RXAC, dpl = 0, present .byte SDT_MEMRWA | 0 | 0x80 // RWA, dpl = 0, present
.byte 0x0 | 0 | 0 | 0 # hilimit, xx, 16bit, byte granularity .byte 0xf | 0 | 0x40 | 0x80 // hilimit, xx, 32bit, 4k granularity
.byte (LINKADDR >> 20) & 0xff # hibase .byte 0 // hibase
/* 0x20 : 16 bit data */ /* 0x18 : 16 bit code */
.word 0xFFFF # lolimit .word 0xFFFF // lolimit
.word (LINKADDR & 0xffff) # lobase .word (LINKADDR & 0xffff) // lobase
.byte (LINKADDR >> 16) & 0xff # midbase .byte (LINKADDR >> 16) & 0xff // midbase
.byte SDT_MEMRWA | 0 | 0x80 # RWA, dpl = 0, present .byte SDT_MEMERAC | 0 | 0x80 // RXAC, dpl = 0, present
.byte 0x0 | 0 | 0 | 0 # hilimit, xx, 16bit, byte granularity .byte 0x0 | 0 | 0 | 0 // hilimit, xx, 16bit, byte granularity
.byte (LINKADDR >> 20) & 0xff # hibase .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 // Register GDT
.globl Gdtr .globl Gdtr
Gdtr: Gdtr:
.word . - gdt -1 .word . - gdt - 1
.long gdt .long gdt
.word 0 .word 0
// ENTRY Reserved // ENTRY Reserved
IPROC(xx): GEN_LABEL(xx):
pushl $1 pushl $1
pushl $T_RESERVED
jmp 1f jmp 1f
// trap entry points // trap entry points
IENTRY_ERR(de,T_DIVIDE) /* #DE divide by zero */ GEN_TRAP(de,T_DIVIDE) /* DE divide by zero */
IENTRY_ERR(db,T_TRCTRAP) /* #DB debug */ GEN_TRAP(db,T_TRCTRAP) /* DB debug */
IENTRY_ERR(nmi,T_NMI) /* NMI */ GEN_TRAP(nmi,T_NMI) /* NMI */
IENTRY_ERR(bp,T_BPTFLT) /* #BP breakpoint */ GEN_TRAP(bp,T_BPTFLT) /* BP breakpoint */
IENTRY_ERR(of,T_OFLOW) /* #OF overflow */ GEN_TRAP(of,T_OFLOW) /* OF overflow */
IENTRY_ERR(br,T_BOUND) /* #BR BOUND range exceeded */ GEN_TRAP(br,T_BOUND) /* BR BOUND range exceeded */
IENTRY_ERR(ud,T_PRIVINFLT) /* #UD invalid opcode */ GEN_TRAP(ud,T_PRIVINFLT) /* UD invalid opcode */
IENTRY_ERR(nm,T_DNA) /* #NM device not available */ GEN_TRAP(nm,T_DNA) /* NM device not available */
IENTRY_ERR(df,T_DOUBLEFLT) /* #DF double fault */ GEN_TRAP(df,T_DOUBLEFLT) /* DF double fault */
IENTRY_ERR(fo,T_FPOPFLT) /* #FO coprocessor segment overrun */ GEN_TRAP(fo,T_FPOPFLT) /* FO coprocessor segment overrun */
IENTRY_ERR(ts,T_TSSFLT) /* #TS invalid TSS */ GEN_TRAP(ts,T_TSSFLT) /* TS invalid TSS */
IENTRY_ERR(np,T_SEGNPFLT) /* #NP segment not present */ GEN_TRAP(np,T_SEGNPFLT) /* NP segment not present */
IENTRY_ERR(ss,T_STKFLT) /* #SS stack fault */ GEN_TRAP(ss,T_STKFLT) /* SS stack fault */
IENTRY_ERR(gp,T_PROTFLT) /* #GP general protection */ GEN_TRAP(gp,T_PROTFLT) /* GP general protection */
IENTRY_ERR(pf,T_PAGEFLT) /* #PF page fault */ GEN_TRAP(pf,T_PAGEFLT) /* PF page fault */
IENTRY_ERR(mf,T_ARITHTRAP) /* #MF floating point error */ GEN_TRAP(mf,T_ARITHTRAP) /* MF floating point error */
IENTRY_ERR(ac,T_ALIGNFLT) /* #AC alignment check */ GEN_TRAP(ac,T_ALIGNFLT) /* AC alignment check */
IENTRY_ERR(mc,T_MACHK) /* #MC machine check */ GEN_TRAP(mc,T_MACHK) /* MC machine check */
1: 1:
jmp alltraps popl %ecx // what trap
// in boot mode don't want handle trap
alltraps:
hlt 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 // 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 .globl EMUh
.align 8, 0x90 .align 8, 0x90
EMUh: EMUh: // build stack for real mode
pushl %eax 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") PHDRS
OUTPUT_ARCH(i386)
PHDRS
{ {
text PT_LOAD; text PT_LOAD;
} }
SECTIONS SECTIONS
{ {
.text : { .text :
KEEP(srt0.o(.text)) {
*(.text) start = . ;
} :text _start = . ;
etext = .; __start = . ;
.data : { *(.data) } :text *(.text)
.rodata : { *(.rodata) } :text etext = . ;
edata = .; } :text
.bss : { *(.bss) } :text .data :
ebss = .; {
end = .; __data_start__ = . ;
/DISCARD/ : *(.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) *(.note.gnu.property)
*(.comment) *(.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" .file "srt0.S"
#define BOOTSTACK 0xfffc #include "def.h"
#define CR0_PE 0x00000001 /* Protected mode Enable */
.globl end .globl end
.globl edata .globl edata
.globl Gdtr .globl Gdtr
.globl boot .globl boot
.globl pmm_init .globl pmode_init
.text .text
.code16 .code16
@ -20,14 +19,16 @@ _start:
1: 1:
popl %edx popl %edx
// load GDT
cli cli
pushl %cs pushl %cs
popl %ds popl %ds
addr32 data32 lgdt (Gdtr - LINKADDR) addr32 data32 lgdt (Gdtr - LINKADDR)
movl %cr0, %eax movl %cr0, %eax
// enable protected mode
orl $CR0_PE, %eax orl $CR0_PE, %eax
data32 movl %eax, %cr0 data32 movl %eax, %cr0
data32 ljmp $8, $1f data32 ljmp $S32TEXT, $1f
1: 1:
.code32 .code32
@ -37,7 +38,7 @@ _start:
mov %ax, %es mov %ax, %es
mov %ax, %fs mov %ax, %fs
mov %ax, %gs mov %ax, %gs
movl $BOOTSTACK, %esp movl $BOOTSTACKOFF, %esp
pushl %edx pushl %edx
// fill 0 .bss // fill 0 .bss
@ -48,5 +49,5 @@ _start:
cld cld
rep; stosb rep; stosb
call pmm_init call pmode_init
call boot call boot

12
btld_conf.h Normal file
View 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

View File

@ -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{ typedef struct{
u64 cyl; u64 cyl;
u64 head; u64 head;

22
def.h
View File

@ -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") */

View File

@ -1,15 +1,17 @@
PROG=installboot SDIR ?= ../
SRCS=$(wildcard *.c) BDIR ?= ./
OBJS=$(SRCS:.c=.o)
PROG = installboot
SRCS = installboot.c
OBJS = installboot.o
CFLAGS = -g -Wall -Werror CFLAGS = -g -Wall -Werror
CPPFLAGS = -I $(IDIR) CPPFLAGS = -I $(SDIR)
${PROG}: $(OBJS) ${PROG}: $(OBJS)
$(CC) $(CFLAGS) -o $(BDIR)/$(PROG) $^ $(CC) $(CFLAGS) -o $(BDIR)/$(PROG) $(OBJS)
cp filecopy.sh $(BDIR)
$(OBJS): ../dat.h $(OBJS): $(SDIR)/u.h $(SDIR)/btld_conf.h $(SDIR)/btld_disk.h elf32.h
clean: clean:
rm -rf $(PROG) *.o rm -rf $(PROG) $(OBJS)

View File

@ -1,12 +1,18 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <ctype.h> #include <ctype.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/mount.h> #include <sys/mount.h>
#include <sys/sysmacros.h> #include <fcntl.h>
#include <sys/wait.h> #include <sys/wait.h>
#include <errno.h> #include <errno.h>
#include <assert.h> #include <assert.h>
#include "dat.h" #include <u.h>
#include "btld_conf.h"
#include "btld_disk.h"
#include "elf32.h" #include "elf32.h"
static char *devpath; static char *devpath;
@ -39,21 +45,21 @@ static struct{
{"and_magic", 2}, {"and_magic", 2},
}; };
void static void
usage(void) usage(void)
{ {
fprintf(stderr, "usgae: ./installboot device [bin]\n"); fprintf(stderr, "usgae: ./installboot device [bin]\n");
exit(1); exit(1);
} }
int static int
streq(char *a, char *b) streq(char *a, char *b)
{ {
int la = strlen(a); int la = strlen(a);
return la==strlen(b) && memcmp(a, b, la)==0; return la==strlen(b) && memcmp(a, b, la)==0;
} }
void static void
loadelf(char *fname) loadelf(char *fname)
{ {
int fd; int fd;
@ -96,7 +102,7 @@ found:
close(fd); close(fd);
} }
void static void
symset(char *name, u32 val) symset(char *name, u32 val)
{ {
for(int i = 0; i < elem(syms); ++i){ for(int i = 0; i < elem(syms); ++i){
@ -108,7 +114,7 @@ symset(char *name, u32 val)
assert(0 && "symbol not exist"); assert(0 && "symbol not exist");
} }
uint static uint
tou32(u8 *str, int i) tou32(u8 *str, int i)
{ {
uint x = 0; uint x = 0;
@ -120,7 +126,7 @@ tou32(u8 *str, int i)
return x; return x;
} }
u16 static u16
exponent(u16 x) exponent(u16 x)
{ {
switch(x){ switch(x){
@ -138,7 +144,7 @@ exponent(u16 x)
} }
} }
void static void
emit(u64 off) emit(u64 off)
{ {
for(int i = 0; i < elem(syms); ++i){ for(int i = 0; i < elem(syms); ++i){
@ -161,7 +167,7 @@ emit(u64 off)
sizeof(btcode)-0x3c); sizeof(btcode)-0x3c);
} }
void static void
setbootparam(int ino, int off, int sec) setbootparam(int ino, int off, int sec)
{ {
u8 buf[512]; u8 buf[512];
@ -189,18 +195,7 @@ setbootparam(int ino, int off, int sec)
symset("and_magic", bps-1); symset("and_magic", bps-1);
} }
void static void
catpath(char *dst, char *s1, char *s2)
{
while(*s1)
*dst++ = *s1++;
*dst++ = '/';
while(*s2)
*dst++ = *s2++;
*dst = '\0';
}
void
install(void) install(void)
{ {
char *args[] = {shpath, devpath, NULL}; char *args[] = {shpath, devpath, NULL};

View File

@ -1,15 +1,17 @@
PROG=installmbr SDIR ?= ../
SRCS=$(wildcard *.c) BDIR ?= ./
OBJS=$(SRCS:.c=.o)
CFLAGS = -g PROG = installmbr
CPPFLAGS = -I $(IDIR) SRCS = installmbr.c
OBJS = installmbr.o
CFLAGS = -g -Wall -Werror
CPPFLAGS = -I $(SDIR)
${PROG}: $(OBJS) ${PROG}: $(OBJS)
@rm -f $(PROG) $(CC) $(CFLAGS) -o $(BDIR)/$(PROG) $(OBJS)
$(CC) $(CFLAGS) -o $(BDIR)/$(PROG) $^
$(OBJS): ../dat.h $(OBJS): $(SDIR)/u.h $(SDIR)/btld_conf.h $(SDIR)/btld_disk.h
clean: clean:
rm -rf $(PROG) $(OBJS) rm -f $(PROG) $(OBJS)

View File

@ -1,17 +1,24 @@
#include <stdint.h>
#include <string.h>
#include <fcntl.h> #include <fcntl.h>
#include <unistd.h> #include <unistd.h>
#include <linux/fs.h> #include <linux/fs.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <stdio.h> #include <stdio.h>
#include <limits.h> #include <limits.h>
#include <endian.h> #include <endian.h>
#include <stdlib.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 *binpath = "build/mbr";
static char bootcode[DOSPARTOFF]; static char bootcode[DOSPARTOFF];
static Disk dsk; static Disk dsk;
void static void
usage(void) usage(void)
{ {
fprintf(stderr, "usage: ./mkmbr device\n"); fprintf(stderr, "usage: ./mkmbr device\n");
@ -34,7 +41,7 @@ secwrite(void *buf, u64 sec, u32 cnt, Disk *dsk)
return wc; return wc;
} }
char* static char*
secread(u64 sec, u32 cnt, Disk *dsk) secread(u64 sec, u32 cnt, Disk *dsk)
{ {
char *buf; char *buf;
@ -53,7 +60,7 @@ secread(u64 sec, u32 cnt, Disk *dsk)
return buf; return buf;
} }
int static int
diskwrite(void *buf, u64 sec, u64 sz, Disk *dsk) diskwrite(void *buf, u64 sec, u64 sz, Disk *dsk)
{ {
char *secbuf; char *secbuf;
@ -68,7 +75,7 @@ diskwrite(void *buf, u64 sec, u64 sz, Disk *dsk)
return wc; return wc;
} }
Part static Part
dospt2pt(DOSpart dpt, u64 self, u64 ext) dospt2pt(DOSpart dpt, u64 self, u64 ext)
{ {
Part pt={0,}; Part pt={0,};
@ -90,7 +97,7 @@ dospt2pt(DOSpart dpt, u64 self, u64 ext)
// H = (LBA / SPT) % HPC // H = (LBA / SPT) % HPC
// S = (LBA / SPT) + 1 // S = (LBA / SPT) + 1
CHS static CHS
lba2chs(u64 lba, u64 spt, u64 hpc) lba2chs(u64 lba, u64 spt, u64 hpc)
{ {
CHS c = {0,}; CHS c = {0,};
@ -101,7 +108,7 @@ lba2chs(u64 lba, u64 spt, u64 hpc)
return c; return c;
} }
CHS static CHS
lba2chsbeg(Part pt) lba2chsbeg(Part pt)
{ {
if(pt.ns == 0 || pt.id == DOSPTYP_UNUSED) if(pt.ns == 0 || pt.id == DOSPTYP_UNUSED)
@ -109,7 +116,7 @@ lba2chsbeg(Part pt)
return lba2chs(pt.bs, dsk.spt, dsk.hpc); return lba2chs(pt.bs, dsk.spt, dsk.hpc);
} }
CHS static CHS
lba2chsend(Part pt) lba2chsend(Part pt)
{ {
if(pt.ns == 0 || pt.id == DOSPTYP_UNUSED) 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); return lba2chs(pt.bs+pt.ns-1, dsk.spt, dsk.hpc);
} }
CHS static CHS
chsnorm(u8 id, CHS c) chsnorm(u8 id, CHS c)
{ {
if(c.head > 254 || c.sec > 63 || c.cyl > 1023){ if(c.head > 254 || c.sec > 63 || c.cyl > 1023){
@ -131,7 +138,7 @@ chsnorm(u8 id, CHS c)
return c; return c;
} }
DOSpart static DOSpart
pt2dospt(Part pt, u64 self, u64 ext) pt2dospt(Part pt, u64 self, u64 ext)
{ {
DOSpart d={0,}; DOSpart d={0,};
@ -158,7 +165,7 @@ pt2dospt(Part pt, u64 self, u64 ext)
return d; return d;
} }
DOSmbr static DOSmbr
mbr2dosmbr(MBR m) mbr2dosmbr(MBR m)
{ {
DOSmbr d={0,}; DOSmbr d={0,};
@ -174,7 +181,7 @@ mbr2dosmbr(MBR m)
return d; return d;
} }
MBR static MBR
mbrinit(void) mbrinit(void)
{ {
MBR m = {0,}; MBR m = {0,};
@ -198,7 +205,7 @@ mbrinit(void)
return m; return m;
} }
int static int
mbrwrite(MBR m) mbrwrite(MBR m)
{ {
DOSmbr d; DOSmbr d;
@ -209,7 +216,7 @@ mbrwrite(MBR m)
return wc; return wc;
} }
void static void
read512(char *path) read512(char *path)
{ {
int fd; int fd;

View File

@ -1,19 +1,24 @@
PROG=mbr SDIR ?= ../
SRCS=$(wildcard *.S) BDIR ?= ./
OBJS=$(SRCS:.S=.o)
LDFLAGS = -Ttext 0 -e 0 PROG = mbr
CPPFLAGS = -I $(IDIR) 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) ${PROG}: $(OBJS)
@rm -f $(PROG)
$(LD) $(LDFLAGS) -o $(PROG) $(OBJS) $(LD) $(LDFLAGS) -o $(PROG) $(OBJS)
objcopy -O binary mbr mbr.new objcopy -S -O binary mbr mbr.new
dd if=mbr.new of=mbr bs=512 count=1 dd if=mbr.new of=$(BDIR)/mbr bs=512 count=1
rm -rf mbr.new rm -f mbr.new
mv $(PROG) $(BDIR)
$(OBJS): ../def.h $(OBJS): $(SDIR)/Makefile.inc $(SDIR)/btld_conf.h
clean: clean:
rm -f *.o *.bin $(PROG) rm -f $(OBJS) $(PROG)

View File

@ -1,6 +1,6 @@
.file "mbr.S" .file "mbr.S"
#include "def.h" #include "btld_conf.h"
#define CHAR_LBA_READ '.' #define CHAR_LBA_READ '.'
#define CHAR_R 'R' #define CHAR_R 'R'
@ -8,7 +8,6 @@
#define CHAR_L 'L' #define CHAR_L 'L'
#define CHAR_B 'B' #define CHAR_B 'B'
#define CHAR_G 'G' #define CHAR_G 'G'
#define DBGMSG(c) movb $c, %al; call Lchr
#define puts(s) movw $s, %si; call Lmessage #define puts(s) movw $s, %si; call Lmessage
// 0x07C00 - 0x07DFF BIOS load us here // 0x07C00 - 0x07DFF BIOS load us here
@ -32,7 +31,6 @@ start:
// set up data segment // set up data segment
movw %ax, %ds movw %ax, %ds
DBGMSG(CHAR_S)
// relocate for PBR // relocate for PBR
// copy to 0x07a0 // copy to 0x07a0
@ -48,13 +46,12 @@ start:
ljmp $BOOTRELOCSEG, $reloc ljmp $BOOTRELOCSEG, $reloc
reloc: reloc:
DBGMSG(CHAR_R)
pushw %ds pushw %ds
popw %es popw %es
pushw %cs pushw %cs
popw %ds popw %ds
testb $DOSACTIVE, %dl testb $0x80, %dl
jnz drive_ok jnz drive_ok
puts(efdmbr) puts(efdmbr)
jmp stay_stopped jmp stay_stopped
@ -64,11 +61,10 @@ drive_ok:
movw $NDOSPART, %cx movw $NDOSPART, %cx
find_active: find_active:
DBGMSG(CHAR_L)
movb (%si), %al movb (%si), %al
cmpb $DOSACTIVE, %al cmpb $0x80, %al
je found je found
addw $PARTSZ, %si addw $16, %si //add partion size
loop find_active loop find_active
no_part: no_part:
@ -83,7 +79,6 @@ stay_stopped:
jmp stay_stopped jmp stay_stopped
found: found:
DBGMSG(CHAR_B)
movb %dl, %al movb %dl, %al
andb $0x0f, %al andb $0x0f, %al
addb $'0', %al addb $'0', %al
@ -178,16 +173,15 @@ eread: .asciz "\r\nRead error\r\n"
enoos: .asciz "No O/S\r\n" enoos: .asciz "No O/S\r\n"
enoboot: .ascii "No active partion" enoboot: .ascii "No active partion"
crlf: .asciz "\r\n" crlf: .asciz "\r\n"
endofcode: endofcode:
nop nop
// partion table
. = DOSPARTOFF // partion table start address . = DOSPARTOFF // partion table start address
pt: .fill 0x40,1,0 pt:
.fill 0x40,1,0
. = 0x1fe . = 0x1fe
signature: signature:
.short DOSMBR_SIGNATURE .short 0xaa55
. = 0x200 . = 0x200

21
u.h Normal file
View 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;