aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xrun38
-rw-r--r--src/entry.asm90
-rw-r--r--src/main.c5
3 files changed, 26 insertions, 107 deletions
diff --git a/run b/run
index 8a53630..3a0d588 100755
--- a/run
+++ b/run
@@ -17,33 +17,6 @@ qemu_with_flags() {
fi
}
-make_genext2fs() {
- if [ "$(genext2fs -V | awk '{print $2}')" = "1.4.2" ]; then
- echo "genext2fs is already the newest version"
- else
- if [ "$no_ask" != "-y" ]; then
- printf "Melvix requires the newest genext2fs version, would you like to install it? [y/n] "
- read -r answer
- fi
- if [ "$answer" != "${answer#[Yy]}" ] || [ "$no_ask" = "-y" ]; then
- echo "Building genext2fs..."
- git clone --quiet https://github.com/bestouff/genext2fs.git >/dev/null
- cd genext2fs >/dev/null
- git checkout --quiet 000e369 >/dev/null
- mv README.md README >/dev/null
- touch ChangeLog >/dev/null
- bash autogen.sh >/dev/null
- ./configure >/dev/null
- sudo make install >/dev/null
- cd .. >/dev/null
- rm -rf genext2fs >/dev/null
- echo "Success!"
- else
- echo "This probably won't compile..."
- fi
- fi
-}
-
make_cross() {
if [ ! -d "./cross/" ]; then
# Create directory
@@ -89,7 +62,7 @@ make_cross() {
}
make_build() {
- rm -rf disk/bin/ disk/
+ rm -rf disk/bin/ disk/ build/disk.img
mkdir -p build/ disk/bin/ disk/
echo "Building..."
@@ -106,9 +79,10 @@ make_build() {
cp build/melvix.bin disk/
# Create disk image
- make_genext2fs
- /usr/local/bin/genext2fs -B 1024 -d disk/ -U -N 1024 -b 65536 build/disk.img
+ dd if=/dev/zero of=build/disk.img bs=1k count=16k
+ sudo mke2fs build/disk.img
dd if=disk/boot.bin of=build/disk.img conv=notrunc
+ ./ext2util/ext2util -x build/disk.img -wf disk/melvix.bin -i 5
printf "Build finshed successfully!\n\n"
}
@@ -118,9 +92,7 @@ make_test() {
}
make_debug() {
- qemu_with_flags -display none -hdb build/disk.img -s -S &
- gdb "$(pwd)"/build/melvix.bin -ex 'target remote localhost:1234'
- killall qemu-system-i386
+ qemu_with_flags -hdb build/disk.img -s -S
}
make_disasm() {
diff --git a/src/entry.asm b/src/entry.asm
index 596a042..c13cf8e 100644
--- a/src/entry.asm
+++ b/src/entry.asm
@@ -24,18 +24,15 @@
%define EXT2_SIG_OFFSET 0x38 ; Signature offset in superblock
%define EXT2_TABLE_OFFSET 0x08 ; Inode table offset after superblock
%define EXT2_INODE_TABLE_LOC 0x1000 ; New inode table location in memory
-%define EXT2_ROOT_INODE 0x02 ; Root directory inode
+%define EXT2_KERNEL_INODE 0x05 ; Kernel inode
%define EXT2_INODE_SIZE 0x80 ; Single inode size
%define EXT2_GET_ADDRESS(inode) (EXT2_INODE_TABLE_LOC + (inode - 1) * EXT2_INODE_SIZE)
-%define EXT2_TYPE_OFFSET 0x00 ; Inode offset of filetype and rights
%define EXT2_COUNT_OFFSET 0x1c ; Inode offset of number of data blocks
%define EXT2_POINTER_OFFSET 0x28 ; Inode offset of first data pointer
-%define EXT2_INODE_OFFSET 0x00 ; Dirent offset of inode number
-%define EXT2_ENTRY_LENGTH_OFFSET 0x04 ; Dirent offset of entry length
-%define EXT2_FILENAME_OFFSET 0x08 ; Dirent offset of file name
%define EXT2_SIG 0xef53 ; Signature
-%define EXT2_DIR 0x4000 ; Directory indicator
-%define EXT2_REG 0x8000 ; Regular file indicator
+
+%define STACK_POINTER 0x00900000 ; The initial stack pointer in kernel mode
+%define KERNEL_POSITION 0x00050000 ; Loaded kernel position in protected mode (* 0x10)
%define A20_GATE 0x92 ; Fast A20 gate
%define A20_ENABLED 0b10 ; Bit 1 defines whether A20 is enabled
@@ -119,14 +116,9 @@ lba_error_msg db "LBA error!", NEWLINE, RETURN, NULL
stage_two_msg db "Stage2 loaded", NEWLINE, RETURN, NULL
disk_success_msg db "Disk is valid", NEWLINE, RETURN, NULL
inode_table_msg db "Found inode table", NEWLINE, RETURN, NULL
-kernel_found_msg db "Found kernel file", NEWLINE, RETURN, NULL
protected_msg db "Jumping to protected mode", NEWLINE, RETURN, NULL
drive db 0
-; Filenames
-kernel_file_name db "melvix.bin", NULL
-kernel_file_name_len equ $ - kernel_file_name
-
; Data
packet:
db 0x10 ; Packet size
@@ -144,9 +136,9 @@ lba:
times 510 - ($ - $$) db 0
dw 0xAA55
-; This is the second stage. It tries to load '/melvix.bin' into memory.
-; To do this, it first checks the integrity of the ext2 fs. Then it has to loop
-; through every file in the root until the 'melvix.bin' file is found.
+; This is the second stage. It tries to load the kernel (inode 5) into memory.
+; To do this, it first checks the integrity of the ext2 fs. Then it has to find
+; the address of the fifth inode and load its contents into memory.
; After this is finished, the stage can jump into the protected mode, enable the
; A20 line and finally jump to the kernel! ez
stage_two:
@@ -172,55 +164,11 @@ stage_two:
mov si, inode_table_msg
call print
- ; Load root dir
- mov bx, EXT2_GET_ADDRESS(EXT2_ROOT_INODE) ; First block
- mov ax, [bx + EXT2_TYPE_OFFSET] ; Get filetype
- and ax, EXT2_DIR ; AND with directory
- cmp ax, EXT2_DIR ; Check if it's a directory
- jne disk_error ; Not a directory!
- ;mov cx, [bx + EXT2_COUNT_OFFSET] ; Number of sectors for inode - TODO later!
- mov ax, [bx + EXT2_POINTER_OFFSET] ; Address of first block pointer
- shl ax, 1 ; Multiply ax by 2
- mov [lba], ax
- mov bx, 0x5000
- mov [dest], bx
- call disk_read
-
- ; Find kernel
- ; TODO: Fix endless loop when not found
- .kernel_find_loop:
- lea si, [bx + EXT2_FILENAME_OFFSET] ; First comparison string
- mov di, kernel_file_name ; Second comparison string
- mov cx, kernel_file_name_len ; String length
- rep cmpsb ; Compare strings
- je .found_kernel ; Found correct dirent!
- add bx, EXT2_ENTRY_LENGTH_OFFSET ; Add dirent struct size
- jmp .kernel_find_loop ; Jump to next dirent!
-
- .found_kernel:
- mov si, kernel_found_msg
- call print ; Show happy message!
-
; Load kernel
- mov ax, [bx + EXT2_INODE_OFFSET] ; Get inode number
- dec ax ; Decrement inode: (inode - 1)
- mov cx, EXT2_INODE_SIZE ; Prepare for mul
- mul cx ; Multiply inode number (* EXT2_INODE_SIZE)
- mov bx, ax ; Move for effective address calculations
- mov bx, [bx + EXT2_INODE_TABLE_LOC] ; bx is at the start of the inode
- mov ax, [bx + EXT2_TYPE_OFFSET] ; Get filetype
- and ax, EXT2_REG ; AND with regular file
- cmp ax, EXT2_REG ; Check if it's a regular file
- jne disk_error ; Not a regular file!
- ; Read first block
- mov ax, [bx + EXT2_POINTER_OFFSET] ; Address of first block pointer
- shl ax, 1 ; Multiply by 2
- mov [lba], ax
- mov bx, 0x5000
- mov [dest], bx
- call disk_read ; TODO: TEST!
-
- mov bx, 0x5000
+ mov bx, EXT2_GET_ADDRESS(EXT2_KERNEL_INODE) ; First block
+ mov cx, [bx + EXT2_COUNT_OFFSET] ; Number of sectors for inode
+ lea di, [bx + EXT2_POINTER_OFFSET] ; Address of first block pointer
+ mov bx, 0x5000 ; Load to this address
mov [dest + 2], bx
mov bx, 0 ; Inode location = 0xF0000
mov [dest], bx
@@ -239,15 +187,12 @@ kernel_load:
call disk_read
- add bx, 1024 ; 1kb increase
+ add bx, 0x400 ; 1kb increase
add di, 0x4 ; Move to next block pointer
- sub cx, 2 ; Read 2 blocks
+ sub cx, 0x2 ; Read 2 blocks
jnz kernel_load
ret
- nop
- hlt
-
protected_mode_enter:
cli ; Turn off interrupts
mov si, protected_msg
@@ -279,10 +224,8 @@ protected_mode_enter:
jmp 08h:protected_mode ; JUMP!
-bits 32 ; Woah!
+bits 32 ; Woah, so big!
protected_mode:
- xor eax, eax
-
mov ax, 10h ; Set data segement indentifier
mov ds, ax
mov es, ax
@@ -290,11 +233,10 @@ protected_mode:
mov gs, ax
mov ss, ax ; Stack segment
- mov esp, 0x00900000 ; Move stack pointer
+ mov esp, STACK_POINTER ; Move stack pointer
- mov edx, 0x00050000
+ mov edx, KERNEL_POSITION
lea eax, [edx]
- jmp $
call eax
; GDT
diff --git a/src/main.c b/src/main.c
index 82f6961..6b9f2da 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1,5 +1,10 @@
int main()
{
+ char *vga = (char *)0x000B8000;
+ for (long i = 0; i < 80 * 25; i++) {
+ *vga++ = 0;
+ *vga++ = 0;
+ }
while (1) {
};
return 0;