init
This commit is contained in:
parent
9c93c11e8c
commit
c9ca86bece
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
stuff/
|
||||
image.iso
|
20
Makefile
Normal file
20
Makefile
Normal 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
183
boot.s
Normal 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
46
cstuff.c
Normal 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
45
link.ld
Normal 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
0
stuff/boot/.placeholder
Normal file
Loading…
Reference in New Issue
Block a user