just merge #1
12 changed files with 874 additions and 0 deletions
72
prototypes/video/Makefile
Normal file
72
prototypes/video/Makefile
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
|
||||||
|
AS=gcc
|
||||||
|
CC=gcc
|
||||||
|
CXX=g++
|
||||||
|
LD=ld
|
||||||
|
|
||||||
|
LIBGCC = $(shell gcc -m32 -print-libgcc-file-name)
|
||||||
|
INCLUDE_DIRS =
|
||||||
|
|
||||||
|
FLAGS = -mno-sse -ffreestanding -m32 -Werror -Wall -iquote include -iquote lists $(addprefix -I, $(INCLUDE_DIRS)) -O3 -g
|
||||||
|
ASFLAGS = $(FLAGS)
|
||||||
|
CFLAGS = $(FLAGS)
|
||||||
|
CXXFLAGS = $(FLAGS) -std=c++14 -fno-rtti -fno-exceptions -fno-leading-underscore -fno-use-cxa-atexit -nostdlib -fno-builtin
|
||||||
|
|
||||||
|
SRCS = $(shell find -regextype egrep -regex '.*/.*\.(cpp|S|c)')
|
||||||
|
OBJS = $(addsuffix .o, $(notdir $(basename $(SRCS))))
|
||||||
|
LIBS = $(LIBGCC) $(LIBSTD) $(LIBVM)
|
||||||
|
|
||||||
|
all: build-dirs video.ker
|
||||||
|
|
||||||
|
build-dirs:
|
||||||
|
mkdir -p obj
|
||||||
|
|
||||||
|
video.ker: $(OBJS)
|
||||||
|
$(LD) -melf_i386 -Tlinker.ld -o $@ $(addprefix obj/, $^) $(LIBS)
|
||||||
|
|
||||||
|
%.o: %.cpp
|
||||||
|
$(CXX) $(CXXFLAGS) -c -o obj/$@ $<
|
||||||
|
|
||||||
|
%.o: %.c
|
||||||
|
$(CC) $(ASFLAGS) -c -o obj/$@ $<
|
||||||
|
|
||||||
|
%.o: %.S
|
||||||
|
$(AS) $(CFLAGS) -c -o obj/$@ $<
|
||||||
|
|
||||||
|
%.o: src/%.cpp
|
||||||
|
$(CXX) $(CXXFLAGS) -c -o obj/$@ $<
|
||||||
|
|
||||||
|
%.o: src/%.c
|
||||||
|
$(CC) $(ASFLAGS) -c -o obj/$@ $<
|
||||||
|
|
||||||
|
%.o: src/%.S
|
||||||
|
$(AS) $(CFLAGS) -c -o obj/$@ $<
|
||||||
|
|
||||||
|
# Linux/Multiboot boot specific:
|
||||||
|
# -kernel bzImage use 'bzImage' as kernel image
|
||||||
|
# -append cmdline use 'cmdline' as kernel command line
|
||||||
|
# -initrd file use 'file' as initial ram disk
|
||||||
|
# -dtb file use 'file' as device tree image
|
||||||
|
|
||||||
|
boot: image
|
||||||
|
qemu-system-i386 \
|
||||||
|
-fda boot.img \
|
||||||
|
-m 64 \
|
||||||
|
-d cpu_reset,int \
|
||||||
|
-serial stdio
|
||||||
|
# -no-reboot \
|
||||||
|
# -no-shutdown \
|
||||||
|
|
||||||
|
insight:
|
||||||
|
objdump -d kernel-base.ker | c++filt | less
|
||||||
|
|
||||||
|
bnr: video.ker run
|
||||||
|
|
||||||
|
deploy: video.ker
|
||||||
|
cp video.ker /srv/tftp/video.ker
|
||||||
|
|
||||||
|
image: video.ker
|
||||||
|
mformat -C -f 1440 -v VIDEO -i boot.img ::
|
||||||
|
mcopy -i boot.img video.ker syslinux.cfg /boot/syslinux/libcom32.c32 /boot/syslinux/mboot.c32 ::
|
||||||
|
syslinux boot.img
|
||||||
|
mdir -i boot.img ::
|
BIN
prototypes/video/boot.img
Normal file
BIN
prototypes/video/boot.img
Normal file
Binary file not shown.
17
prototypes/video/compat.c
Normal file
17
prototypes/video/compat.c
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
#include "compat.h"
|
||||||
|
|
||||||
|
typedef void (*constructor)();
|
||||||
|
|
||||||
|
constructor start_ctors;
|
||||||
|
constructor end_ctors;
|
||||||
|
|
||||||
|
void compat_call_ctors()
|
||||||
|
{
|
||||||
|
for (constructor* i = &start_ctors;i != &end_ctors;++i)
|
||||||
|
(*i)();
|
||||||
|
}
|
||||||
|
|
||||||
|
void compat_call_dtors()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
23
prototypes/video/entrypoint.S
Normal file
23
prototypes/video/entrypoint.S
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
.section .text
|
||||||
|
|
||||||
|
.extern init
|
||||||
|
.extern compat_call_ctors
|
||||||
|
.extern compat_call_dtors
|
||||||
|
|
||||||
|
.global _start
|
||||||
|
_start:
|
||||||
|
mov $kernel_stack, %esp
|
||||||
|
|
||||||
|
push %ebx
|
||||||
|
call compat_call_ctors
|
||||||
|
call init
|
||||||
|
call compat_call_dtors
|
||||||
|
|
||||||
|
_stop:
|
||||||
|
cli
|
||||||
|
hlt
|
||||||
|
jmp _stop
|
||||||
|
|
||||||
|
.section .bss
|
||||||
|
.space 8192
|
||||||
|
kernel_stack:
|
13
prototypes/video/include/compat.h
Normal file
13
prototypes/video/include/compat.h
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void compat_call_ctors();
|
||||||
|
|
||||||
|
void compat_call_dtors();
|
||||||
|
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
}
|
||||||
|
#endif
|
309
prototypes/video/include/multiboot.h
Normal file
309
prototypes/video/include/multiboot.h
Normal file
|
@ -0,0 +1,309 @@
|
||||||
|
/* multiboot.h - Multiboot header file. */
|
||||||
|
/* Copyright (C) 1999,2003,2007,2008,2009,2010 Free Software Foundation, Inc.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to
|
||||||
|
* deal in the Software without restriction, including without limitation the
|
||||||
|
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||||
|
* sell copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ANY
|
||||||
|
* DEVELOPER OR DISTRIBUTOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
|
||||||
|
* IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MULTIBOOT_HEADER
|
||||||
|
#define MULTIBOOT_HEADER 1
|
||||||
|
|
||||||
|
/* How many bytes from the start of the file we search for the header. */
|
||||||
|
#define MULTIBOOT_SEARCH 8192
|
||||||
|
#define MULTIBOOT_HEADER_ALIGN 4
|
||||||
|
|
||||||
|
/* The magic field should contain this. */
|
||||||
|
#define MULTIBOOT_HEADER_MAGIC 0x1BADB002
|
||||||
|
|
||||||
|
/* This should be in %eax. */
|
||||||
|
#define MULTIBOOT_BOOTLOADER_MAGIC 0x2BADB002
|
||||||
|
|
||||||
|
/* Alignment of multiboot modules. */
|
||||||
|
#define MULTIBOOT_MOD_ALIGN 0x00001000
|
||||||
|
|
||||||
|
/* Alignment of the multiboot info structure. */
|
||||||
|
#define MULTIBOOT_INFO_ALIGN 0x00000004
|
||||||
|
|
||||||
|
/* Flags set in the 'flags' member of the multiboot header. */
|
||||||
|
|
||||||
|
/* Align all boot modules on i386 page (4KB) boundaries. */
|
||||||
|
#define MULTIBOOT_PAGE_ALIGN 0x00000001
|
||||||
|
|
||||||
|
/* Must pass memory information to OS. */
|
||||||
|
#define MULTIBOOT_MEMORY_INFO 0x00000002
|
||||||
|
|
||||||
|
/* Must pass video information to OS. */
|
||||||
|
#define MULTIBOOT_VIDEO_MODE 0x00000004
|
||||||
|
|
||||||
|
/* This flag indicates the use of the address fields in the header. */
|
||||||
|
#define MULTIBOOT_AOUT_KLUDGE 0x00010000
|
||||||
|
|
||||||
|
/* Flags to be set in the 'flags' member of the multiboot info structure. */
|
||||||
|
|
||||||
|
/* is there basic lower/upper memory information? */
|
||||||
|
#define MULTIBOOT_INFO_MEMORY 0x00000001
|
||||||
|
/* is there a boot device set? */
|
||||||
|
#define MULTIBOOT_INFO_BOOTDEV 0x00000002
|
||||||
|
/* is the command-line defined? */
|
||||||
|
#define MULTIBOOT_INFO_CMDLINE 0x00000004
|
||||||
|
/* are there modules to do something with? */
|
||||||
|
#define MULTIBOOT_INFO_MODS 0x00000008
|
||||||
|
|
||||||
|
/* These next two are mutually exclusive */
|
||||||
|
|
||||||
|
/* is there a symbol table loaded? */
|
||||||
|
#define MULTIBOOT_INFO_AOUT_SYMS 0x00000010
|
||||||
|
/* is there an ELF section header table? */
|
||||||
|
#define MULTIBOOT_INFO_ELF_SHDR 0X00000020
|
||||||
|
|
||||||
|
/* is there a full memory map? */
|
||||||
|
#define MULTIBOOT_INFO_MEM_MAP 0x00000040
|
||||||
|
|
||||||
|
/* Is there drive info? */
|
||||||
|
#define MULTIBOOT_INFO_DRIVE_INFO 0x00000080
|
||||||
|
|
||||||
|
/* Is there a config table? */
|
||||||
|
#define MULTIBOOT_INFO_CONFIG_TABLE 0x00000100
|
||||||
|
|
||||||
|
/* Is there a boot loader name? */
|
||||||
|
#define MULTIBOOT_INFO_BOOT_LOADER_NAME 0x00000200
|
||||||
|
|
||||||
|
/* Is there a APM table? */
|
||||||
|
#define MULTIBOOT_INFO_APM_TABLE 0x00000400
|
||||||
|
|
||||||
|
/* Is there video information? */
|
||||||
|
#define MULTIBOOT_INFO_VBE_INFO 0x00000800
|
||||||
|
#define MULTIBOOT_INFO_FRAMEBUFFER_INFO 0x00001000
|
||||||
|
|
||||||
|
#ifndef ASM_FILE
|
||||||
|
|
||||||
|
typedef unsigned char multiboot_uint8_t;
|
||||||
|
typedef unsigned short multiboot_uint16_t;
|
||||||
|
typedef unsigned int multiboot_uint32_t;
|
||||||
|
typedef unsigned long long multiboot_uint64_t;
|
||||||
|
|
||||||
|
struct multiboot_header
|
||||||
|
{
|
||||||
|
/* Must be MULTIBOOT_MAGIC - see above. */
|
||||||
|
multiboot_uint32_t magic;
|
||||||
|
|
||||||
|
/* Feature flags. */
|
||||||
|
multiboot_uint32_t flags;
|
||||||
|
|
||||||
|
/* The above fields plus this one must equal 0 mod 2^32. */
|
||||||
|
multiboot_uint32_t checksum;
|
||||||
|
|
||||||
|
/* These are only valid if MULTIBOOT_AOUT_KLUDGE is set. */
|
||||||
|
multiboot_uint32_t header_addr;
|
||||||
|
multiboot_uint32_t load_addr;
|
||||||
|
multiboot_uint32_t load_end_addr;
|
||||||
|
multiboot_uint32_t bss_end_addr;
|
||||||
|
multiboot_uint32_t entry_addr;
|
||||||
|
|
||||||
|
/* These are only valid if MULTIBOOT_VIDEO_MODE is set. */
|
||||||
|
multiboot_uint32_t mode_type;
|
||||||
|
multiboot_uint32_t width;
|
||||||
|
multiboot_uint32_t height;
|
||||||
|
multiboot_uint32_t depth;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* The symbol table for a.out. */
|
||||||
|
struct multiboot_aout_symbol_table
|
||||||
|
{
|
||||||
|
multiboot_uint32_t tabsize;
|
||||||
|
multiboot_uint32_t strsize;
|
||||||
|
multiboot_uint32_t addr;
|
||||||
|
multiboot_uint32_t reserved;
|
||||||
|
};
|
||||||
|
typedef struct multiboot_aout_symbol_table multiboot_aout_symbol_table_t;
|
||||||
|
|
||||||
|
/* The section header table for ELF. */
|
||||||
|
struct multiboot_elf_section_header_table
|
||||||
|
{
|
||||||
|
multiboot_uint32_t num;
|
||||||
|
multiboot_uint32_t size;
|
||||||
|
multiboot_uint32_t addr;
|
||||||
|
multiboot_uint32_t shndx;
|
||||||
|
};
|
||||||
|
typedef struct multiboot_elf_section_header_table multiboot_elf_section_header_table_t;
|
||||||
|
|
||||||
|
struct multiboot_info
|
||||||
|
{
|
||||||
|
/* Multiboot info version number */
|
||||||
|
multiboot_uint32_t flags;
|
||||||
|
|
||||||
|
/* Available memory from BIOS */
|
||||||
|
multiboot_uint32_t mem_lower;
|
||||||
|
multiboot_uint32_t mem_upper;
|
||||||
|
|
||||||
|
/* "root" partition */
|
||||||
|
multiboot_uint32_t boot_device;
|
||||||
|
|
||||||
|
/* Kernel command line */
|
||||||
|
multiboot_uint32_t cmdline;
|
||||||
|
|
||||||
|
/* Boot-Module list */
|
||||||
|
multiboot_uint32_t mods_count;
|
||||||
|
multiboot_uint32_t mods_addr;
|
||||||
|
|
||||||
|
union
|
||||||
|
{
|
||||||
|
multiboot_aout_symbol_table_t aout_sym;
|
||||||
|
multiboot_elf_section_header_table_t elf_sec;
|
||||||
|
} u;
|
||||||
|
|
||||||
|
/* Memory Mapping buffer */
|
||||||
|
multiboot_uint32_t mmap_length;
|
||||||
|
multiboot_uint32_t mmap_addr;
|
||||||
|
|
||||||
|
/* Drive Info buffer */
|
||||||
|
multiboot_uint32_t drives_length;
|
||||||
|
multiboot_uint32_t drives_addr;
|
||||||
|
|
||||||
|
/* ROM configuration table */
|
||||||
|
multiboot_uint32_t config_table;
|
||||||
|
|
||||||
|
/* Boot Loader Name */
|
||||||
|
multiboot_uint32_t boot_loader_name;
|
||||||
|
|
||||||
|
/* APM table */
|
||||||
|
multiboot_uint32_t apm_table;
|
||||||
|
|
||||||
|
/* Video */
|
||||||
|
multiboot_uint32_t vbe_control_info;
|
||||||
|
multiboot_uint32_t vbe_mode_info;
|
||||||
|
multiboot_uint16_t vbe_mode;
|
||||||
|
multiboot_uint16_t vbe_interface_seg;
|
||||||
|
multiboot_uint16_t vbe_interface_off;
|
||||||
|
multiboot_uint16_t vbe_interface_len;
|
||||||
|
|
||||||
|
multiboot_uint64_t framebuffer_addr;
|
||||||
|
multiboot_uint32_t framebuffer_pitch;
|
||||||
|
multiboot_uint32_t framebuffer_width;
|
||||||
|
multiboot_uint32_t framebuffer_height;
|
||||||
|
multiboot_uint8_t framebuffer_bpp;
|
||||||
|
#define MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED 0
|
||||||
|
#define MULTIBOOT_FRAMEBUFFER_TYPE_RGB 1
|
||||||
|
#define MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT 2
|
||||||
|
multiboot_uint8_t framebuffer_type;
|
||||||
|
union
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
multiboot_uint32_t framebuffer_palette_addr;
|
||||||
|
multiboot_uint16_t framebuffer_palette_num_colors;
|
||||||
|
};
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
multiboot_uint8_t framebuffer_red_field_position;
|
||||||
|
multiboot_uint8_t framebuffer_red_mask_size;
|
||||||
|
multiboot_uint8_t framebuffer_green_field_position;
|
||||||
|
multiboot_uint8_t framebuffer_green_mask_size;
|
||||||
|
multiboot_uint8_t framebuffer_blue_field_position;
|
||||||
|
multiboot_uint8_t framebuffer_blue_mask_size;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
typedef struct multiboot_info multiboot_info_t;
|
||||||
|
|
||||||
|
struct multiboot_color
|
||||||
|
{
|
||||||
|
multiboot_uint8_t red;
|
||||||
|
multiboot_uint8_t green;
|
||||||
|
multiboot_uint8_t blue;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct multiboot_mmap_entry
|
||||||
|
{
|
||||||
|
multiboot_uint32_t size;
|
||||||
|
multiboot_uint64_t addr;
|
||||||
|
multiboot_uint64_t len;
|
||||||
|
#define MULTIBOOT_MEMORY_AVAILABLE 1
|
||||||
|
#define MULTIBOOT_MEMORY_RESERVED 2
|
||||||
|
#define MULTIBOOT_MEMORY_ACPI_RECLAIMABLE 3
|
||||||
|
#define MULTIBOOT_MEMORY_NVS 4
|
||||||
|
#define MULTIBOOT_MEMORY_BADRAM 5
|
||||||
|
multiboot_uint32_t type;
|
||||||
|
} __attribute__((packed));
|
||||||
|
typedef struct multiboot_mmap_entry multiboot_memory_map_t;
|
||||||
|
|
||||||
|
struct multiboot_mod_list
|
||||||
|
{
|
||||||
|
/* the memory used goes from bytes 'mod_start' to 'mod_end-1' inclusive */
|
||||||
|
multiboot_uint32_t mod_start;
|
||||||
|
multiboot_uint32_t mod_end;
|
||||||
|
|
||||||
|
/* Module command line */
|
||||||
|
multiboot_uint32_t cmdline;
|
||||||
|
|
||||||
|
/* padding to take it to 16 bytes (must be zero) */
|
||||||
|
multiboot_uint32_t pad;
|
||||||
|
};
|
||||||
|
typedef struct multiboot_mod_list multiboot_module_t;
|
||||||
|
|
||||||
|
/* APM BIOS info. */
|
||||||
|
struct multiboot_apm_info
|
||||||
|
{
|
||||||
|
multiboot_uint16_t version;
|
||||||
|
multiboot_uint16_t cseg;
|
||||||
|
multiboot_uint32_t offset;
|
||||||
|
multiboot_uint16_t cseg_16;
|
||||||
|
multiboot_uint16_t dseg;
|
||||||
|
multiboot_uint16_t flags;
|
||||||
|
multiboot_uint16_t cseg_len;
|
||||||
|
multiboot_uint16_t cseg_16_len;
|
||||||
|
multiboot_uint16_t dseg_len;
|
||||||
|
};
|
||||||
|
struct MODE_INFO
|
||||||
|
{
|
||||||
|
unsigned short ModeAttributes ;
|
||||||
|
unsigned char WinAAttributes ;
|
||||||
|
unsigned char WinBAttributes ;
|
||||||
|
unsigned short WinGranularity ;
|
||||||
|
unsigned short WinSize ;
|
||||||
|
unsigned short WinASegment ;
|
||||||
|
unsigned short WinBSegment ;
|
||||||
|
unsigned int WinFuncPtr ;
|
||||||
|
unsigned short BytesPerScanLine ;
|
||||||
|
unsigned short XResolution ;
|
||||||
|
unsigned short YResolution ;
|
||||||
|
unsigned char XCharSize ;
|
||||||
|
unsigned char YCharSize ;
|
||||||
|
unsigned char NumberOfPlanes ;
|
||||||
|
unsigned char BitsPerPixel ;
|
||||||
|
unsigned char NumberOfBanks ;
|
||||||
|
unsigned char MemoryModel ;
|
||||||
|
unsigned char BankSize ;
|
||||||
|
unsigned char NumberOfImagePages ;
|
||||||
|
unsigned char Reserved_page ;
|
||||||
|
unsigned char RedMaskSize ;
|
||||||
|
unsigned char RedMaskPos ;
|
||||||
|
unsigned char GreenMaskSize ;
|
||||||
|
unsigned char GreenMaskPos ;
|
||||||
|
unsigned char BlueMaskSize ;
|
||||||
|
unsigned char BlueMaskPos ;
|
||||||
|
unsigned char ReservedMaskSize ;
|
||||||
|
unsigned char ReservedMaskPos ;
|
||||||
|
unsigned char DirectColorModeInfo ;
|
||||||
|
unsigned int PhysBasePtr ;
|
||||||
|
unsigned int OffScreenMemOffset ;
|
||||||
|
unsigned short OffScreenMemSize ;
|
||||||
|
unsigned char Reserved[206] ;
|
||||||
|
}__attribute__ ((packed));
|
||||||
|
#endif /* ! ASM_FILE */
|
||||||
|
|
||||||
|
#endif /* ! MULTIBOOT_HEADER */
|
169
prototypes/video/include/multiboot.hpp
Normal file
169
prototypes/video/include/multiboot.hpp
Normal file
|
@ -0,0 +1,169 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include "pointer.hpp"
|
||||||
|
|
||||||
|
#define MB_MEMSIZE (1<<0)
|
||||||
|
#define MB_BOOTDEVICE (1<<1)
|
||||||
|
#define MB_COMMANDLINE (1<<2)
|
||||||
|
#define MB_MODULES (1<<3)
|
||||||
|
#define MB_SYMS_AOUT (1<<4)
|
||||||
|
#define MB_SYMS_ELF (1<<5)
|
||||||
|
#define MB_MEMORYMAP (1<<6)
|
||||||
|
#define MB_DRIVES (1<<7)
|
||||||
|
#define MB_CONFIG_TABLE (1<<8)
|
||||||
|
#define MB_BOOTLOADER_NAME (1<<9)
|
||||||
|
#define MB_APS_TABLE (1<<10)
|
||||||
|
#define MB_VBE (1<<11)
|
||||||
|
|
||||||
|
#define MB_ASSERT_SIZE(type, len) static_assert(sizeof(type) == len, "multiboot::" #type " must be " #len " bytes large.")
|
||||||
|
|
||||||
|
namespace multiboot
|
||||||
|
{
|
||||||
|
template<typename T>
|
||||||
|
class mbarray
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
const uint32_t length;
|
||||||
|
private:
|
||||||
|
T *data;
|
||||||
|
|
||||||
|
mbarray() = delete;
|
||||||
|
public:
|
||||||
|
T const & operator [](size_t idx) const {
|
||||||
|
return this->data[idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
const T *begin() const {
|
||||||
|
return &data[0];
|
||||||
|
}
|
||||||
|
const T *end() const {
|
||||||
|
return &data[length];
|
||||||
|
}
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
// Make sure the size is not dependend on the template parameter
|
||||||
|
MB_ASSERT_SIZE(mbarray<uint8_t>, 8);
|
||||||
|
MB_ASSERT_SIZE(mbarray<uint32_t>, 8);
|
||||||
|
|
||||||
|
struct MemoryMap
|
||||||
|
{
|
||||||
|
uint32_t entry_size;
|
||||||
|
uint64_t base;
|
||||||
|
uint64_t length;
|
||||||
|
uint32_t type;
|
||||||
|
|
||||||
|
|
||||||
|
bool isFree() const {
|
||||||
|
return this->type == 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
MB_ASSERT_SIZE(MemoryMap, 24);
|
||||||
|
|
||||||
|
struct Module
|
||||||
|
{
|
||||||
|
physical_t start;
|
||||||
|
physical_t end;
|
||||||
|
const char * name;
|
||||||
|
uint32_t reserved;
|
||||||
|
|
||||||
|
uint32_t size() const {
|
||||||
|
return this->end.numeric() - this->start.numeric();
|
||||||
|
}
|
||||||
|
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
MB_ASSERT_SIZE(Module, 16);
|
||||||
|
|
||||||
|
struct Drive
|
||||||
|
{
|
||||||
|
uint32_t size;
|
||||||
|
uint8_t number;
|
||||||
|
uint8_t mode;
|
||||||
|
uint16_t cylinders;
|
||||||
|
uint8_t heads;
|
||||||
|
uint8_t sectors;
|
||||||
|
|
||||||
|
// 0x10 size-0x10 drive_ports I/O-Ports, die von diesem Gerät benutzt werden
|
||||||
|
// uint16_t ports[0];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the number of ports used by this drive.
|
||||||
|
*/
|
||||||
|
uint32_t portCount() const {
|
||||||
|
return (this->size - 0x10) / sizeof(uint16_t);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the given port.
|
||||||
|
* @return The port #idx or 0 if out of range.
|
||||||
|
*/
|
||||||
|
uint16_t port(size_t idx) const {
|
||||||
|
uint16_t const * ports = reinterpret_cast<uint16_t const *>(reinterpret_cast<uint8_t const *>(this) + 0x10);
|
||||||
|
if(idx >= this->portCount()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return ports[idx];
|
||||||
|
}
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
static_assert(sizeof(Drive) >= 10, "multiboot::Drive must be at least 12 bytes large.");
|
||||||
|
|
||||||
|
struct APMTable
|
||||||
|
{
|
||||||
|
uint16_t version;
|
||||||
|
uint16_t cseg;
|
||||||
|
uint32_t offset;
|
||||||
|
uint16_t cseg_16;
|
||||||
|
uint16_t dseg;
|
||||||
|
uint16_t flags;
|
||||||
|
uint16_t cseg_len;
|
||||||
|
uint16_t cseg_16_len;
|
||||||
|
uint16_t dseg_len;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
MB_ASSERT_SIZE(APMTable, 20);
|
||||||
|
|
||||||
|
struct Structure
|
||||||
|
{
|
||||||
|
uint32_t flags;
|
||||||
|
physical_t memLower;
|
||||||
|
physical_t memUpper;
|
||||||
|
uint32_t bootDevice;
|
||||||
|
const char * commandline;
|
||||||
|
mbarray<Module> modules;
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
uint32_t tabsize;
|
||||||
|
uint32_t strsize;
|
||||||
|
uint32_t addr;
|
||||||
|
uint32_t reserved;
|
||||||
|
} __attribute__((packed)) symsAssemblerOut;
|
||||||
|
struct {
|
||||||
|
uint32_t num;
|
||||||
|
uint32_t size;
|
||||||
|
uintptr_t addr;
|
||||||
|
uintptr_t shndx;
|
||||||
|
} __attribute__((packed)) symsELF;
|
||||||
|
};
|
||||||
|
mbarray<MemoryMap> memoryMaps;
|
||||||
|
mbarray<Drive> drives;
|
||||||
|
physical_t configTable;
|
||||||
|
const char * bootLoaderName;
|
||||||
|
const APMTable * apmTable;
|
||||||
|
struct {
|
||||||
|
uint32_t controlInfo;
|
||||||
|
uint32_t modeInfo;
|
||||||
|
uint16_t mode;
|
||||||
|
uint16_t interfaceSegment;
|
||||||
|
uint16_t interfaceOffset;
|
||||||
|
uint16_t interfaceLength;
|
||||||
|
} __attribute__((packed)) vbe;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
// MB_ASSERT_SIZE(Structure, 88);
|
||||||
|
|
||||||
|
}
|
116
prototypes/video/include/pointer.hpp
Normal file
116
prototypes/video/include/pointer.hpp
Normal file
|
@ -0,0 +1,116 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides a strong pointer wrapper which can be used to address
|
||||||
|
* different memory types (physical, virtual, ...) and preventing
|
||||||
|
* a wrong assignment.
|
||||||
|
* @remarks The pointer size is fixed to 32 bits.
|
||||||
|
*/
|
||||||
|
template<typename TIdent>
|
||||||
|
class pointer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* A value that declares the pointer invalid.
|
||||||
|
*/
|
||||||
|
static pointer invalid;
|
||||||
|
private:
|
||||||
|
uint32_t ptr;
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Creates the pointer by giving a raw pointer.
|
||||||
|
*/
|
||||||
|
explicit pointer(void *ptr) :
|
||||||
|
ptr(reinterpret_cast<uint32_t>(ptr))
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the pointer by giving an integer value.
|
||||||
|
*/
|
||||||
|
explicit pointer(uint32_t value) :
|
||||||
|
ptr(value)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
pointer(const pointer &) = default;
|
||||||
|
pointer(pointer &&) = default;
|
||||||
|
~pointer() = default;
|
||||||
|
|
||||||
|
pointer & operator = (const pointer & other) {
|
||||||
|
this->ptr = other.ptr;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the numeric integer value of the pointer.
|
||||||
|
*/
|
||||||
|
uint32_t numeric() const {
|
||||||
|
return this->ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the pointer as a raw pointer.
|
||||||
|
*/
|
||||||
|
void * data() const {
|
||||||
|
return reinterpret_cast<void*>(this->ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the pointer as a raw typed pointer.
|
||||||
|
*/
|
||||||
|
template<typename T>
|
||||||
|
T * data () const {
|
||||||
|
return reinterpret_cast<T*>(this->ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allow explicit conversion to a raw pointer.
|
||||||
|
*/
|
||||||
|
explicit operator void * () const {
|
||||||
|
return this->data();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an aligned version of the pointer.
|
||||||
|
* Rounds the pointer to the memory bottom.
|
||||||
|
*/
|
||||||
|
pointer alignLower(uint32_t alignment) {
|
||||||
|
if(alignment == 0) return pointer::invalid;
|
||||||
|
return pointer(this->ptr & ~(alignment - 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an aligned version of the pointer.
|
||||||
|
* Rounds the pointer to the memory top.
|
||||||
|
*/
|
||||||
|
pointer alignUpper(uint32_t alignment) {
|
||||||
|
if(alignment == 0) return pointer::invalid;
|
||||||
|
return pointer((this->ptr + (alignment - 1)) & ~(alignment - 1));
|
||||||
|
}
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
pointer<T> pointer<T>::invalid(uint32_t(0xFFFFFFFF));
|
||||||
|
|
||||||
|
struct physical_t_ident;
|
||||||
|
struct virtual_t_ident;
|
||||||
|
|
||||||
|
// Add different memory pointer types here....
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A pointer pointing to physical memory.
|
||||||
|
*/
|
||||||
|
using physical_t = pointer<physical_t_ident>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A pointer pointing to virtual memory.
|
||||||
|
*/
|
||||||
|
using virtual_t = pointer<virtual_t_ident>;
|
||||||
|
|
||||||
|
|
||||||
|
static_assert(sizeof(physical_t) == 4, "pointer is not 4 byte wide.");
|
84
prototypes/video/init.cpp
Normal file
84
prototypes/video/init.cpp
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
#include <inttypes.h>
|
||||||
|
|
||||||
|
#include "multiboot.h"
|
||||||
|
|
||||||
|
#include "../base/include/io.hpp"
|
||||||
|
|
||||||
|
struct dummy;
|
||||||
|
|
||||||
|
// Symbols generated by linker, no useful content in there...
|
||||||
|
extern dummy kernelStartMarker;
|
||||||
|
extern dummy kernelEndMarker;
|
||||||
|
|
||||||
|
uint16_t * video = (uint16_t*)0xB8000;
|
||||||
|
|
||||||
|
// Prüft, ob man bereits schreiben kann
|
||||||
|
static uint8_t is_transmit_empty(uint16_t base) {
|
||||||
|
return inb(base+5) & 0x20;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Byte senden
|
||||||
|
static void write_com(uint16_t base, uint8_t chr) {
|
||||||
|
while (is_transmit_empty(base)==0);
|
||||||
|
outb(base,chr);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define VBE_FAR(name) uint32_t name;
|
||||||
|
|
||||||
|
struct ModeInfoBlock {
|
||||||
|
uint16_t attributes;
|
||||||
|
uint8_t winA,winB;
|
||||||
|
uint16_t granularity;
|
||||||
|
uint16_t winsize;
|
||||||
|
uint16_t segmentA, segmentB;
|
||||||
|
VBE_FAR(realFctPtr);
|
||||||
|
uint16_t pitch; // bytes per scanline
|
||||||
|
|
||||||
|
uint16_t Xres, Yres;
|
||||||
|
uint8_t Wchar, Ychar, planes, bpp, banks;
|
||||||
|
uint8_t memory_model, bank_size, image_pages;
|
||||||
|
uint8_t reserved0;
|
||||||
|
|
||||||
|
uint8_t red_mask, red_position;
|
||||||
|
uint8_t green_mask, green_position;
|
||||||
|
uint8_t blue_mask, blue_position;
|
||||||
|
uint8_t rsv_mask, rsv_position;
|
||||||
|
uint8_t directcolor_attributes;
|
||||||
|
|
||||||
|
uint32_t physbase; // your LFB (Linear Framebuffer) address ;)
|
||||||
|
uint32_t reserved1;
|
||||||
|
uint16_t reserved2;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
extern "C" void init(multiboot_info_t const & data)
|
||||||
|
{
|
||||||
|
const char *msg = "You should not see this.";
|
||||||
|
while(*msg)
|
||||||
|
{
|
||||||
|
*(video++) = *msg++ | 0x0700;
|
||||||
|
}
|
||||||
|
|
||||||
|
ModeInfoBlock *modeInfo = (ModeInfoBlock*)data.vbe_mode_info;
|
||||||
|
|
||||||
|
uint8_t *fb = (uint8_t*)modeInfo->physbase;
|
||||||
|
|
||||||
|
for(int y = 0; y < modeInfo->Yres; y++)
|
||||||
|
{
|
||||||
|
for(int x = 0; x < modeInfo->Xres; x++)
|
||||||
|
{
|
||||||
|
uint32_t r = (x * 384 / modeInfo->Xres);
|
||||||
|
uint32_t g = (y * 384 / modeInfo->Yres);
|
||||||
|
uint32_t b = 0x00;
|
||||||
|
|
||||||
|
fb[modeInfo->pitch * y + 4 * x + 2] = r;
|
||||||
|
fb[modeInfo->pitch * y + 4 * x + 1] = g;
|
||||||
|
fb[modeInfo->pitch * y + 4 * x + 0] = b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
write_com(0x3F8, 'H');
|
||||||
|
write_com(0x3F8, 'i');
|
||||||
|
write_com(0x3F8, '\n');
|
||||||
|
|
||||||
|
while(true);
|
||||||
|
}
|
37
prototypes/video/linker.ld
Normal file
37
prototypes/video/linker.ld
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
ENTRY(_start)
|
||||||
|
OUTPUT_FORMAT(elf32-i386)
|
||||||
|
OUTPUT_ARCH(i386:i386)
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
. = 0x100000;
|
||||||
|
|
||||||
|
kernelStartMarker = .;
|
||||||
|
|
||||||
|
.text : {
|
||||||
|
*(multiboot)
|
||||||
|
*(.text)
|
||||||
|
}
|
||||||
|
.data ALIGN(4096) : {
|
||||||
|
start_ctors = .;
|
||||||
|
KEEP(*( .init_array ));
|
||||||
|
KEEP(*(SORT_BY_INIT_PRIORITY( .init_array.* )));
|
||||||
|
end_ctors = .;
|
||||||
|
|
||||||
|
start_dtors = .;
|
||||||
|
KEEP(*( .fini_array ));
|
||||||
|
end_dtors = .;
|
||||||
|
|
||||||
|
*(.data)
|
||||||
|
}
|
||||||
|
.rodata ALIGN(4096) : {
|
||||||
|
*(.rodata)
|
||||||
|
}
|
||||||
|
.bss ALIGN(4096) : {
|
||||||
|
*(.bss)
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Align the end of the kernel to the page size */
|
||||||
|
. = ALIGN(4096);
|
||||||
|
kernelEndMarker = .;
|
||||||
|
}
|
28
prototypes/video/multiboot.S
Normal file
28
prototypes/video/multiboot.S
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
.section multiboot
|
||||||
|
|
||||||
|
#define MB_MAGIC 0x1badb002
|
||||||
|
#define MB_FLAGS 0x07
|
||||||
|
#define MB_CHECKSUM -(MB_MAGIC + MB_FLAGS)
|
||||||
|
|
||||||
|
.align 4
|
||||||
|
|
||||||
|
// Offset Type Field Name Note
|
||||||
|
// 0 u32 magic required
|
||||||
|
// 4 u32 flags required
|
||||||
|
// 8 u32 checksum required
|
||||||
|
.int MB_MAGIC
|
||||||
|
.int MB_FLAGS
|
||||||
|
.int MB_CHECKSUM
|
||||||
|
|
||||||
|
// 12 u32 header_addr if flags[16] is set
|
||||||
|
// 16 u32 load_addr if flags[16] is set
|
||||||
|
// 20 u32 load_end_addr if flags[16] is set
|
||||||
|
// 24 u32 bss_end_addr if flags[16] is set
|
||||||
|
// 28 u32 entry_addr if flags[16] is set
|
||||||
|
.int 0, 0, 0, 0, 0
|
||||||
|
|
||||||
|
// 32 u32 mode_type if flags[2] is set
|
||||||
|
// 36 u32 width if flags[2] is set
|
||||||
|
// 40 u32 height if flags[2] is set
|
||||||
|
// 44 u32 depth if flags[2] is set
|
||||||
|
.int 0, 640, 480, 32
|
6
prototypes/video/syslinux.cfg
Normal file
6
prototypes/video/syslinux.cfg
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
DEFAULT video
|
||||||
|
|
||||||
|
LABEL video
|
||||||
|
SAY Now booting video demo.
|
||||||
|
KERNEL mboot.c32
|
||||||
|
APPEND video.ker
|
Loading…
Reference in a new issue