Compare commits

..

No commits in common. "4361041d09d939f35fba361b4ca2a0cca72576d9" and "e71c7ce5557ed331e01ef48ab2e85f0ab6b37760" have entirely different histories.

12 changed files with 251 additions and 412 deletions

View file

@ -9,8 +9,7 @@ STAGE0_SRCS = boot0.asm \
STAGE1_SRCS = boot1.asm \ STAGE1_SRCS = boot1.asm \
const.inc \ const.inc \
a20.inc \ a20.inc
multiboot.inc
.PHONY: all .PHONY: all
all: $(TARGET) all: $(TARGET)
@ -28,5 +27,3 @@ clean:
.PHONY: install .PHONY: install
install: $(TARGET) install: $(TARGET)
@ mkdir -p $(DESTDIR) @ mkdir -p $(DESTDIR)
install stpdboot.sys $(DESTDIR)

View file

@ -1,33 +1,2 @@
#+TITLE: StupidOS Bootloader #+TITLE: StupidOS Bootloader
#+begin_src
0x100000 +-----------------------+
| |
| Reserved |
| |
0x080000 +-----------------------+
| |
| Kernel preload |
| |
0x00F000 +-----------------------+
| |
| buffer |
| |
0x008000 +-----------------------+
| |
| Boot0 |
| |
0x007000 +-----------------------+
| |
| Real mode stack |
| |
0x006000 +-----------------------+
| |
| Boot1 |
| |
0x001000 +-----------------------+
| |
| Reserved (BIOS & IVT) |
| |
0x000000 +-----------------------+
#+end_src

View file

@ -1,18 +1,9 @@
INCLUDE 'const.inc' INCLUDE 'const.inc'
INCLUDE 'multiboot.inc'
ORG STAGE1_BASE ORG STAGE1_BASE
USE16 USE16
jmp _start stage2:
mb_header MultibootHeader mb_header
_start:
cmp eax, MULTIBOOT_MAGIC
je .multiboot
;; non multiboot process
push cs push cs
pop ds pop ds
@ -22,22 +13,9 @@ _start:
call a20_enable call a20_enable
jc .error_a20 jc .error_a20
; detect memory
call memory_get_map
jc .error_memory
xchg bx, bx
call video_setup
.multiboot:
jmp .hang jmp .hang
.error_memory:
mov si, msg_error_memory
jmp .error
.error_a20: .error_a20:
mov si, msg_error_a20 mov si, msg_error_a20
.error:
call bios_print call bios_print
.hang: .hang:
hlt hlt
@ -45,21 +23,6 @@ _start:
INCLUDE 'a20.inc' INCLUDE 'a20.inc'
INCLUDE 'utils.inc' INCLUDE 'utils.inc'
INCLUDE 'memory.inc'
INCLUDE 'video.inc'
msg_stage2 db "StupidOS Bootloader (Stage 1)", CR, LF, 0 msg_stage2 db "StupidOS Bootloader (Stage 1)", 0x0D, 0x0A, 0
msg_error_a20 db "ERROR: can't enable a20 line", CR, LF, 0 msg_error_a20 db "ERROR: can't enable a20 line", 0x0D, 0x0A, 0
msg_error_memory db "ERROR: can't detect available memory", CR, LF, 0
;;
bi_screen_width: dw 0
bi_screen_height: dw 0
_edata:
; BSS
rb 0x4000
_end:

View file

@ -1,6 +1,5 @@
CR = 0x0D CR = 0x0D
LF = 0x0A LF = 0x0A
; -------- Address ---------- ; -------- Address ----------
STAGE0_BASE = 0x7C00 STAGE0_BASE = 0x7C00
STAGE1_BASE = 0x1000 STAGE1_BASE = 0x1000
@ -8,7 +7,3 @@ DISK_BUFFER = 0x8000
KERNEL_PRELOAD = 0xF000 KERNEL_PRELOAD = 0xF000
STACK_TOP = 0x7000 STACK_TOP = 0x7000
; ---------- Video ------------
VIDEO_WIDTH = 1024
VIDEO_HEIGHT = 768
VIDEO_DEPTH = 32

View file

