Commit 3f2fdf00 authored by Adam Matoušek's avatar Adam Matoušek
Browse files

Vysokopůlní jádro.

parent 269ea64e
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -13,7 +13,7 @@ boot.img: a.out
	$(MKRESCUE) -o $@ _boot
	rm -rf _boot

a.out: mem/paging.o dev/io.o kernel.o boot.o
a.out: mem/paging.o dev/io.o kernel.o boot.o util.o
	$(LD) -o $@ -T linkscript $(CFLAGS) $(LDFLAGS) $^

%.o: %.cpp
+86 −14
Original line number Diff line number Diff line
#define ASM_FILE        1
// Stack size shall be at most 4M
#define STACK_SIZE      0x4000
#define HIGHER_HALF     0xC0000000
#define VIRT_STACK      0xFFC00000
#include "multiboot2.h"

        .text

        .globl  start, _start
start:
_start:
        jmp     multiboot_entry

        .section .multiboot
        .align  8 /* required multiboot header alignment */
multiboot_header:
        .long   MULTIBOOT2_HEADER_MAGIC
@@ -17,23 +14,78 @@ multiboot_header:
        .long   -( MULTIBOOT2_HEADER_MAGIC + MULTIBOOT_ARCHITECTURE_I386 \
                   + ( multiboot_header_end - multiboot_header ) )

        .align 8 /* each tag must be aligned separately */
        .short MULTIBOOT_HEADER_TAG_ADDRESS
        .short 0                        /* flags */
        .long 24                        /* tag size */
        .long (multiboot_header - HIGHER_HALF) /* header address */
        .long (_kernel_start - HIGHER_HALF)    /* load address */
        .long (_kernel_end - HIGHER_HALF)      /* load end address */
        .long (_bss_end - HIGHER_HALF)         /* bss end address */


        .align 8 /* each tag must be aligned separately */
        .short MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS
        .short 0                        /* flags */
        .long 12                        /* tag size */
        .long (start - HIGHER_HALF)     /* entry address */

        .align 8 /* each tag must be aligned separately */
        .short MULTIBOOT_HEADER_TAG_END /* tag id */
        .short 0                        /* flags */
        .long 8                         /* tag size */
multiboot_header_end:

        .text

        .globl  start, _start
        .type _start, @function

#define VIDEO 0xC00B8000

_start:
start:
multiboot_entry:
        movl    $(stack + STACK_SIZE), %esp /* stack pointer */

        movl    %eax, %esi
        movl    %ebx, %edi

        movl    $(page_directory - HIGHER_HALF), %eax
        movl    %eax, %cr3              # Set phys. addr. of page directory
        mov     %cr4, %eax
        or      $0x00000010, %eax       # Enable PSE
        mov     %eax, %cr4
        mov     %cr0, %eax
        or      $0x80000001, %eax       # Enable paging
        mov     %eax, %cr0

        mov     $higher, %eax
        jmp     *%eax

higher:
        /* map the stack base to 4G minus 4M */
        movl    $((STACK_SIZE >> 12) - 1), %ecx
loop1:
        movl    %ecx, %ebx
        shl     $12, %ebx
        add     $(stack - HIGHER_HALF), %ebx
        or      $0x3, %ebx
        mov     %ecx, %eax
        shl     $2, %eax
        add     $(stack_pgtbl + 0x1000 - (STACK_SIZE >> 10) ), %eax
        movl    %ebx, (%eax)
        dec     %ecx
        jns     loop1

        movl    $VIRT_STACK, %esp       # Map stack to a new virt. addr.
        pushl   $0
        popf                                /* reset EFLAGS */
        popf

        pushl   %edi /* multiboot information structure */
        pushl   %esi /* multiboot magic value */
        call    main

        pushl   %ebx /* multiboot information structure */
        pushl   %eax /* multiboot magic value */
        call    main /* let's C */
        jmp     pre_halt

#define VIDEO 0xB8000
pre_halt:
        mov     $2, %ecx
loop_flags_row:
@@ -61,6 +113,26 @@ empty:
        hlt
#undef VIDEO

#define HH_PGDIR_IDX (HIGHER_HALF >> 22)
        .section .paging
        .global page_directory
        .align 0x1000
page_directory:
        .long 0x00000083                        # Id-map low 4M
        .fill (HH_PGDIR_IDX - 1), 4, 0x0        # Nothing
        .long 0x00000083                        # Map low 4M to HIGHER_HALF
        .fill (1021 - HH_PGDIR_IDX), 4, 0x0     # Nothing
        .long (stack_pgtbl - HIGHER_HALF + 0x3) # Page table for the stack
        .long 0x00000000

        .align 0x1000
stack_pgtbl:
        .fill 1020, 4, 0x0                    # Nothing
        .long (stack - HIGHER_HALF + 0x3)     # Four static stack pages
        .long (stack - HIGHER_HALF + 0x1003)
        .long (stack - HIGHER_HALF + 0x2003)
        .long (stack - HIGHER_HALF + 0x3003)

halt_message:
        .asciz  "  Nyni muzete pocitac bezpecne vypnout  "
        .comm   stack, STACK_SIZE /* the stack */
