Skip to content

Latest commit

 

History

History
 
 

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 

README.md

Pure64 Manual

This manual has the purpose of helping software developers understand how they should be using Pure64 to load their kernel.

Prerequisites

This manual assumes you have some understanding of a typical boot process.

You'll have to have NASM installed to build the software.

Building

In the top directory of Pure64, just run the following:

./build.sh

System Requirements

A computer with at least one 64-bit Intel or AMD CPU (or anything else that uses the x86-64 architecture)

At least 2 MiB of RAM

The ability to boot via a hard drive, USB stick, or the network

Writing the Kernel with NASM

Here's a minimal kernel, written for NASM, that you could use with Pure64. Once it's loaded, it enters an infinite loop. The file can be called kernel.asm.

BITS 64
ORG 0x100000

start:
	jmp start

The ORG statement tells NASM that the code should be made to run at the address, 0x100000.

Assemble it like this:

nasm kernel.asm -o kernel.bin

Writing a Kernel with GCC

Here's a similar example written in C with GCC. The file can be called kernel.c.

void _start(void) {

	for (;;) {

	}
}

The kernel needs a linker script to be loaded to 1 MiB, replacing NASMs ORG instruction. The file can be called kernel.ld.

OUTPUT_FORMAT("binary")
OUTPUT_ARCH("i386:x86-64")

SECTIONS
{
    . = 0x100000;
    .text : {
        *(.text)
    }
    .data : {
        *(.data)
    }
    .rodata : {
        *(.rodata)
    }
    .bss : {
        *(.bss)
    }
}

Compile is like this:

gcc -c kernel.c -o kernel.o -mno-red-zone -fno-stack-protector -fomit-frame-pointer
ld -T kernel.ld -o kernel.bin kernel.o

The flags added to the first command are there to help GCC produce could that will run in kernel space. The second command simply takes kernel.o and orders it as the linker script tells it to.

Contributors note

The _start symbol must always appear first within flat binaries as Pure64 will call the start of the file so it must contain executable code. Function definitions (such as inline ones) in header files could interfere with the placement of the _start symbol. The best solution is to put the entry point in a separate file that calls the main function. Such a file could be called start.c.

extern int main(void);

void _start(void)
{
    main();
}

This file would always have to be linked in front of everything else. For the above example that would mean the linker command above would have to become:

ld -T kernel.ld -o kernel.bin start.o kernel.o

Creating a bootable image

After creating a kernel this is a possible routine to create a bootable image. The commands require Pure64 to be build and pure64.sys and mbr.sys to be in the same directory as your kernel with the name kernel.bin

dd if=/dev/zero of=disk.img count=128 bs=1048576
cat pure64.sys kernel.bin > software.sys

dd if=mbr.sys of=disk.img conv=notrunc
dd if=software.sys of=disk.img bs=512 seek=16 conv=notrunc

After creating a bootable image it can be tested using qemu: qemu-system-x86_64 -drive format=raw,file=disk.img

Memory Map

This memory map shows how physical memory looks after Pure64 is finished.

Start AddressEnd AddressSizeDescription
0x00000000000000000x0000000000000FFF4 KiBIDT - 256 descriptors (each descriptor is 16 bytes)
0x00000000000010000x0000000000001FFF4 KiBGDT - 256 descriptors (each descriptor is 16 bytes)
0x00000000000020000x0000000000002FFF4 KiBPML4 - 512 entries, first entry points to PDP at 0x3000
0x00000000000030000x0000000000003FFF4 KiBPDP Low - 512 entries
0x00000000000040000x0000000000004FFF4 KiBPDP High - 512 entries
0x00000000000050000x0000000000007FFF12 KiBPure64 Data
0x00000000000080000x000000000000FFFF32 KiBPure64 - After the OS is loaded and running this memory is free again
0x00000000000100000x000000000001FFFF64 KiBPD Low - Entries are 8 bytes per 2MiB page
0x00000000000200000x000000000005FFFF256 KiBPD High - Entries are 8 bytes per 2MiB page
0x00000000000600000x000000000009FFFF256 KiBFree
0x00000000000A00000x00000000000FFFFF384 KiBROM Area
   VGA mem at 0xA0000 (128 KiB) Color text starts at 0xB8000
   Video BIOS at 0xC0000 (64 KiB)
   Motherboard BIOS at F0000 (64 KiB)
0x00000000001000000xFFFFFFFFFFFFFFFF1+ MiBThe software payload is loaded here

When creating your Operating System or Demo you can use the sections marked free, however it is the safest to use memory above 1 MiB.

Information Table

Pure64 stores an information table in memory that contains various pieces of data about the computer before it passes control over to the software you want it to load.

The Pure64 information table is located at 0x0000000000005000 and ends at 0x00000000000057FF (2048 bytes).

Memory AddressVariable SizeNameDescription
0x500064-bitACPIAddress of the ACPI tables
0x500832-bitBSP_IDAPIC ID of the BSP
0x501016-bitCPUSPEEDSpeed of the CPUs in MegaHertz (MHz)
0x501216-bitCORES_ACTIVEThe number of CPU cores that were activated in the system
0x501416-bitCORES_DETECTThe number of CPU cores that were detected in the system
0x5016 - 0x501F  For future use
0x502032-bitRAMAMOUNTAmount of system RAM in Mebibytes (MiB)
0x5022 - 0x502F  For future use
0x50308-bitIOAPIC_COUNTNumber of IO-APICs in the system
0x5031 - 0x503F  For future use
0x504064-bitHPETBase memory address for the High Precision Event Timer
0x5048 - 0x505F  For future use
0x506064-bitLAPICLocal APIC address
0x5068 - 0x507F64-bitIOAPICIO-APIC addresses (based on IOAPIC_COUNT)
0x508032-bitVIDEO_BASEBase memory for video (if graphics mode set)
0x508416-bitVIDEO_XX resolution
0x508616-bitVIDEO_YY resolution
0x50888-bitVIDEO_DEPTHColor depth
0x5089 - 0x50FF  For future use
0x5100...8-bitAPIC_IDAPIC ID's for valid CPU cores (based on CORES_ACTIVE)

A copy of the E820 System Memory Map is stored at memory address 0x0000000000006000. Each E820 record is 32 bytes in length and the memory map is terminated by a blank record.

VariableVariable SizeDescription
Starting Address64-bitThe starting address for this record
Length64-bitThe length of memory for this record
Memory Type32-bitType 1 is usable memory, Type 2 is not usable
Extended Attributes32-bitACPI 3.0 Extended Attributes bitfield
Padding64-bitPadding for 32-byte alignment
For more information on the E820 Memory Map: OSDev wiki on E820