@ -1,28 +0,0 @@
; 0xE820 Get System Memory Map
; EAX=0x0000E820
; EDX=0x534D4150
; EBX=0x0 or continuation value
; ECX=buffer size
; ES:SI = buffer
memory_do_E820:
ret
memory_get_map:
call memory_do_E820
jnc .end
; try 0x88
clc
mov ah, 0x88
int 0x15
jc .error
test ax, ax
je .error
.end:
clc
ret
.error:
stc
ret

View file

@ -1,3 +0,0 @@
video_setup:
ret

View file

@ -1,25 +1,27 @@
AS = fasm AS = fasm
RM = rm -f RM = rm -f
INSTALL = install INSTALL = install
KERNEL = vmstupid.sys KERNEL = vmstupid
SRCS = kernel.asm \ SRCS = kernel.asm \
const.inc \ const.inc \
mm/mm.inc boot/multiboot.inc \
boot/boot.inc \
.PHONY: all mm/mm.inc
all: $(KERNEL)
.PHONY: all
$(KERNEL): $(SRCS) all: $(KERNEL)
$(AS) kernel.asm $@
$(KERNEL): $(SRCS)
.PHONY: clean $(AS) kernel.asm $@
clean:
$(RM) $(KERNEL) .PHONY: clean
clean:
.PHONY: install $(RM) $(KERNEL)
install: $(KERNEL)
@ mkdir -p $(DESTDIR) .PHONY: install
install $< $(DESTDIR) install: $(KERNEL)
@ mkdir -p $(DESTDIR)
.PHONY: all clean install $< $(DESTDIR)
.PHONY: all clean

35
kernel/boot/boot.inc Normal file
View file

@ -0,0 +1,35 @@
ORG 0x100000
ALIGN 4
USE32
INCLUDE 'boot/multiboot.inc'
INCLUDE 'const.inc'
mb_header MultibootHeader MB_FLAGS, mb_header, VIDEO_WIDTH, VIDEO_HEIGHT, VIDEO_DEPTH
_start:
cli
cmp eax, MULTIBOOT_MAGIC
jne hang
; iterate over memory
;
;
xor esi, esi
mov edi, kernel_page_table - KBASE
mov ecx, kernel_page_directory - KBASE
mov cr3, ecx
mov ecx, cr0
hang:
hlt
jmp $-1
; SEGMENT readable writable
boot_struct dd 0x0

View file

