This commit is contained in:
K. Lange 2018-03-05 23:12:24 +09:00 committed by Kevin Lange
parent 9c93c11e8c
commit c9ca86bece
6 changed files with 296 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
stuff/
image.iso

20
Makefile Normal file
View File

@ -0,0 +1,20 @@
KERNEL_TARGET=i686-elf
KCC = $(KERNEL_TARGET)-gcc
KAS = $(KERNEL_TARGET)-as
KLD = $(KERNEL_TARGET)-ld
all: image.iso
image.iso: stuff/boot/boot.sys
xorriso -as mkisofs -R -J -c boot/bootcat -b boot/boot.sys -no-emul-boot -boot-load-size 4 -o image.iso stuff
cstuff.o: cstuff.c
${KCC} -c -o cstuff.o cstuff.c
boot.o: boot.s
yasm -f elf -o $@ $<
stuff/boot/boot.sys: boot.o cstuff.o link.ld
${KLD} -T link.ld -o $@ boot.o cstuff.o
#objcopy -j .text -O binary temp.elf $@

183
boot.s Normal file
View File

@ -0,0 +1,183 @@
[bits 16]
jmp main
;jmp protected_start
main:
mov ax, 0x0000
mov ds, ax
mov ax, 0x0500
mov es, ax
cli
mov si, msg_hello
call print
mov di, 0x0
call do_e820
jc .e820_failed
; success
mov si, msg_done
call print
mov si, msg_a20
call print
in al, 0x92
or al, 2
out 0x92, al
mov si, msg_done
call print
mov si, msg_gdt
call print
call set_gdt
mov si, msg_done
call print
mov eax, cr0
or eax, 1
mov cr0, eax
mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
jmp far 0x08:(protected_start)
; failure
.e820_failed:
mov si, msg_fail
call print
jmp hang
hang:
jmp hang
print: lodsb
or al, al
jz .ch_done
mov ah, 0x0E
int 0x10
jmp print
.ch_done:
ret
set_gdt:
xor eax, eax
mov ax, ds
shl eax, 4
add eax, gdt_base
mov [gdtr+2], eax
mov eax, gdt_end
sub eax, gdt_base
mov [gdtr], ax
lgdt [gdtr]
ret
do_e820:
xor ebx, ebx ; ebx must be 0 to start
xor bp, bp ; keep an entry count in bp
mov edx, 0x0534D4150 ; Place "SMAP" into edx
mov eax, 0xe820
mov [es:di + 20], dword 1 ; force a valid ACPI 3.X entry
mov ecx, 24 ; ask for 24 bytes
int 0x15
jc short .failed ; carry set on first call means "unsupported function"
mov edx, 0x0534D4150 ; Some BIOSes apparently trash this register?
cmp eax, edx ; on success, eax must have been reset to "SMAP"
jne short .failed
test ebx, ebx ; ebx = 0 implies list is only 1 entry long (worthless)
je short .failed
jmp short .jmpin
.e820lp:
mov eax, 0xe820 ; eax, ecx get trashed on every int 0x15 call
mov [es:di + 20], dword 1 ; force a valid ACPI 3.X entry
mov ecx, 24 ; ask for 24 bytes again
int 0x15
jc short .e820f ; carry set means "end of list already reached"
mov edx, 0x0534D4150 ; repair potentially trashed register
.jmpin:
jcxz .skipent ; skip any 0 length entries
cmp cl, 20 ; got a 24 byte ACPI 3.X response?
jbe short .notext
test byte [es:di + 20], 1 ; if so: is the "ignore this data" bit clear?
je short .skipent
.notext:
mov ecx, [es:di + 8] ; get lower uint32_t of memory region length
or ecx, [es:di + 12] ; "or" it with upper uint32_t to test for zero
jz .skipent ; if length uint64_t is 0, skip entry
inc bp ; got a good entry: ++count, move to next storage spot
add di, 24
.skipent:
test ebx, ebx ; if ebx resets to 0, list is complete
jne short .e820lp
.e820f:
mov [mmap_ent], bp ; store the entry count
clc ; there is "jc" on end of list to this point, so the carry must be cleared
ret
.failed:
stc ; "function unsupported" error exit
ret
db '--- Data Starts Here ---'
msg_hello db 'Scanning memory... ', 0
msg_gdt db 'Instaling gdt... ', 0
msg_a20 db 'Flipping A20... ', 0
msg_done db 'Done', 13, 10, 0
msg_fail db 'Failed', 13, 10, 0
;typedef struct {
; /* Limits */
; uint16_t limit_low;
; /* Segment address */
; uint16_t base_low;
; uint8_t base_middle;
; /* Access modes */
; uint8_t access;
; uint8_t granularity;
; uint8_t base_high;
align 8
gdtr
dw 0
dd 0
gdt_base
dq 0
dw 0xFFFF
dw 0
db 0
db 0x9a
db 0xcf
db 0
dw 0xffff
dw 0
db 0
db 0x92
db 0xcf
db 0
gdt_end
mmap_ent db 0, 0
[bits 32]
align 8
protected_start:
mov eax, 0xAAAABBBB
mov [0xB8000], eax
;jmp protected_start
extern kmain
jmp (kmain)

46
cstuff.c Normal file
View File

@ -0,0 +1,46 @@
unsigned short * textmemptr = (unsigned short *)0xB8000;
static void placech(unsigned char c, int x, int y, int attr) {
unsigned short *where;
unsigned att = attr << 8;
where = textmemptr + (y * 80 + x);
*where = c | att;
}
static int x = 0;
static int y = 0;
static void print(char * str) {
while (*str) {
if (*str == '\n') {
x = 0;
y += 1;
if (y == 24) {
y = 0;
}
} else {
placech(*str, x, y, 0x07);
x++;
if (x == 80) {
x = 0;
y += 1;
if (y == 24) {
y = 0;
}
}
}
str++;
}
}
static void clear() {
for (int y = 0; y < 24; ++y) {
for (int x = 0; x < 80; ++x) {
placech(' ', x, y, 0x00);
}
}
}
int kmain() {
clear();
print("ToaruOS-NIH Bootloader v0.1\n");
while (1);
}

45
link.ld Normal file
View File

@ -0,0 +1,45 @@
/* vim: tabstop=4 shiftwidth=4 noexpandtab
* Kernel linker script for x86
*/
OUTPUT_FORMAT("binary")
ENTRY(start)
phys = 0x7c00;
SECTIONS
{
. = 0x7c00;
.text :
{
code = .;
*(.text)
}
.rodata BLOCK(1) : ALIGN(1)
{
*(.rodata)
}
.data BLOCK(1) : ALIGN(1)
{
data = .;
*(.data)
}
.bss BLOCK(1) : ALIGN(1)
{
bss = .;
*(COMMON)
*(.bss)
*(.stack)
}
end = .;
/DISCARD/ :
{
*(.comment)
*(.eh_frame)
*(.note.gnu.build-id)
}
}

0
stuff/boot/.placeholder Normal file
View File