Add dummy kernel.
This commit is contained in:
parent
1cc3169cd0
commit
dbaad4cf88
14
Makefile
14
Makefile
@ -1,10 +1,11 @@
|
|||||||
AS=x86_64-elf-as
|
AS=x86_64-elf-as
|
||||||
LD=x86_64-elf-ld
|
LD=x86_64-elf-ld
|
||||||
|
CC=x86_64-elf-gcc
|
||||||
|
|
||||||
run: mbr.bin
|
run: image.bin
|
||||||
qemu-system-i386 -drive format=raw,file=$<
|
qemu-system-i386 -drive format=raw,file=$<
|
||||||
|
|
||||||
debug: mbr.bin
|
debug: image.bin
|
||||||
qemu-system-i386 -drive format=raw,file=$< -s -S &
|
qemu-system-i386 -drive format=raw,file=$< -s -S &
|
||||||
i386-elf-gdb \
|
i386-elf-gdb \
|
||||||
-ex "target remote localhost:1234" \
|
-ex "target remote localhost:1234" \
|
||||||
@ -12,6 +13,15 @@ debug: mbr.bin
|
|||||||
-ex "break *0x7c00" \
|
-ex "break *0x7c00" \
|
||||||
-ex "continue"
|
-ex "continue"
|
||||||
|
|
||||||
|
image.bin: mbr.bin kernel.bin
|
||||||
|
cat $^ >$@
|
||||||
|
|
||||||
|
kernel.bin: kernel.o
|
||||||
|
$(LD) -m elf_i386 -o $@ -Ttext 0x1000 $^ --oformat binary
|
||||||
|
|
||||||
|
%.o: %.c
|
||||||
|
$(CC) -m32 -ffreestanding -c $< -o $@
|
||||||
|
|
||||||
%.o: %.S
|
%.o: %.S
|
||||||
$(AS) $^ -o $@
|
$(AS) $^ -o $@
|
||||||
|
|
||||||
|
|||||||
7
kernel.c
Normal file
7
kernel.c
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
asm("jmp main");
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
char* video_memory = (char*) 0xb8000;
|
||||||
|
*video_memory = 'X';
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
77
mbr.S
77
mbr.S
@ -1,12 +1,56 @@
|
|||||||
.code16
|
.code16
|
||||||
.global _start
|
.global _start
|
||||||
_start:
|
_start:
|
||||||
|
mov %dl, boot_drive
|
||||||
mov $banner, %si
|
mov $banner, %si
|
||||||
call print_string
|
call print_string
|
||||||
|
|
||||||
|
call load_kernel
|
||||||
|
call switch_to_32bit
|
||||||
|
|
||||||
jmp . // loop forever
|
jmp . // loop forever
|
||||||
|
|
||||||
|
|
||||||
|
.equ KERNEL_OFFSET, 0x1000
|
||||||
|
load_kernel:
|
||||||
|
mov $2, %ah // read mode
|
||||||
|
mov $2, %al // sectors to read
|
||||||
|
mov $2, %cl // start from sector 2
|
||||||
|
mov $0, %ch // cylinder 0
|
||||||
|
mov $0, %dh // head 0
|
||||||
|
mov $KERNEL_OFFSET, %bx // bx -> destination
|
||||||
|
mov boot_drive, %dl // dl -> disk
|
||||||
|
int $0x13
|
||||||
|
// no error checking, let's hope it works
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
switch_to_32bit:
|
||||||
|
cli // 1. disable interrupts
|
||||||
|
lgdt gdt_descriptor // 2. load GDT descriptor
|
||||||
|
mov %cr0, %eax
|
||||||
|
or $1, %eax // 3. enable protected mode
|
||||||
|
mov %eax, %cr0
|
||||||
|
ljmp $CODE_SEG, $init_32bit // 4. far jump
|
||||||
|
|
||||||
|
|
||||||
|
.code32
|
||||||
|
init_32bit:
|
||||||
|
mov $DATA_SEG, %ax // 5. update segment registers
|
||||||
|
mov %ax, %ds
|
||||||
|
mov %ax, %ss
|
||||||
|
mov %ax, %es
|
||||||
|
mov %ax, %fs
|
||||||
|
mov %ax, %gs
|
||||||
|
|
||||||
|
mov $0x90000, %ebp // 6. setup stack
|
||||||
|
mov %ebp, %esp
|
||||||
|
|
||||||
|
call KERNEL_OFFSET // 7. jump to the kernel
|
||||||
|
jmp . // 8. loop forever
|
||||||
|
|
||||||
|
|
||||||
|
.code16
|
||||||
print_string:
|
print_string:
|
||||||
mov $0x0e, %ah // "teletype output"
|
mov $0x0e, %ah // "teletype output"
|
||||||
repeat:
|
repeat:
|
||||||
@ -21,8 +65,41 @@ done:
|
|||||||
ret
|
ret
|
||||||
|
|
||||||
. = _start + 256 # pad to 256 bytes
|
. = _start + 256 # pad to 256 bytes
|
||||||
|
boot_drive:
|
||||||
|
.byte 0
|
||||||
banner:
|
banner:
|
||||||
.asciz "YABLOKO bootloader started\r\n"
|
.asciz "YABLOKO bootloader started\r\n"
|
||||||
|
|
||||||
|
gdt_start:
|
||||||
|
.quad 0x0 // null descriptor
|
||||||
|
|
||||||
|
// code segment descriptor
|
||||||
|
gdt_code:
|
||||||
|
.word 0xffff // segment length, bits 0-15
|
||||||
|
.word 0x0 // segment base, bits 0-15
|
||||||
|
.byte 0x0 // segment base, bits 16-23
|
||||||
|
.byte 0b10011010 // flags (8 bits)
|
||||||
|
.byte 0b11001111 // flags (4 bits) + segment length, bits 16-19
|
||||||
|
.byte 0x0 // segment base, bits 24-31
|
||||||
|
|
||||||
|
// data segment descriptor
|
||||||
|
gdt_data:
|
||||||
|
.word 0xffff // segment length, bits 0-15
|
||||||
|
.word 0x0 // segment base, bits 0-15
|
||||||
|
.byte 0x0 // segment base, bits 16-23
|
||||||
|
.byte 0b10010010 // flags (8 bits)
|
||||||
|
.byte 0b11001111 // flags (4 bits) + segment length, bits 16-19
|
||||||
|
.byte 0x0 // segment base, bits 24-31
|
||||||
|
|
||||||
|
gdt_end:
|
||||||
|
|
||||||
|
// GDT descriptor
|
||||||
|
gdt_descriptor:
|
||||||
|
.word gdt_end - gdt_start - 1 // size (16 bit)
|
||||||
|
.int gdt_start // address (32 bit)
|
||||||
|
|
||||||
|
.equ CODE_SEG, gdt_code - gdt_start
|
||||||
|
.equ DATA_SEG, gdt_data - gdt_start
|
||||||
|
|
||||||
. = _start + 510 # pad to 510 bytes
|
. = _start + 510 # pad to 510 bytes
|
||||||
.byte 0x55, 0xaa # boot sector magic value
|
.byte 0x55, 0xaa # boot sector magic value
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user