call c 32bit code

This commit is contained in:
lukas 2022-02-27 20:03:19 +01:00
parent e77248f8e9
commit a0e745b6b5
4 changed files with 93 additions and 4 deletions

View File

@ -1,6 +1,7 @@
all:
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:
qemu-system-x86_64 boot.bin

49
boot.s
View File

@ -1,15 +1,58 @@
.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
.globl mainentry
init: # this is the beginning of our binary later.
#jmp init # jump to "init"
#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:
mov $0xe37, %ax
mov $0x0e, %ah # function mode -> display char
mov $'S', %al
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
.fill 510-(.-init), 1, 0 # add zeroes to make it 510 bytes long

27
gdt.s Normal file
View 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
View 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:
}