Add Multiboot information struct and pass it in to kmain()
Print memory availability
This commit is contained in:
		
							parent
							
								
									98ad3282c1
								
							
						
					
					
						commit
						100da19d28
					
				
					 4 changed files with 274 additions and 6 deletions
				
			
		
							
								
								
									
										23
									
								
								src/Main.cc
									
										
									
									
									
								
							
							
						
						
									
										23
									
								
								src/Main.cc
									
										
									
									
									
								
							| 
						 | 
					@ -1,8 +1,17 @@
 | 
				
			||||||
 | 
					/* Main.cc
 | 
				
			||||||
 | 
					 * vim: set tw=80:
 | 
				
			||||||
 | 
					 * Eryn Wells <eryn@erynwells.me>
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Entry point for the kernel in C/C++.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <stddef.h>
 | 
					#include <stddef.h>
 | 
				
			||||||
#include <stdint.h>
 | 
					#include <stdint.h>
 | 
				
			||||||
#include "Console.hh"
 | 
					#include "Console.hh"
 | 
				
			||||||
#include "Descriptors.hh"
 | 
					#include "Descriptors.hh"
 | 
				
			||||||
#include "Interrupts.hh"
 | 
					#include "Interrupts.hh"
 | 
				
			||||||
 | 
					#include "Multiboot.hh"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if defined(__linux__)
 | 
					#if defined(__linux__)
 | 
				
			||||||
#error "This file should be compiled with a cross-compiler, not the Linux system compiler!"
 | 
					#error "This file should be compiled with a cross-compiler, not the Linux system compiler!"
 | 
				
			||||||
| 
						 | 
					@ -19,10 +28,7 @@ kearly()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    using kernel::Console;
 | 
					    using kernel::Console;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /*
 | 
					    // Create a console object for early use because global initialization hasn't happened yet.
 | 
				
			||||||
     * Create a console object for early use because global initialization
 | 
					 | 
				
			||||||
     * hasn't happened yet.
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    Console console;
 | 
					    Console console;
 | 
				
			||||||
    console.clear(kernel::Console::Color::Blue);
 | 
					    console.clear(kernel::Console::Color::Blue);
 | 
				
			||||||
    console.printString("Loading system ...\n");
 | 
					    console.printString("Loading system ...\n");
 | 
				
			||||||
| 
						 | 
					@ -32,12 +38,19 @@ kearly()
 | 
				
			||||||
/** The beginning of the world... */
 | 
					/** The beginning of the world... */
 | 
				
			||||||
