forked from PoliEcho-holding-org/kern
Got the OS to boot from new disk image
- Pretty much rewrote stage1.asm - Changed some addresses in stage2.asm and in memory/adresses.h - Changed stage3.c to read root INode and it's dirEntries to find kernel.bin and term16n.fnt - Made a fake ls command in kernel.c, just so it prints something - Fixed makedisk.c to make the disk image properly - Changed Makefile to compile makedisk.c and then run makedisk - Added makedisk executable to .gitignore
This commit is contained in:
@@ -1,2 +1,3 @@
|
|||||||
build
|
build
|
||||||
kern.iso
|
kern.iso
|
||||||
|
makedisk
|
||||||
|
|||||||
@@ -14,24 +14,11 @@ FONTS = testfont term16n
|
|||||||
.PHONY: os clean run
|
.PHONY: os clean run
|
||||||
|
|
||||||
# Main compilation target
|
# Main compilation target
|
||||||
os: $(BUILD) filesystem
|
os: $(BUILD) bootloader kernel $(C_FILES) $(FONTS)
|
||||||
|
@cc ./makedisk.c -o ./makedisk
|
||||||
|
@./makedisk # TODO: List of files
|
||||||
@echo "\nDone!\n"
|
@echo "\nDone!\n"
|
||||||
|
|
||||||
# Filesystem
|
|
||||||
filesystem: bootloader kernel $(C_FILES) $(FONTS)
|
|
||||||
@echo "Building filesystem..."
|
|
||||||
@$(AS) -fbin -o $(BUILD)/filetable.bin $(SRC)/filetable.asm
|
|
||||||
@dd if=/dev/zero of=kern.iso bs=512 count=2880 status=none
|
|
||||||
# TODO: Make this not so manual
|
|
||||||
@dd if=$(BUILD)/boot.bin of=kern.iso bs=512 seek=0 conv=notrunc status=none
|
|
||||||
@dd if=$(BUILD)/filetable.bin of=kern.iso bs=512 seek=15 conv=notrunc status=none
|
|
||||||
@dd if=$(BUILD)/kernel.bin of=kern.iso bs=512 seek=16 conv=notrunc status=none
|
|
||||||
@dd if=$(BUILD)/term16n.fnt of=kern.iso bs=512 seek=56 conv=notrunc status=none
|
|
||||||
@dd if=$(BUILD)/testfont.fnt of=kern.iso bs=512 seek=60 conv=notrunc status=none
|
|
||||||
@dd if=$(SRC)/fs/test.txt of=kern.iso bs=512 seek=64 conv=notrunc status=none
|
|
||||||
@dd if=$(BUILD)/calc.bin of=kern.iso bs=512 seek=65 conv=notrunc status=none
|
|
||||||
@dd if=$(BUILD)/editor.bin of=kern.iso bs=512 seek=71 conv=notrunc status=none
|
|
||||||
|
|
||||||
$(BUILD):
|
$(BUILD):
|
||||||
@[ -d $(BUILD) ] || mkdir $(BUILD)
|
@[ -d $(BUILD) ] || mkdir $(BUILD)
|
||||||
@rm -rf $(BUILD)/*
|
@rm -rf $(BUILD)/*
|
||||||
@@ -55,12 +42,14 @@ kernel: $(SRC)/kernel.c
|
|||||||
@$(LD) -T$(SRC)/kernel.ld -z notext --oformat binary -o $(BUILD)/kernel.bin $(BUILD)/kernel.o
|
@$(LD) -T$(SRC)/kernel.ld -z notext --oformat binary -o $(BUILD)/kernel.bin $(BUILD)/kernel.o
|
||||||
@rm $(BUILD)/kernel.o
|
@rm $(BUILD)/kernel.o
|
||||||
|
|
||||||
|
# This target compiles *.c (except kernel.c)
|
||||||
$(C_FILES):
|
$(C_FILES):
|
||||||
@echo "Compiling $(SRC)/$@.c..."
|
@echo "Compiling $(SRC)/$@.c..."
|
||||||
@$(CC) $(CFLAGS) -o $(BUILD)/$@.o -c $(SRC)/$@.c
|
@$(CC) $(CFLAGS) -o $(BUILD)/$@.o -c $(SRC)/$@.c
|
||||||
@$(LD) -T$(SRC)/$@.ld -z notext --oformat binary -o $(BUILD)/$@.bin $(BUILD)/$@.o
|
@$(LD) -T$(SRC)/$@.ld -z notext --oformat binary -o $(BUILD)/$@.bin $(BUILD)/$@.o
|
||||||
@rm $(BUILD)/$@.o
|
@rm $(BUILD)/$@.o
|
||||||
|
|
||||||
|
# This target builds all fonts inside src/fonts
|
||||||
$(FONTS):
|
$(FONTS):
|
||||||
@echo "Assembling $(SRC)/fonts/$@.asm..."
|
@echo "Assembling $(SRC)/fonts/$@.asm..."
|
||||||
@$(AS) -fbin -o $(BUILD)/$@.fnt $(SRC)/fonts/$@.asm
|
@$(AS) -fbin -o $(BUILD)/$@.fnt $(SRC)/fonts/$@.asm
|
||||||
|
|||||||
+25
-12
@@ -2,25 +2,28 @@
|
|||||||
#define ADDRESSES_H
|
#define ADDRESSES_H
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Memory layout of addresses 0x0000 - 0xA000
|
* Memory layout of addresses 0x0000 - 0x12000
|
||||||
* 0x0000-0x0fff - Probably shouldn't mess with this? idk it feels wrong
|
* 0x0000-0x0fff - Probably shouldn't mess with this? idk it feels wrong
|
||||||
* 0x1000-0x17ff - Free
|
* 0x1000-0x17ff - Free
|
||||||
* 0x1800-0x1fff - Global Variables
|
* 0x1800-0x1fff - Global Variables
|
||||||
* 0x2000-0x2fff - Larger structs
|
* 0x2000-0x2fff - Larger structs
|
||||||
* 0x3000-0x3fff - Filesystem area
|
* 0x3000-0x3fff - Free
|
||||||
* 0x4000-0x4fff - Font area
|
* 0x4000-0x4fff - Font area
|
||||||
* 0x6000-0x84ff - Free
|
* 0x6000-0x6fff - VBE info area
|
||||||
* 0x8500-0x8fff - SMAP Area
|
* 0x7000-0x7bff - SMAP Area
|
||||||
* 0x9000-0x9fff - VBE info area
|
* 0x7c00-0x8bff - Bootblock
|
||||||
|
* 0x8c00-0x9bff - Superblock (i think)
|
||||||
|
* 0x9c00-0xafff - Free
|
||||||
|
* 0xb000-0xbfff - Bootloader first INode
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Global Variables
|
// Global Variables 0x1800-0x1fff
|
||||||
#define SLEEP_TIMER 0x1800
|
#define SLEEP_TIMER 0x1800
|
||||||
#define CURRENT_PAGE_DIR_ADDR 0x1804
|
#define CURRENT_PAGE_DIR_ADDR 0x1804
|
||||||
#define PHYS_MEM_MAX_BLOCKS 0x1808
|
#define PHYS_MEM_MAX_BLOCKS 0x1808
|
||||||
#define PHYS_MEM_USED_BLOCKS 0x180C
|
#define PHYS_MEM_USED_BLOCKS 0x180C
|
||||||
|
|
||||||
// Some structs
|
// Some structs 0x2000-0x2fff
|
||||||
#define TERMINAL_INFO_LOC 0x2000
|
#define TERMINAL_INFO_LOC 0x2000
|
||||||
#define KEYBOARD_STATE_LOC 0x2100
|
#define KEYBOARD_STATE_LOC 0x2100
|
||||||
#define DATETIME_LOC 0x2200
|
#define DATETIME_LOC 0x2200
|
||||||
@@ -33,12 +36,22 @@
|
|||||||
#define FONT_WIDTH (FONT_LOC)
|
#define FONT_WIDTH (FONT_LOC)
|
||||||
#define FONT_HEIGHT (FONT_LOC + 1)
|
#define FONT_HEIGHT (FONT_LOC + 1)
|
||||||
|
|
||||||
// Smap Area 0x8500 - 0x8fff
|
// VBE Info Area 0x6000 - 0x6fff
|
||||||
#define SMAP_ENTRY_COUNT 0x8500
|
#define MODE_INFO_BLOCK_LOC 0x6000 // 512 Bytes
|
||||||
#define SMAP_ENTRIES 0x8504
|
|
||||||
|
|
||||||
// VBE Info Area 0x9000 - 0x9fff
|
// Smap Area 0x7000 - 0x7bff
|
||||||
#define MODE_INFO_BLOCK_LOC 0x9000 // 512 Bytes
|
#define SMAP_ENTRY_COUNT 0x7000
|
||||||
|
#define SMAP_ENTRIES 0x7004
|
||||||
|
|
||||||
|
// Bootblock 0x7c00-0x9bff
|
||||||
|
#define BOOTBLOCK_LOC 0x7c00
|
||||||
|
|
||||||
|
// Superblock 0x9c00-0xabff
|
||||||
|
#define SUPERBLOCK_LOC 0x8c00
|
||||||
|
|
||||||
|
// First INode from bootloader
|
||||||
|
#define BOOT_FIRST_INODE_LOC 0xb000
|
||||||
|
#define SCRATCH_BLOCK_LOC 0xc000
|
||||||
|
|
||||||
// Other addresses
|
// Other addresses
|
||||||
#define KERNEL_LOC 0x100000
|
#define KERNEL_LOC 0x100000
|
||||||
|
|||||||
+9
-6
@@ -83,10 +83,9 @@ int main(int argc, char** argv) {
|
|||||||
printf("Free blocks: %d (%d Bytes)\n", bytesToBlocks(diskSize) - writtenBlocks, diskSize - writtenBlocks * FS_BLOCK_SIZE);
|
printf("Free blocks: %d (%d Bytes)\n", bytesToBlocks(diskSize) - writtenBlocks, diskSize - writtenBlocks * FS_BLOCK_SIZE);
|
||||||
|
|
||||||
// Pad out to the whole disk size
|
// Pad out to the whole disk size
|
||||||
/*
|
|
||||||
for (uint32_t i = 0; i < bytesToBlocks(diskSize) - writtenBlocks; i++) {
|
for (uint32_t i = 0; i < bytesToBlocks(diskSize) - writtenBlocks; i++) {
|
||||||
assert(fwrite(nullBlock, FS_BLOCK_SIZE, 1, imagePtr) == 1);
|
assert(fwrite(nullBlock, FS_BLOCK_SIZE, 1, imagePtr) == 1);
|
||||||
} */
|
}
|
||||||
|
|
||||||
// Cleanup
|
// Cleanup
|
||||||
for (uint32_t i = 0; i < fileCount; i++) {
|
for (uint32_t i = 0; i < fileCount; i++) {
|
||||||
@@ -120,7 +119,7 @@ void writeSuperblock() {
|
|||||||
superblock.inodeCount = fileCount; // 2 reserved INodes (0 - Invalid, 1 - Root)
|
superblock.inodeCount = fileCount; // 2 reserved INodes (0 - Invalid, 1 - Root)
|
||||||
superblock.firstInodeBitmapBlock = 2; // Block 0 - Boot, Block 1 - Superblock
|
superblock.firstInodeBitmapBlock = 2; // Block 0 - Boot, Block 1 - Superblock
|
||||||
superblock.inodeBitmapBlockCount = superblock.inodeCount / (FS_BLOCK_SIZE * 8) + ((superblock.inodeCount % (FS_BLOCK_SIZE * 8) > 0) ? 1 : 0);
|
superblock.inodeBitmapBlockCount = superblock.inodeCount / (FS_BLOCK_SIZE * 8) + ((superblock.inodeCount % (FS_BLOCK_SIZE * 8) > 0) ? 1 : 0);
|
||||||
superblock.firstDataBitmapBlock = superblock.firstInodeBlock + superblock.inodeBitmapBlockCount;
|
superblock.firstDataBitmapBlock = superblock.firstInodeBitmapBlock + superblock.inodeBitmapBlockCount;
|
||||||
superblock.inodeBlockCount = bytesToBlocks(superblock.inodeCount * sizeof(inode_t));
|
superblock.inodeBlockCount = bytesToBlocks(superblock.inodeCount * sizeof(inode_t));
|
||||||
|
|
||||||
dataBlocks = bytesToBlocks(diskSize);
|
dataBlocks = bytesToBlocks(diskSize);
|
||||||
@@ -195,14 +194,17 @@ void writeINodeBlocks() {
|
|||||||
.id = 1,
|
.id = 1,
|
||||||
.filetype = FILETYPE_DIR,
|
.filetype = FILETYPE_DIR,
|
||||||
.sizeBytes = sizeof(dirEntry_t) * fileCount,
|
.sizeBytes = sizeof(dirEntry_t) * fileCount,
|
||||||
.sizeSectors = bytesToSectors(inode.sizeBytes),
|
// .sizeSectors = bytesToSectors(inode.sizeBytes), Set below
|
||||||
.timestamp = defaultTimestamp,
|
.timestamp = defaultTimestamp,
|
||||||
.extent[0] = (extent_t) {
|
.extent[0] = (extent_t) {
|
||||||
.firstBlock = superblock.firstDataBlock,
|
.firstBlock = superblock.firstDataBlock,
|
||||||
.length = bytesToBlocks(inode.sizeBytes),
|
// .length = bytesToBlocks(inode.sizeBytes), Set below
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inode.sizeSectors = bytesToSectors(inode.sizeBytes);
|
||||||
|
inode.extent[0].length = bytesToBlocks(inode.sizeBytes);
|
||||||
|
|
||||||
assert(fwrite(&inode, sizeof(inode), 1, imagePtr) == 1);
|
assert(fwrite(&inode, sizeof(inode), 1, imagePtr) == 1);
|
||||||
|
|
||||||
// INode 2 - Bootloader (stage 3) followed by other INodes
|
// INode 2 - Bootloader (stage 3) followed by other INodes
|
||||||
@@ -216,8 +218,9 @@ void writeINodeBlocks() {
|
|||||||
inode.timestamp = defaultTimestamp;
|
inode.timestamp = defaultTimestamp;
|
||||||
inode.extent[0] = (extent_t) {
|
inode.extent[0] = (extent_t) {
|
||||||
.firstBlock = block,
|
.firstBlock = block,
|
||||||
.length = bytesToBlocks(inode.sizeBytes),
|
// .length = bytesToBlocks(inode.sizeBytes),
|
||||||
};
|
};
|
||||||
|
inode.extent[0].length = bytesToBlocks(inode.sizeBytes);
|
||||||
|
|
||||||
assert(fwrite(&inode, sizeof(inode), 1, imagePtr) == 1);
|
assert(fwrite(&inode, sizeof(inode), 1, imagePtr) == 1);
|
||||||
|
|
||||||
|
|||||||
+16
-43
@@ -25,10 +25,10 @@
|
|||||||
#include <color.h>
|
#include <color.h>
|
||||||
#include <fs/fs.h>
|
#include <fs/fs.h>
|
||||||
|
|
||||||
#define PROMPT "#> "
|
#define PROMPT "/ #> "
|
||||||
|
|
||||||
// Function declarations
|
// Function declarations
|
||||||
void printFiletable(char* ft);
|
void listFiles();
|
||||||
void printPhysicalMemmap();
|
void printPhysicalMemmap();
|
||||||
|
|
||||||
__attribute__ ((section("entry")))
|
__attribute__ ((section("entry")))
|
||||||
@@ -72,12 +72,10 @@ void main() {
|
|||||||
mallocPhysicalAddr = kernelMallocPhysicalAddr;
|
mallocPhysicalAddr = kernelMallocPhysicalAddr;
|
||||||
mallocPages = kernelMallocPages;
|
mallocPages = kernelMallocPages;
|
||||||
|
|
||||||
// Screen setup
|
|
||||||
loadFont("term16n.fnt");
|
|
||||||
terminal->fg = FG_COLOR;
|
terminal->fg = FG_COLOR;
|
||||||
terminal->bg = BG_COLOR;
|
terminal->bg = BG_COLOR;
|
||||||
clear();
|
clear();
|
||||||
printf("kern.\n\n");
|
print("kern.\n\n");
|
||||||
|
|
||||||
// Run Interactive Shell Program
|
// Run Interactive Shell Program
|
||||||
// TODO: Make it in another file
|
// TODO: Make it in another file
|
||||||
@@ -174,14 +172,14 @@ void main() {
|
|||||||
printf(" exit | Exits shell\n");
|
printf(" exit | Exits shell\n");
|
||||||
printf(" gfx | Does a graphics test\n");
|
printf(" gfx | Does a graphics test\n");
|
||||||
printf(" help | Prints this message\n");
|
printf(" help | Prints this message\n");
|
||||||
printf(" ls | Lists all available files\n");
|
printf(" ls | Lists files in current directory\n");
|
||||||
printf(" memmap | Prints the memory map and info\n");
|
printf(" memmap | Prints the memory map and info\n");
|
||||||
printf(" reboot | Reboots the system\n");
|
printf(" reboot | Reboots the system\n");
|
||||||
printf(" sleep | Sleeps for input number of seconds\n");
|
printf(" sleep | Sleeps for input number of seconds\n");
|
||||||
printf(" soundtest | Plays a tune :)\n");
|
printf(" soundtest | Plays a tune :)\n");
|
||||||
printf(" test | Performs tests\n");
|
printf(" test | Performs tests\n");
|
||||||
} else if (strcmp(argv[0], "ls") == 0) {
|
} else if (strcmp(argv[0], "ls") == 0) {
|
||||||
printFiletable(filetable);
|
listFiles();
|
||||||
} else if (strcmp(argv[0], "memmap") == 0) {
|
} else if (strcmp(argv[0], "memmap") == 0) {
|
||||||
printPhysicalMemmap();
|
printPhysicalMemmap();
|
||||||
} else if (strcmp(argv[0], "reboot") == 0) {
|
} else if (strcmp(argv[0], "reboot") == 0) {
|
||||||
@@ -269,8 +267,6 @@ void main() {
|
|||||||
mallocVirtualAddr = kernelMallocVirtualAddr;
|
mallocVirtualAddr = kernelMallocVirtualAddr;
|
||||||
mallocPhysicalAddr = kernelMallocPhysicalAddr;
|
mallocPhysicalAddr = kernelMallocPhysicalAddr;
|
||||||
mallocPages = kernelMallocPages;
|
mallocPages = kernelMallocPages;
|
||||||
} else if (strcmp(file->filetype, "tab") == 0) {
|
|
||||||
printFiletable(entryPoint);
|
|
||||||
} else if (strcmp(file->filetype, "fnt") == 0) {
|
} else if (strcmp(file->filetype, "fnt") == 0) {
|
||||||
printf("Loading %s...\n", file->filename);
|
printf("Loading %s...\n", file->filename);
|
||||||
memcpy(entryPoint, (char*)FONT_LOC, file->length * 512);
|
memcpy(entryPoint, (char*)FONT_LOC, file->length * 512);
|
||||||
@@ -299,40 +295,17 @@ void main() {
|
|||||||
while (1); // Just hang
|
while (1); // Just hang
|
||||||
}
|
}
|
||||||
|
|
||||||
void printFiletable(char* ft) {
|
void listFiles() {
|
||||||
while (*ft != '\0') {
|
// TODO: Make this real
|
||||||
char filename[15] = { 0 };
|
printf("Total 8\n");
|
||||||
uint8_t offset = 0;
|
printf(". [dir]\n");
|
||||||
for (uint8_t i = 0; i < 14; i++) {
|
printf(".. [dir]\n");
|
||||||
if (i == 9) {
|
printf("stage3.bin 2868B\n");
|
||||||
filename[offset++] = '.';
|
printf("kernel.bin 13536B\n");
|
||||||
continue;
|
printf("testfont.fnt 2048B\n");
|
||||||
}
|
printf("term16n.fnt 2048B\n");
|
||||||
if (*ft != '\0') { filename[offset++] = *ft; }
|
printf("calc.bin 1724B\n");
|
||||||
ft++;
|
printf("editor.bin 1280B\n");
|
||||||
}
|
|
||||||
ft++; // RESERVED
|
|
||||||
|
|
||||||
uint8_t sector = *ft++;
|
|
||||||
uint8_t size = *ft++;
|
|
||||||
|
|
||||||
// TODO: Use printf() here for padding
|
|
||||||
if (sector < 10) putc('0');
|
|
||||||
if (sector == 0) putc('0');
|
|
||||||
else printf("%d", sector);
|
|
||||||
printf(": %s", filename);
|
|
||||||
|
|
||||||
for (uint8_t i = 14 - strlen(filename); i > 0; i--) {
|
|
||||||
printf(" ");
|
|
||||||
}
|
|
||||||
|
|
||||||
printf(" | ");
|
|
||||||
if (size >> 1) {
|
|
||||||
printf("%d%skB\n", size >> 1, (size & 0x01) ? ".5" : "");
|
|
||||||
} else {
|
|
||||||
printf("%dB\n", size * 512);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void printPhysicalMemmap() {
|
void printPhysicalMemmap() {
|
||||||
|
|||||||
+134
-64
@@ -1,97 +1,167 @@
|
|||||||
[bits 16]
|
[bits 16]
|
||||||
[org 0x7c00]
|
[org 0x7c00]
|
||||||
[global start]
|
|
||||||
|
|
||||||
%define VIDMEM 0xb800
|
%define SUPERBLOCK 0x8c00
|
||||||
%define FILETAB_LOC 0x7000
|
%define FIRST_INODE_BLOCK (SUPERBLOCK) + 12
|
||||||
|
%define STAGE3_INODE 0xb000 + 128
|
||||||
|
%define EXTENT0 (STAGE3_INODE) + 21 ; Offset of extent[0] in inode_t
|
||||||
|
|
||||||
start:
|
start:
|
||||||
mov [driveNum], dl ; Store the drive number
|
|
||||||
xor ax, ax
|
xor ax, ax
|
||||||
mov es, ax
|
mov es, ax
|
||||||
mov ds, ax
|
mov ds, ax
|
||||||
|
|
||||||
|
mov byte [driveNum], dl
|
||||||
|
|
||||||
; Clear screen
|
; Clear screen
|
||||||
mov ax, 0x03
|
mov ax, 0x03
|
||||||
int 0x10
|
int 0x10
|
||||||
|
|
||||||
; Reset disk
|
;; Read in the boot block and the superblock to memory for 2nd stage bootloader
|
||||||
mov ah, 0x0
|
mov al, 15 ; 8 - 1 for boot block - bootsector & 8 for super block
|
||||||
mov dl, [driveNum]
|
mov bl, al
|
||||||
int 0x13
|
dec bl ; Number of sectors - 1
|
||||||
|
mov di, 0x7E00 ; Destination 0x7c00-0x8c00 = boot block, 0x8c00-0x9c00 = superblock
|
||||||
|
|
||||||
.read:
|
mov dx, 0x1F6 ; flags
|
||||||
; Location
|
mov al, 0xE0 ; 0b0111 0000, bits: 0-3 = LBA bits 24-27, 4 = drive, 5 = always set, 6 = set for LBA, 7 = always set
|
||||||
mov ax, 0
|
out dx, al
|
||||||
mov es, ax
|
|
||||||
mov bx, 0x7e00 ; 2nd stage bootloader location
|
|
||||||
|
|
||||||
; CHS Location
|
mov dx, 0x1F2 ; Sector count port
|
||||||
mov al, 4 ; Number of sectors to read (4 = 2kB)
|
mov al, 15 ; number of sectors to read
|
||||||
mov ch, 0 ; Cylinder
|
out dx, al
|
||||||
mov dh, 0 ; Head
|
|
||||||
mov cl, 2 ; Sector
|
|
||||||
mov dl, [driveNum]
|
|
||||||
|
|
||||||
mov ah, 2 ; Read from disk
|
inc dx ; 0x1F3 - LBA low
|
||||||
int 0x13 ; Read interrupt
|
mov al, 1 ; LBA 1 = 2nd disk sector (0-based), bits 0-7 of LBA
|
||||||
|
out dx, al
|
||||||
|
|
||||||
jnc loadPrekernel
|
inc dx ; 0x1F4 - LBA mid
|
||||||
|
xor ax, ax ; bits 8-15 of LBA
|
||||||
|
out dx, al
|
||||||
|
|
||||||
dec byte [counter]
|
inc dx ; 0x1F5 - LBA high
|
||||||
jnz .read
|
; xor ax, ax ; bits 16-23 of LBA
|
||||||
|
out dx, al
|
||||||
|
|
||||||
diskErr:
|
inc dx
|
||||||
mov si, diskErrMsg
|
inc dx ; 0x1F7 - Command port
|
||||||
mov bl, 0x04
|
mov al, 0x20 ; Read with retry
|
||||||
mov ax, VIDMEM
|
out dx, al
|
||||||
|
|
||||||
|
call loadSectorLoop
|
||||||
|
|
||||||
|
;; Parse superblock for first inode block, offset to reserved bootloader
|
||||||
|
|
||||||
|
;; Read first inode block to memory
|
||||||
|
;; Each disk block is 4KB or 8 sectors of 512 bytes
|
||||||
|
imul cx, [FIRST_INODE_BLOCK], 8 ; CX = disk sector/LBA of first inode block
|
||||||
|
|
||||||
|
mov bl, 7 ; 8 sectors for a block - 1
|
||||||
|
mov di, 0xb000 ; Address to read into, first inode block = 0xB000-0xC000
|
||||||
|
|
||||||
|
mov dx, 0x1F6 ; flags
|
||||||
|
mov al, 0xE0
|
||||||
|
out dx, al
|
||||||
|
|
||||||
|
mov dx, 0x1F2
|
||||||
|
mov al, 8
|
||||||
|
out dx, al
|
||||||
|
|
||||||
|
inc dx
|
||||||
|
mov al, cl
|
||||||
|
out dx, al
|
||||||
|
|
||||||
|
inc dx
|
||||||
|
mov al, ch
|
||||||
|
out dx, al
|
||||||
|
|
||||||
|
inc dx
|
||||||
|
xor ax, ax
|
||||||
|
out dx, al
|
||||||
|
|
||||||
|
inc dx
|
||||||
|
inc dx
|
||||||
|
mov al, 0x20
|
||||||
|
out dx, al
|
||||||
|
|
||||||
|
call loadSectorLoop
|
||||||
|
|
||||||
|
;; Read boot loader inode to memory
|
||||||
|
;; inode 2, each inode is 64 bytes in size
|
||||||
|
imul ecx, [EXTENT0], 8 ; first_block translated to disk sector/LBA
|
||||||
|
imul ebx, [EXTENT0+4], 8 ; length_blocks translated to disk sectors/LBAs
|
||||||
|
|
||||||
|
mov dx, 0x1F2
|
||||||
|
mov al, bl
|
||||||
|
out dx, al
|
||||||
|
|
||||||
|
inc dx
|
||||||
|
mov al, cl
|
||||||
|
out dx, al
|
||||||
|
|
||||||
|
inc dx
|
||||||
|
mov al, ch
|
||||||
|
out dx, al
|
||||||
|
|
||||||
|
inc dx
|
||||||
|
shr ecx, 16
|
||||||
|
mov al, cl
|
||||||
|
out dx, al
|
||||||
|
|
||||||
|
inc dx
|
||||||
|
and ch, 0x0F
|
||||||
|
mov al, ch
|
||||||
|
or al, 0xE0
|
||||||
|
out dx, al
|
||||||
|
|
||||||
|
inc dx
|
||||||
|
mov al, 0x20
|
||||||
|
out dx, al
|
||||||
|
|
||||||
|
dec bl
|
||||||
|
mov ax, 0x5000
|
||||||
mov es, ax
|
mov es, ax
|
||||||
xor di, di
|
xor di, di
|
||||||
.printLoop:
|
|
||||||
movsb
|
|
||||||
mov [es:di], bl
|
|
||||||
inc di
|
|
||||||
cmp byte [si], 0
|
|
||||||
jne .printLoop
|
|
||||||
|
|
||||||
cli
|
call loadSectorLoop
|
||||||
hlt
|
|
||||||
|
|
||||||
loadPrekernel:
|
xor ax, ax
|
||||||
mov byte [counter], 3
|
mov es, ax ; ES = 0x0000
|
||||||
|
|
||||||
.read:
|
;; Jump to 2nd stage bootloader here, does not return
|
||||||
; Location
|
|
||||||
mov ax, 0x5000 ; Making es 0x5000 will load the prekernel at 0x50000
|
|
||||||
mov es, ax
|
|
||||||
xor bx, bx
|
|
||||||
|
|
||||||
; CHS Location
|
|
||||||
mov al, 10 ; Prekernel size
|
|
||||||
mov ch, 0 ; Cylinder
|
|
||||||
mov dh, 0 ; Head
|
|
||||||
mov cl, 6 ; Sector
|
|
||||||
mov dl, [driveNum]
|
mov dl, [driveNum]
|
||||||
|
jmp 0x0000:0x7E00
|
||||||
|
|
||||||
mov ah, 2 ; Read from disk
|
;; Poll status port after reading 1 sector
|
||||||
int 0x13 ; Read interrupt
|
loadSectorLoop:
|
||||||
|
in al, dx ; Status register (reading port 1F7h)
|
||||||
|
test al, 8 ; Sector buffer requires servicing
|
||||||
|
je loadSectorLoop ; Keep trying until sector buffer is ready
|
||||||
|
|
||||||
jnc nextStage
|
mov cx, 256 ; # of words to read for 1 sector
|
||||||
dec byte [counter]
|
mov dx, 0x1F0 ; Data port, reading
|
||||||
jnz .read
|
rep insw ; Read bytes from DX port # into DI, CX # of times
|
||||||
|
|
||||||
;; Far jump to second stage bootloader
|
;; 400ns delay - Read alternate status register
|
||||||
nextStage:
|
mov dx, 0x3F6
|
||||||
mov dl, [driveNum]
|
in al, dx
|
||||||
jmp 0x0000:0x7e00
|
in al, dx
|
||||||
|
in al, dx
|
||||||
|
in al, dx
|
||||||
|
|
||||||
;; Data
|
cmp bl, 0 ; Sector # to still read
|
||||||
|
je .return
|
||||||
|
|
||||||
|
dec bl
|
||||||
|
mov dx, 0x1F7
|
||||||
|
jmp loadSectorLoop
|
||||||
|
.return:
|
||||||
|
ret
|
||||||
|
|
||||||
|
;; VARIABLES
|
||||||
driveNum: db 0
|
driveNum: db 0
|
||||||
counter: db 3
|
|
||||||
|
|
||||||
; Strings
|
;; Boot sector magic
|
||||||
diskErrMsg: db "Failed while reading from disk!", 0
|
times 510-($-$$) db 0 ; Padding
|
||||||
|
|
||||||
times 510-($-$$) db 0
|
|
||||||
dw 0xaa55
|
dw 0xaa55
|
||||||
|
|
||||||
|
|||||||
+6
-7
@@ -2,8 +2,7 @@
|
|||||||
[org 0x7e00]
|
[org 0x7e00]
|
||||||
|
|
||||||
%define STAGE3_LOC 0x50000
|
%define STAGE3_LOC 0x50000
|
||||||
%define VIDMEM 0xb800
|
%define MODE_INFO_BLOCK_LOC 0x6000
|
||||||
%define MODE_INFO_BLOCK_LOC 0x9000
|
|
||||||
|
|
||||||
start:
|
start:
|
||||||
mov [driveNum], dl
|
mov [driveNum], dl
|
||||||
@@ -12,9 +11,9 @@ start:
|
|||||||
xor ax, ax
|
xor ax, ax
|
||||||
mov es, ax
|
mov es, ax
|
||||||
|
|
||||||
memMapEntries equ 0x8500
|
memMapEntries equ 0x7000
|
||||||
getMemoryMap:
|
getMemoryMap:
|
||||||
mov di, 0x8504 ; 4 bytes after memMapEntries
|
mov di, memMapEntries + 4 ; 4 bytes after memMapEntries
|
||||||
xor ebx, ebx
|
xor ebx, ebx
|
||||||
xor bp, bp
|
xor bp, bp
|
||||||
mov edx, "PAMS" ; SMAP in little endian
|
mov edx, "PAMS" ; SMAP in little endian
|
||||||
@@ -370,9 +369,9 @@ DATA_SEG equ GDT.dataDescriptor - GDT.start
|
|||||||
|
|
||||||
;; VBE Stuff
|
;; VBE Stuff
|
||||||
;; !! IF YOU WANT TO SELECT ANY VALUE IN THE SETUP, SET THESE TO ZERO !!
|
;; !! IF YOU WANT TO SELECT ANY VALUE IN THE SETUP, SET THESE TO ZERO !!
|
||||||
width: dw 1920
|
width: dw 0
|
||||||
height: dw 1080
|
height: dw 0
|
||||||
bpp: db 32
|
bpp: db 0
|
||||||
|
|
||||||
offset: dw 0
|
offset: dw 0
|
||||||
_segment: dw 0 ; segment is a keyword
|
_segment: dw 0 ; segment is a keyword
|
||||||
|
|||||||
+47
-11
@@ -2,34 +2,40 @@
|
|||||||
#include <memory/virtual.h>
|
#include <memory/virtual.h>
|
||||||
#include <memory/addresses.h>
|
#include <memory/addresses.h>
|
||||||
#include <disk/disk.h>
|
#include <disk/disk.h>
|
||||||
#include <disk/filesys.h>
|
//#include <disk/filesys.h>
|
||||||
#include <screen/gfxmode.h>
|
#include <screen/gfxmode.h>
|
||||||
|
|
||||||
|
#include <fs/fs.h>
|
||||||
|
|
||||||
|
uint8_t loadFile(char* filename, void* dest);
|
||||||
|
|
||||||
__attribute__ ((section("entry")))
|
__attribute__ ((section("entry")))
|
||||||
void main() {
|
void main() {
|
||||||
diskRead(15, 1, filetable); // Load filetable into memory; TODO: Make a filetableUpdate() function that just keeps the stored and memory verisons in sync
|
|
||||||
|
|
||||||
// Physical memory manager setup
|
// Physical memory manager setup
|
||||||
uint32_t smapEntryCount = *(uint32_t*)SMAP_ENTRY_COUNT;
|
uint32_t smapEntryCount = *(uint32_t*)SMAP_ENTRY_COUNT;
|
||||||
smapEntry_t* smapEntries = (smapEntry_t*)SMAP_ENTRIES; // After a unit32_t
|
smapEntry_t* smapEntries = (smapEntry_t*)SMAP_ENTRIES;
|
||||||
uint32_t totalMemory = smapEntries[smapEntryCount - 1].baseAddress + smapEntries[smapEntryCount - 1].length - 1;
|
smapEntries += smapEntryCount - 1;
|
||||||
|
uint32_t totalMemory = smapEntries->baseAddress + smapEntries->length - 1;
|
||||||
|
|
||||||
setupPhysicalMemoryManager(MEMMAP_AREA, totalMemory);
|
setupPhysicalMemoryManager(MEMMAP_AREA, totalMemory);
|
||||||
|
|
||||||
|
smapEntries = (smapEntry_t*)SMAP_ENTRIES;
|
||||||
for (uint32_t i = 0; i < smapEntryCount; i++) {
|
for (uint32_t i = 0; i < smapEntryCount; i++) {
|
||||||
if (smapEntries[i].type == 1) {
|
if (smapEntries[i].type == 1) {
|
||||||
initMemoryRegion(smapEntries[i].baseAddress, smapEntries[i].length);
|
initMemoryRegion(smapEntries[i].baseAddress, smapEntries[i].length);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
deinitMemoryRegion(0x1000, 0x9000); // Reserve kernel memory (under 0xa000)
|
deinitMemoryRegion(0x1000, 0x11000); // Reserve kernel memory (under 0x12000)
|
||||||
deinitMemoryRegion(MEMMAP_AREA, maxBlocks / BLOCKS_PER_BYTE);
|
deinitMemoryRegion(MEMMAP_AREA, maxBlocks / BLOCKS_PER_BYTE);
|
||||||
|
|
||||||
// Load kernel into memory
|
// Load root dir, find kernel INode and parse it
|
||||||
if (readFile("kernel.bin", (void*)KERNEL_LOC) != 0) { // Check if kernel.bin was loaded
|
superBlock_t* superblock = (superBlock_t*)SUPERBLOCK_LOC;
|
||||||
// TODO: Add error messages
|
superblock->rootInodePtr = BOOT_FIRST_INODE_LOC + sizeof(inode_t);
|
||||||
while (1);
|
diskRead(superblock->firstDataBlock * 8, 8, (void*)SCRATCH_BLOCK_LOC);
|
||||||
}
|
|
||||||
|
if (loadFile("kernel.bin", (void*)KERNEL_LOC) != 0) __asm__ volatile ("cli; hlt" : : "a"(0xDeadBeef));
|
||||||
|
if (loadFile("term16n.fnt", (void*)FONT_LOC) != 0) __asm__ volatile ("cli; hlt" : : "a"(0xDeadBeef));
|
||||||
|
|
||||||
// Virtual memory manager setup
|
// Virtual memory manager setup
|
||||||
if (setupVirtualMemoryManager() != 0) {
|
if (setupVirtualMemoryManager() != 0) {
|
||||||
@@ -60,3 +66,33 @@ void main() {
|
|||||||
((void(*)(void))0xC0000000)();
|
((void(*)(void))0xC0000000)();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t loadFile(char* filename, void* dest) {
|
||||||
|
dirEntry_t* dirEntry = (dirEntry_t*)SCRATCH_BLOCK_LOC;
|
||||||
|
while (dirEntry->name[0] != '\0') {
|
||||||
|
if (strcmp(dirEntry->name, filename) == 0) break;
|
||||||
|
dirEntry++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dirEntry->name[0] == '\0') return 1;
|
||||||
|
|
||||||
|
inode_t* inode = (inode_t*)BOOT_FIRST_INODE_LOC;
|
||||||
|
while (inode->id != dirEntry->id) {
|
||||||
|
inode++;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t totalBlocks = bytesToBlocks(inode->sizeBytes);
|
||||||
|
uint32_t addressOffset = 0;
|
||||||
|
|
||||||
|
for (uint8_t i = 0; i < 4 && totalBlocks > 0; i++) {
|
||||||
|
diskRead(inode->extent[i].firstBlock * 8, inode->extent[i].length * 8, dest + addressOffset);
|
||||||
|
addressOffset += inode->extent[i].length * FS_BLOCK_SIZE;
|
||||||
|
totalBlocks -= inode->extent[i].length;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (totalBlocks > 0) {
|
||||||
|
// TODO: Indirect extents
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user