+7 −1
Original line number Diff line number Diff line
@@ -7,7 +7,8 @@ namespace masys {
namespace dev {

class Vga : public CharacterOutput {
    u8 * const video = ( u8 * ) 0xB8000;

    u8 * const video;
    const int columns = 80;
    const int lines = 24;

@@ -15,6 +16,11 @@ class Vga : public CharacterOutput {
       y = 0,
       flags = 0x07;
public:
    static const u32 MEMORY_MAPPED = 0xB8000;

    Vga( u8 * fb_addr )
        : video( fb_addr ) {}

    Status putch( u8 c ) {
        if ( c == '\b' && x > 0 ) {
            --x;
+34 −30
Original line number Diff line number Diff line
#include <dev/vga.hpp>
#include <dev/serial.hpp>
#include <mem/paging.hpp>
#include <util.hpp>
#include <multiboot2.h>

namespace masys {

const size_t PAGE_SIZE = 4096;

alignas( PAGE_SIZE ) mem::PageEntry page_directory[ PAGE_SIZE ];

void kernel( unsigned long magic, unsigned long addr )
{
    dev::Vga vga;
    vga.clear();
extern "C" {

    vga.puts( "Enabling paging...\n" );
extern masys::mem::PageEntry page_directory[];

    for ( auto & pgdir_entry : page_directory )
    {
        pgdir_entry._raw = 0;
}
    auto & mypage = page_directory[ 1 << 8 ];
    mypage.present = 1;

    mem::enable_paging( page_directory );
namespace masys {

const size_t PAGE_SIZE = 0x1000;
const size_t PAGEDIR_ENTRIES = 1024;
const u32 HIGHER_HALF = 0xC0000000;

    if ( magic != MULTIBOOT2_BOOTLOADER_MAGIC )
void kernel( unsigned long magic, unsigned long addr )
{
        vga.puts( "invalid magic number :-(" );
        return;
    }
    dev::SerialLine ser( dev::SERIAL_PORT_1 );

    if ( addr & 7 )
    {
        vga.puts( "unaligned mbi :-(" );
        return;
    }
    char buf[32];
    ser.puts( "Page Directory address: 0x" );
    itoa( (u32) page_directory, buf, 16 );
    ser.puts( buf );
    ser.putch( '\n' );
    ser.puts( "Stack pointer: 0x" );
    itoa( (u32) buf, buf, 16 );
    ser.puts( buf );
    ser.putch( '\n' );
    ser.puts( "Multiboot info address: 0x" );
    itoa( addr, buf, 16 );
    ser.puts( buf );
    ser.putch( '\n' );

    dev::Vga vga( (u8*) dev::Vga::MEMORY_MAPPED + HIGHER_HALF );
    vga.clear();
    vga.puts( "\nSwitched.\n" );

    // TODO: Don't assume that multiboot info is in lower 4M
    vga.puts( "Co nam Multiboot povedel:\n================================\n" );

    auto tag = reinterpret_cast< multiboot_tag * >( addr + 8 );
@@ -58,11 +60,12 @@ void kernel( unsigned long magic, unsigned long addr )
                  + tag->size + 7 ) & 0xfffffff8UL );
    }

    vga.puts( "Nyni ocekavam vstup na seriove lince (coz je stdin, ehm).\n" );
    vga.puts( "^D ukonci cinnost tohoto bohorovneho jadra.\n\n" );
    /* Cancel id-mapping */
    page_directory[ 0 ].present = 0;

    vga.puts( "Nyni ocekavam vstup na seriove lince.\n" );
    vga.puts( "^D ukonci cinnost tohoto bohorovneho jadra.\n\n" );

    dev::SerialLine ser( dev::SERIAL_PORT_1 );
    ser.puts( "Ahoj svete za seriovou linkou! Povez mi neco:\n" );

    const char CTRL_D = 4;
@@ -74,6 +77,7 @@ void kernel( unsigned long magic, unsigned long addr )
        ser.putch( a );
    } while ( a != CTRL_D );

    ser.puts( "\nKernel konec.\n" );
    vga.puts( "\nKernel konec.\n" );
}

+11 −7
Original line number Diff line number Diff line
@@ -6,37 +6,41 @@ ENTRY(_start)
   kernel image. */
SECTIONS
{
	/* Begin putting sections at 1 MiB, a conventional place for kernels to be
	   loaded at by the bootloader. */
	. = 1M;
	/* This is a higher half kernel, virtually at 1G+1M, physically at 1M */
	. = 0xC0100000;

        _kernel_start = .;
	/* First put the multiboot header, as it is required to be put very early
	   early in the image or the bootloader won't recognize the file format.
	   Next we'll put the .text section. */
	.text BLOCK(4K) : ALIGN(4K)
	.text BLOCK(4K) : AT(ADDR(.text) - 0xC000000)
	{
		*(.multiboot)
		*(.text)
	}

	/* Read-only data. */
	.rodata BLOCK(4K) : ALIGN(4K)
	.rodata BLOCK(4K) : AT(ADDR(.rodata) - 0xC000000)
	{
		*(.rodata)
	}

	/* Read-write data (initialized) */
	.data BLOCK(4K) : ALIGN(4K)
	.data BLOCK(4K) : AT(ADDR(.data) - 0xC000000)
	{
                *(.paging)
		*(.data)
	}

        _kernel_end = .;

	/* Read-write data (uninitialized) and stack */
	.bss BLOCK(4K) : ALIGN(4K)
	.bss BLOCK(4K) : AT(ADDR(.bss) - 0xC000000)
	{
		*(COMMON)
		*(.bss)
	}
        _bss_end = .;

	/* The compiler may produce other sections, by default it will put them in
	   a segment with the same name. Simply add stuff here as needed. */
Loading