@ -1,107 +1,106 @@
MULTIBOOT_HDR_MAGIC = 0x1BADB002 MULTIBOOT_HDR_MAGIC = 0x1BADB002
MULTIBOOT_MAGIC = 0x2BADB002 MULTIBOOT_MAGIC = 0x2BADB002
MULTIBOOT_HDR_ALIGN = 0x1 MULTIBOOT_HDR_ALIGN = 0x1
MULTIBOOT_HDR_MEMINFO = 0x2 MULTIBOOT_HDR_MEMINFO = 0x2
MULTIBOOT_HDR_VIDEO = 0x4 MULTIBOOT_HDR_VIDEO = 0x4
MULTIBOOT_FLAGS = MULTIBOOT_HDR_ALIGN or MULTIBOOT_HDR_MEMINFO or MULTIBOOT_HDR_VIDEO
struc MultibootHeader flags,addr,width,height,depth
struc MultibootHeader addr {
{ .magic dd MULTIBOOT_HDR_MAGIC
.magic dd MULTIBOOT_HDR_MAGIC .flags dd flags
.flags dd MULTIBOOT_FLAGS .checksum dd -(MULTIBOOT_HDR_MAGIC + flags)
.checksum dd -(MULTIBOOT_HDR_MAGIC + MULTIBOOT_FLAGS)
; address fields (we'll just skip them)
; address fields (we'll just skip them) .header_addr dd addr
.header_addr dd addr .load_addr dd 0x100000
.load_addr dd STAGE1_BASE .load_end_addr dd _edata - KBASE
.load_end_addr dd _edata - STAGE1_BASE .bss_end_addr dd _end - KBASE
.bss_end_addr dd _end - STAGE1_BASE .entry_addr dd _start
.entry_addr dd _start
; Video mode
; Video mode .mode_type dd 0x0
.mode_type dd 0x0 .width dd width
.width dd VIDEO_WIDTH .height dd height
.height dd VIDEO_HEIGHT .depth dd depth
.depth dd VIDEO_DEPTH }
}
struc MultibootData
struc MultibootData {
{ .flags dd ?
.flags dd ?
; if flags[0] is set
; if flags[0] is set .mem_lower dd ?
.mem_lower dd ? .mem_upper dd ?
.mem_upper dd ?
; if flags[1] is set
; if flags[1] is set .boot_device dd ?
.boot_device dd ?
; if flags[2] is set
; if flags[2] is set .cmdline dd ?
.cmdline dd ?
; if flags[3] is set
; if flags[3] is set .mods_count dd ?
.mods_count dd ? .mods_addr dd ?
.mods_addr dd ?
; if flags[4] is set
; if flags[4] is set .syms dd 4 dup ?
.syms dd 4 dup ?
; if flags[6] is set
; if flags[6] is set .mmap_length dd ?
.mmap_length dd ? .mmap_addr dd ?
.mmap_addr dd ?
; if flags[7] is set
; if flags[7] is set .drives_length dd ?
.drives_length dd ? .drives_addr dd ?
.drives_addr dd ?
; if flags[8] is set
; if flags[8] is set .config_table dd ?
.config_table dd ?
; if flags[9] is set
; if flags[9] is set .bootloader_name dd ?
.bootloader_name dd ?
; if flags[10] is set
; if flags[10] is set .apm_table dd ?
.apm_table dd ?
; if flags[11] is set
; if flags[11] is set .vbe_control_info dd ?
.vbe_control_info dd ? .vbe_mode_info dd ?
.vbe_mode_info dd ? .vbe_mode dw ?
.vbe_mode dw ? .vbe_if_seg dw ?
.vbe_if_seg dw ? .vbe_if_off dw ?
.vbe_if_off dw ? .vbe_if_length dw ?
.vbe_if_length dw ?
; if flags[12] is set
; if flags[12] is set .fb_addr dq ?
.fb_addr dq ? .fb_pitch dd ?
.fb_pitch dd ? .fb_width dd ?
.fb_width dd ? .fb_height dd ?
.fb_height dd ? .fb_bpp db ?
.fb_bpp db ? .fb_type db ?
.fb_type db ? .fb_misc dw 3 dup ?
.fb_misc dw 3 dup ? }
}
MULTIBOOT_DATA_MEM = 0x0001
MULTIBOOT_DATA_MEM = 0x0001 MULTIBOOT_DATA_BOOTDEV = 0x0002
MULTIBOOT_DATA_BOOTDEV = 0x0002 MULTIBOOT_DATA_CMDLINE = 0x0004
MULTIBOOT_DATA_CMDLINE = 0x0004 MULTIBOOT_DATA_MODULES = 0x0008
MULTIBOOT_DATA_MODULES = 0x0008 MULTIBOOT_DATA_MMAP = 0x0040
MULTIBOOT_DATA_MMAP = 0x0040 MULTIBOOT_DATA_DRIVES = 0x0080
MULTIBOOT_DATA_DRIVES = 0x0080 MULTIBOOT_DATA_BOOTLOADER_NAME = 0x0200
MULTIBOOT_DATA_BOOTLOADER_NAME = 0x0200 MULTIBOOT_DATA_VBE = 0x0800
MULTIBOOT_DATA_VBE = 0x0800 MULTIBOOT_DATA_FB = 0x1000
MULTIBOOT_DATA_FB = 0x1000
struc MultibootMMap
struc MultibootMMap {
{ .size dd ?
.size dd ? .addr dq ?
.addr dq ? .length dq ?
.length dq ? .type dd ?
.type dd ? }
}
MULTIBOOT_MEMORY_AVAILABLE = 0x1
MULTIBOOT_MEMORY_AVAILABLE = 0x1 MULTIBOOT_MEMORY_RESERVED = 0x2
MULTIBOOT_MEMORY_RESERVED = 0x2 MULTIBOOT_MEMORY_ACPI = 0x3
MULTIBOOT_MEMORY_ACPI = 0x3 MULTIBOOT_MEMORY_NVS = 0x4
MULTIBOOT_MEMORY_NVS = 0x4 MULTIBOOT_MEMORY_BADPARAM = 0x5
MULTIBOOT_MEMORY_BADPARAM = 0x5

View file

@ -1,46 +1,53 @@
KBASE = 0xC0000000 KBASE = 0xC0000000
PSIZE = 0x1000 PSIZE = 0x1000
; --------- VERSION ------------- ; --------- VERSION -------------
VERSION_MAJOR = 1 VERSION_MAJOR = 1
VERSION_MINOR = 0 VERSION_MINOR = 0
; --------- Registers ------------
CR0_PE = 0x00000001 ; --------- BOOT PARAMS ---------
CR0_MP = 0x00000002 MB_FLAGS = MULTIBOOT_HDR_ALIGN or MULTIBOOT_HDR_MEMINFO or MULTIBOOT_HDR_VIDEO
CR0_EM = 0x00000004 VIDEO_WIDTH = 1024
CR0_TS = 0x00000008 VIDEO_HEIGHT = 768
CR0_ET = 0x00000010 VIDEO_DEPTH = 32
CR0_NE = 0x00000020
CR0_WP = 0x00010000 ; --------- Registers ------------
CR0_AM = 0x00040000 CR0_PE = 0x00000001
CR0_NW = 0x20000000 CR0_MP = 0x00000002
CR0_CD = 0x40000000 CR0_EM = 0x00000004
CR0_PG = 0x80000000 CR0_TS = 0x00000008
CR0_ET = 0x00000010
CR3_PWT = 0x08 CR0_NE = 0x00000020
CR3_PCD = 0x10 CR0_WP = 0x00010000
CR0_AM = 0x00040000
CR4_VME = 0x0000001 CR0_NW = 0x20000000
CR4_PVI = 0x0000002 CR0_CD = 0x40000000
CR4_TSD = 0x0000004 CR0_PG = 0x80000000
CR4_DE = 0x0000008
CR4_PSE = 0x0000010 CR3_PWT = 0x08
CR4_PAE = 0x0000020 CR3_PCD = 0x10
CR4_MCE = 0x0000040
CR4_PGE = 0x0000080 CR4_VME = 0x0000001
CR4_PCE = 0x0000100 CR4_PVI = 0x0000002
CR4_OSDXSR = 0x0000200 CR4_TSD = 0x0000004
CR4_OSXMMEXCPT = 0x0000400 CR4_DE = 0x0000008
CR4_UMIP = 0x0000800 CR4_PSE = 0x0000010
CR4_VMXE = 0x0002000 CR4_PAE = 0x0000020
CR4_SMXE = 0x0004000 CR4_MCE = 0x0000040
CR4_FSGSBASE = 0x0010000 CR4_PGE = 0x0000080
CR4_PCIDE = 0x0020000 CR4_PCE = 0x0000100
CR4_OSXSAVE = 0x0040000 CR4_OSDXSR = 0x0000200
CR4_SMEP = 0x0100000 CR4_OSXMMEXCPT = 0x0000400
CR4_SMAP = 0x0200000 CR4_UMIP = 0x0000800
CR4_PKE = 0x0400000 CR4_VMXE = 0x0002000
CR4_CET = 0x0800000 CR4_SMXE = 0x0004000
CR4_PKS = 0x1000000 CR4_FSGSBASE = 0x0010000
CR4_PCIDE = 0x0020000
CR4_OSXSAVE = 0x0040000
CR4_SMEP = 0x0100000
CR4_SMAP = 0x0200000
CR4_PKE = 0x0400000
CR4_CET = 0x0800000
CR4_PKS = 0x1000000

View file

@ -1,18 +1,15 @@
INCLUDE 'const.inc' INCLUDE 'boot/boot.inc'
ORG KBASE ORG $ + KBASE
USE32
INCLUDE 'mm/mm.inc'
jmp kmain
kmain:
INCLUDE 'mm/mm.inc' nop
kmain: _edata:
nop
; BSS
_edata: rb 0x4000
; BSS _end:
rb 0x4000
_end:

View file

@ -32,24 +32,7 @@ typedef struct
uint8_t fs_type[8]; uint8_t fs_type[8];
} __attribute__((packed)) BiosParamBlock; } __attribute__((packed)) BiosParamBlock;
typedef struct
{
uint8_t name[8];
uint8_t ext[3];
uint8_t attr;
uint16_t reserved0;
uint16_t creation_time;
uint16_t creation_date;
uint16_t access_date;
uint16_t reserved1;
uint16_t mod_time;
uint16_t mod_date;
uint16_t start;
uint32_t size;
} __attribute__((packed)) Entry;
static const char *prg_name; static const char *prg_name;
static int sector_size = 512;
static void static void
fatal(const char *str, ...) fatal(const char *str, ...)
@ -65,104 +48,27 @@ fatal(const char *str, ...)
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
static void
read_sector(uint8_t *dest, int sect, FILE *fp)
{
if (fseek(fp, sect*sector_size, SEEK_SET) != 0) goto fatal_sect;
if (fread(dest, 1, sector_size, fp) != sector_size) goto fatal_sect;
return;
fatal_sect:
fatal("Can't read sector %d", sect);
}
static void
dump_bpb(BiosParamBlock *bpb)
{
char label[12];
printf("Bytes per logical sector: %hd\n", bpb->bytes_per_sector);
sector_size = bpb->bytes_per_sector;
printf("Logical sectors per cluster: %d\n", bpb->sectors_per_cluster);
printf("Reserved logical sectors: %hd\n", bpb->reserved_sectors);
printf("Number of FATs: %d\n", bpb->number_of_FATs);
printf("Root directory entries: %hd\n", bpb->root_entries);
printf("Total logical sectors: %hd\n", bpb->logical_sectors);
printf("Logical sectors per FAT: %hd\n", bpb->sectors_per_FAT);
printf("Serial: %X\n", bpb->serial);
memset(label, 0, 12);
strncpy(label, bpb->label, 11);
printf("Label: '%s'\n", label);
printf("signature: %X\n", bpb->signature);
}
static void
dump_entry(Entry *entry)
{
char filename[9];
char ext[4];
int i;
if (entry->name[0] == 0x0) return;
memset(filename, 0, 9);
strncpy(filename, entry->name, 8);
memset(ext, 0, 4);
strncpy(ext, entry->ext, 3);
for (i = 7; i > 0; i--)
{
if (filename[i] == ' ')
{
filename[i] = '\0';
}
else
{
break;
}
}
printf("%s.%s\n", filename, ext);
}
static void static void
dump(const char *img) dump(const char *img)
{ {
FILE *fp; FILE *fp;
BiosParamBlock *bpb; BiosParamBlock bpb;
uint8_t buffer[512]; char label[12];
int root_start;
int root_size;
int i;
int j;
fp = fopen(img, "rb"); fp = fopen(img, "rb");
if (fp == NULL) fatal("Can't open '%s': %s", img, strerror(errno)); if (fp == NULL) fatal("Can't open '%s': %s", img, strerror(errno));
read_sector(buffer, 0, fp); if (fread(&bpb, 1, sizeof(BiosParamBlock), fp) != sizeof(BiosParamBlock))
if (buffer[511] != 0xAA || buffer[510] != 0x55)
{ {
fatal("MBR not found"); fatal("Can't read BPB");
}
bpb = (BiosParamBlock *)buffer;
dump_bpb(bpb);
root_start = bpb->sectors_per_FAT * bpb->number_of_FATs;
root_start += bpb->reserved_sectors;
root_size = bpb->root_entries / (sector_size >> 0x5);
for (i = 0; i < root_size; i++)
{
read_sector(buffer, root_start + i, fp);
for (j = 0; j < sector_size; j+=32)
{
dump_entry((Entry *)(buffer + j));
}
} }
printf("Bytes per logical sector: %hd\n", bpb.bytes_per_sector);
printf("Logical sectors per cluster: %d\n", bpb.sectors_per_cluster);
memset(label, 0, 12);
strncpy(label, bpb.label, 11);
printf("Label: '%s'\n", label);
printf("signature: %X\n", bpb.signature);
fclose(fp); fclose(fp);
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
} }