extern "C"
 | 
					extern "C"
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
kmain()
 | 
					kmain(multiboot::Information *information)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    multiboot::Information::setInformation(information);
 | 
				
			||||||
 | 
					    auto info = multiboot::Information::information();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Reinitialize the system console now that we have global static objects.
 | 
					    // Reinitialize the system console now that we have global static objects.
 | 
				
			||||||
    auto& console = kernel::Console::systemConsole();
 | 
					    auto& console = kernel::Console::systemConsole();
 | 
				
			||||||
    console.clear(kernel::Console::Color::Blue);
 | 
					    console.clear(kernel::Console::Color::Blue);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    console.printString("Loading Polka ...\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    console.printFormat("Detected memory: lower = %ld KB, upper = %ld KB\n", info->lowerMemoryKB(), info->upperMemoryKB());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    auto& gdt = x86::GDT::systemGDT();
 | 
					    auto& gdt = x86::GDT::systemGDT();
 | 
				
			||||||
    gdt.setNullDescriptor(0);
 | 
					    gdt.setNullDescriptor(0);
 | 
				
			||||||
    gdt.setDescriptor(1, x86::GDT::DescriptorSpec::kernelSegment(0, 0xFFFFFFFF, x86::GDT::Type::CodeEXR));
 | 
					    gdt.setDescriptor(1, x86::GDT::DescriptorSpec::kernelSegment(0, 0xFFFFFFFF, x86::GDT::Type::CodeEXR));
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										87
									
								
								src/Multiboot.cc
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								src/Multiboot.cc
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,87 @@
 | 
				
			||||||
 | 
					/* Multiboot.cc
 | 
				
			||||||
 | 
					 * vim: set tw=80:
 | 
				
			||||||
 | 
					 * Eryn Wells <eryn@erynwells.me>
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Definition of multiboot stuff.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "Multiboot.hh"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum Present {
 | 
				
			||||||
 | 
					    Memory = 1 << 0,
 | 
				
			||||||
 | 
					    BootDevice = 1 << 1,
 | 
				
			||||||
 | 
					    CommandLine = 1 << 2,
 | 
				
			||||||
 | 
					    Modules = 1 << 3,
 | 
				
			||||||
 | 
					    AOutSymbols = 1 << 4,
 | 
				
			||||||
 | 
					    ElfSymbols = 1 << 5,
 | 
				
			||||||
 | 
					    MemoryMap = 1 << 6,
 | 
				
			||||||
 | 
					    Drives = 1 << 7,
 | 
				
			||||||
 | 
					    ConfigurationTable = 1 << 8,
 | 
				
			||||||
 | 
					    BootLoaderName = 1 << 9,
 | 
				
			||||||
 | 
					    APMTable = 1 << 10,
 | 
				
			||||||
 | 
					    VBE = 1 << 11,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					multiboot::Information *sInformation = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace multiboot {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Static
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const Information *
 | 
				
			||||||
 | 
					Information::information()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return sInformation;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					Information::setInformation(Information *info)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    sInformation = info;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Public
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint32_t
 | 
				
			||||||
 | 
					Information::lowerMemoryKB()
 | 
				
			||||||
 | 
					    const
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if ((mFlags & Present::Memory) == 0) {
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return mMemLower;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint32_t
 | 
				
			||||||
 | 
					Information::upperMemoryKB()
 | 
				
			||||||
 | 
					    const
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if ((mFlags & Present::Memory) == 0) {
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return mMemUpper;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const char *
 | 
				
			||||||
 | 
					Information::commandLine()
 | 
				
			||||||
 | 
					    const
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if ((mFlags & Present::CommandLine) == 0) {
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return reinterpret_cast<const char *>(mCommandLine);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					} /* namespace multiboot */
 | 
				
			||||||
							
								
								
									
										167
									
								
								src/Multiboot.hh
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										167
									
								
								src/Multiboot.hh
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,167 @@
 | 
				
			||||||
 | 
					/* Multiboot.hh
 | 
				
			||||||
 | 
					 * vim: set tw=80:
 | 
				
			||||||
 | 
					 * Eryn Wells <eryn@erynwells.me>
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Definition of the Multiboot structure. When grub boots, it fills in this
 | 
				
			||||||
 | 
					 * structure and leaves a pointer to it in the EBX register.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef __MULTIBOOT_HH__
 | 
				
			||||||
 | 
					#define __MULTIBOOT_HH__
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "stdint.h"
 | 
				
			||||||
 | 
					#include "Attributes.hh"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace multiboot {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * The multiboot information struct. Defined by the multiboot spec.
 | 
				
			||||||
 | 
					 * See http://www.gnu.org/software/grub/manual/multiboot/multiboot.html#Machine-state
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					struct PACKED Information
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    static const Information *information();
 | 
				
			||||||
 | 
					    static void setInformation(Information* info);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    uint32_t lowerMemoryKB() const;
 | 
				
			||||||
 | 
					    uint32_t upperMemoryKB() const;
 | 
				
			||||||
 | 
					    const char* commandLine() const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Bit field of flags. Fields below are only defined if the appropriate
 | 
				
			||||||
 | 
					     * flag is set.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    uint32_t mFlags;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /** Amount of lower (0 to 1 MB) memory, in KB. */
 | 
				
			||||||
 | 
					    uint32_t mMemLower;
 | 
				
			||||||
 | 
					    /** Amount of upper (1 MB to ...) memory, in KB. Maximally, this value is the address of the first upper memory hole, minus 1 MB. */
 | 
				
			||||||
 | 
					    uint32_t mMemUpper;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Indicates which BIOS disk the boot loader loaded the OS image from.
 | 
				
			||||||
 | 
					     * Defined only if `bootDevice == true`.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    struct PACKED
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        /** Third level partition number. If unused this is set to 0xFF. */
 | 
				
			||||||
 | 
					        uint8_t partitionLevel3;
 | 
				
			||||||
 | 
					        /** Sub-partition number. If unused this is set to 0xFF. */
 | 
				
			||||||
 | 
					        uint8_t partitionLevel2;
 | 
				
			||||||
 | 
					        /** Top-level partition number. */
 | 
				
			||||||
 | 
					        uint8_t partitionLevel1;
 | 
				
			||||||
 | 
					        /**
 | 
				
			||||||
 | 
					         * BIOS drive number, as returned by the `INT 0x13` low-level disk
 | 
				
			||||||
 | 
					         * interface.
 | 
				
			||||||
 | 
					         */
 | 
				
			||||||
 | 
					        uint8_t driveNumber;
 | 
				
			||||||
 | 
					    } bootDevice;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Pointer to a C-style string containing the command line arguments.
 | 
				
			||||||
 | 
					     * Defined only if `commandLinePresent == true`.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    uint32_t mCommandLine;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Indicates what boot modules were loaded along with the kernel image.
 | 
				
			||||||
 | 
					     * Defined only if `modulesPresent == true`.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    struct PACKED
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        /** Number of boot modules present. */
 | 
				
			||||||
 | 
					        uint32_t count;
 | 
				
			||||||
 | 
					        /** Pointer to start of boot modules array. */
 | 
				
			||||||
 | 
					        uint32_t address;
 | 
				
			||||||
 | 
					    } modules;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // TODO: Document these.
 | 
				
			||||||
 | 
					    union PACKED
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        struct PACKED
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            uint32_t tableSize;
 | 
				
			||||||
 | 
					            uint32_t stringSize;
 | 
				
			||||||
 | 
					            uint32_t address;
 | 
				
			||||||
 | 
					            uint32_t reserved;
 | 
				
			||||||
 | 
					        } aout;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        struct PACKED
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            uint32_t number;
 | 
				
			||||||
 | 
					            uint32_t size;
 | 
				
			||||||
 | 
					            uint32_t address;
 | 
				
			||||||
 | 
					            uint32_t shndx;
 | 
				
			||||||
 | 
					        } elf;
 | 
				
			||||||
 | 
					    } symbols;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Points to a buffer containing a memory map of the machine provided by the
 | 
				
			||||||
 | 
					     * BIOS. Defined only if `memoryMapPresent == true`.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    struct PACKED
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        /** Number of memory map entries present. */
 | 
				
			||||||
 | 
					        uint32_t count;
 | 
				
			||||||
 | 
					        /** Pointer to start of memory map entry array. */
 | 
				
			||||||
 | 
					        uint32_t address;
 | 
				
			||||||
 | 
					    } memoryMap;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Points to a buffer containing a list of drive definitions provided by the
 | 
				
			||||||
 | 
					     * BIOS. Defined only if `drivesPresent == true`.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    struct PACKED
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        /** Number of memory map entries present. */
 | 
				
			||||||
 | 
					        uint32_t count;
 | 
				
			||||||
 | 
					        /** Pointer to start of memory map entry array. */
 | 
				
			||||||
 | 
					        uint32_t address;
 | 
				
			||||||
 | 
					    } drives;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Pointer to the table containing APM information. Defined only if
 | 
				
			||||||
 | 
					     * `apmTablePresent == true`.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    uint32_t apmTable;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * I dunno some VBE stuff. TODO.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    struct PACKED {
 | 
				
			||||||
 | 
					        uint32_t controlInformation;
 | 
				
			||||||
 | 
					        uint32_t modeInformation;
 | 
				
			||||||
 | 
					        uint32_t mode;
 | 
				
			||||||
 | 
					        uint32_t interfaceSegment;
 | 
				
			||||||
 | 
					        uint32_t interfaceOff;
 | 
				
			||||||
 | 
					        uint32_t interfaceLength;
 | 
				
			||||||
 | 
					    } vbe;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct PACKED Module
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /** Start address of boot module. */
 | 
				
			||||||
 | 
					    uint32_t start;
 | 
				
			||||||
 | 
					    /** End address of boot module. */
 | 
				
			||||||
 | 
					    uint32_t end;
 | 
				
			||||||
 | 
					    /** Pointer to a C-style boot module string. */
 | 
				
			||||||
 | 
					    uint32_t string;
 | 
				
			||||||
 | 
					    /** Reserved and ignored. */
 | 
				
			||||||
 | 
					    uint32_t reserved;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// TODO: Define the MemoryMap struct
 | 
				
			||||||
 | 
					struct PACKED MemoryChunk
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// TODO: Define the Drive struct
 | 
				
			||||||
 | 
					struct PACKED Drive
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					} /* namespace multiboot */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* __MULTIBOOT_HH__ */
 | 
				
			||||||
| 
						 | 
					@ -41,7 +41,8 @@ _start:
 | 
				
			||||||
    # Global initialization done here.
 | 
					    # Global initialization done here.
 | 
				
			||||||
    call _init
 | 
					    call _init
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Here we go...
 | 
					    # Here we go... Give kmain the address of the multiboot info structure.
 | 
				
			||||||
 | 
					    pushl %ebx
 | 
				
			||||||
    call kmain
 | 
					    call kmain
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # In case the function returns, we'll want to put the computer into an
 | 
					    # In case the function returns, we'll want to put the computer into an
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue