From a0e745b6b55893d42f5b05b3aa1d6a0560904084 Mon Sep 17 00:00:00 2001 From: lukas Date: Sun, 27 Feb 2022 20:03:19 +0100 Subject: [PATCH] call c 32bit code --- Makefile | 3 ++- boot.s | 49 ++++++++++++++++++++++++++++++++++++++++++++++--- gdt.s | 27 +++++++++++++++++++++++++++ main.c | 18 ++++++++++++++++++ 4 files changed, 93 insertions(+), 4 deletions(-) create mode 100644 gdt.s create mode 100644 main.c diff --git a/Makefile b/Makefile index 96ab501..33be7a9 100644 --- a/Makefile +++ b/Makefile @@ -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 \ No newline at end of file diff --git a/boot.s b/boot.s index b584d95..1089357 100644 --- a/boot.s +++ b/boot.s @@ -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 diff --git a/gdt.s b/gdt.s new file mode 100644 index 0000000..28110f5 --- /dev/null +++ b/gdt.s @@ -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) diff --git a/main.c b/main.c new file mode 100644 index 0000000..21518c8 --- /dev/null +++ b/main.c @@ -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: +}