call c 32bit code
This commit is contained in:
parent
e77248f8e9
commit
a0e745b6b5
3
Makefile
3
Makefile
@ -1,6 +1,7 @@
|
|||||||
all:
|
all:
|
||||||
as -o boot.o boot.s
|
as -o boot.o boot.s
|
||||||
ld -o boot.bin --oformat binary -e init boot.o
|
gcc -nostdinc -nostdlib -ffreestanding -c main.c -o theObjectCode.o
|
||||||
|
ld -o boot.bin -Ttext 0x0 --oformat binary -e init boot.o theObjectCode.o
|
||||||
|
|
||||||
run:
|
run:
|
||||||
qemu-system-x86_64 boot.bin
|
qemu-system-x86_64 boot.bin
|
49
boot.s
49
boot.s
@ -1,15 +1,58 @@
|
|||||||
.code16 # tell the assembler that we're using 16 bit mode
|
.code16 # tell the assembler that we're using 16 bit mode
|
||||||
|
.include "gdt.s"
|
||||||
|
|
||||||
|
.section .text
|
||||||
|
|
||||||
.global init # makes our label "init" available to the outside
|
.global init # makes our label "init" available to the outside
|
||||||
|
.globl mainentry
|
||||||
|
|
||||||
init: # this is the beginning of our binary later.
|
init: # this is the beginning of our binary later.
|
||||||
|
|
||||||
#jmp init # jump to "init"
|
#jmp init # jump to "init"
|
||||||
#ljmpw $0xFFFF, $0 # jumps to the "reset vector", doing a reboot
|
#ljmpw $0xFFFF, $0 # jumps to the "reset vector", doing a reboot
|
||||||
jmp printhelloworld
|
call printhelloworld
|
||||||
|
|
||||||
|
jmp switchto32bit
|
||||||
|
|
||||||
|
switchto32bit:
|
||||||
|
# Load Global Descriptor Table
|
||||||
|
lgdt gdt32ptr
|
||||||
|
|
||||||
|
# Load Control Register CR0
|
||||||
|
# Enable Protected Mode (Bit0 in CR0)
|
||||||
|
# Store Control Register CR0
|
||||||
|
movl %cr0, %eax
|
||||||
|
orl $(1<<0), %eax
|
||||||
|
movl %eax, %cr0
|
||||||
|
|
||||||
|
# Setup all Segment Registers
|
||||||
|
# and reload Code Segment, Instruction Pointer
|
||||||
|
movw $0x0010, %ax
|
||||||
|
movw %ax, %ds
|
||||||
|
movw %ax, %es
|
||||||
|
movw %ax, %fs
|
||||||
|
movw %ax, %gs
|
||||||
|
movw %ax, %ss
|
||||||
|
ljmp $0x0008, $JumpToPM
|
||||||
|
|
||||||
|
.code32
|
||||||
|
JumpToPM:
|
||||||
|
call mainentry
|
||||||
|
|
||||||
|
ljmpw $0xFFFF, $0 # jumps to the "reset vector", doing a reboot
|
||||||
|
|
||||||
printhelloworld:
|
printhelloworld:
|
||||||
mov $0xe37, %ax
|
mov $0x0e, %ah # function mode -> display char
|
||||||
|
|
||||||
|
mov $'S', %al
|
||||||
int $0x10 # video bios interrupt
|
int $0x10 # video bios interrupt
|
||||||
mov $0xe38, %ax
|
mov $'T', %al
|
||||||
|
int $0x10 # video bios interrupt
|
||||||
|
mov $'A', %al
|
||||||
|
int $0x10 # video bios interrupt
|
||||||
|
mov $'R', %al
|
||||||
|
int $0x10 # video bios interrupt
|
||||||
|
mov $'T', %al
|
||||||
int $0x10 # video bios interrupt
|
int $0x10 # video bios interrupt
|
||||||
|
|
||||||
.fill 510-(.-init), 1, 0 # add zeroes to make it 510 bytes long
|
.fill 510-(.-init), 1, 0 # add zeroes to make it 510 bytes long
|
||||||
|
27
gdt.s
Normal file
27
gdt.s
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
#GDT
|
||||||
|
|
||||||
|
gdt_start:
|
||||||
|
INITSEG = 0x0050
|
||||||
|
INITOFF = 0x0000
|
||||||
|
|
||||||
|
.section .rodata
|
||||||
|
|
||||||
|
gdt:
|
||||||
|
# Null Descriptor
|
||||||
|
.word 0x0000, 0x0000
|
||||||
|
.byte 0x00, 0b00000000, 0b00000000, 0x00
|
||||||
|
# Code Descriptor
|
||||||
|
.word 0xffff, (INITSEG * 0x10 + INITOFF)
|
||||||
|
.byte 0x00, 0b10011010, 0b11001111, 0x00
|
||||||
|
# Data Descriptor
|
||||||
|
.word 0xffff, (INITSEG * 0x10 + INITOFF)
|
||||||
|
.byte 0x00, 0b10010010, 0b11001111, 0x00
|
||||||
|
gdt_end:
|
||||||
|
|
||||||
|
gdt32ptr:
|
||||||
|
.word (gdt_end - gdt - 1)
|
||||||
|
.long (gdt + INITSEG * 0x10 + INITOFF)
|
||||||
|
|
||||||
|
gdt64ptr:
|
||||||
|
.word (gdt_end - gdt - 1)
|
||||||
|
.quad (gdt + INITSEG * 0x10 + INITOFF)
|
18
main.c
Normal file
18
main.c
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
void mainentry() {
|
||||||
|
int x = 5;
|
||||||
|
|
||||||
|
char* video_memory = (char*) 0xb8000;
|
||||||
|
*video_memory = 'X';
|
||||||
|
|
||||||
|
// Here , the star following the type means that this is not a variable to hold
|
||||||
|
// a char (i.e. a single byte ) but a pointer to the ADDRESS of a char ,
|
||||||
|
// which , being an address , will actually require the allocation of at least
|
||||||
|
// 32 bits .
|
||||||
|
char * video_address = (char*)(0xb8000);
|
||||||
|
// If we ’d like to store a character at the address pointed to , we make the
|
||||||
|
// assignment with a star - prefixed pointer variable . This is known as
|
||||||
|
// dereferencing a pointer , because we are not changing the address held by
|
||||||
|
// the pointer variable but the contents of that address .
|
||||||
|
*video_address = 'x';
|
||||||
|
// Just to emphasise the purpose of the star , an ommision of it , such as:
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user