feat: add given files
Signed-off-by: Julien CLEMENT <julien.clement@epita.fr>
This commit is contained in:
commit
7178dbb6a7
151 files changed
+13845
No files matched your search
+51
@@ -0,0 +1,51 @@
|
||||
#
|
||||
# Copyright (c) LSE
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY LSE AS IS AND ANY
|
||||
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL LSE BE LIABLE FOR ANY
|
||||
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
include ../config.mk
|
||||
|
||||
TARGET = k
|
||||
OBJS = \
|
||||
crt0.o \
|
||||
k.o \
|
||||
libvga.o \
|
||||
list.o \
|
||||
memory.o \
|
||||
|
||||
|
||||
DEPS = $(OBJS:.o=.d)
|
||||
|
||||
all: $(TARGET)
|
||||
|
||||
$(TARGET): CPPFLAGS += -MMD -Iinclude -I ../libs/libc/include/
|
||||
$(TARGET): CFLAGS += $(K_EXTRA_CFLAGS)
|
||||
$(TARGET): LDFLAGS += -Wl,-Tk.lds
|
||||
$(TARGET): LDLIBS = -L../libs/libc -lc
|
||||
$(TARGET): $(OBJS)
|
||||
|
||||
install: $(TARGET)
|
||||
$(INSTALL) $(TARGET) $(INSTALL_ROOT)/$(TARGET)
|
||||
|
||||
clean:
|
||||
$(RM) $(OBJS) $(DEPS) $(TARGET)
|
||||
|
||||
-include $(DEPS)
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (c) LSE
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY LSE AS IS AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL LSE BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "multiboot.h"
|
||||
|
||||
#define HEADER_FLAGS (MULTIBOOT_PAGE_ALIGN | MULTIBOOT_MEMORY_INFO)
|
||||
#define STACK_SIZE 8192
|
||||
|
||||
.section .multiboot
|
||||
.type multiboot_header, @object
|
||||
multiboot_header:
|
||||
.align MULTIBOOT_HEADER_ALIGN
|
||||
.long MULTIBOOT_HEADER_MAGIC
|
||||
.long HEADER_FLAGS
|
||||
.long -(MULTIBOOT_HEADER_MAGIC + HEADER_FLAGS)
|
||||
.size multiboot_header, . - multiboot_header
|
||||
|
||||
.section .text
|
||||
.global k_entry
|
||||
.type k_entry, @function
|
||||
k_entry:
|
||||
lea end_stack, %esp
|
||||
push %ebx /* multiboot info */
|
||||
push %eax /* magic */
|
||||
call k_main /* kernel entry point */
|
||||
.Lend:
|
||||
jmp .Lend
|
||||
.size k_entry, . - k_entry
|
||||
|
||||
.section .bss
|
||||
stack:
|
||||
.space STACK_SIZE
|
||||
.align 16
|
||||
end_stack:
|
||||
.global end_stack
|
||||
@@ -0,0 +1,672 @@
|
||||
/* $NetBSD: exec_elf.h,v 1.60 2002/01/28 22:15:54 thorpej Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1994 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Christos Zoulas.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the NetBSD
|
||||
* Foundation, Inc. and its contributors.
|
||||
* 4. Neither the name of The NetBSD Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef _SYS_EXEC_ELF_H_
|
||||
#define _SYS_EXEC_ELF_H_
|
||||
|
||||
/*
|
||||
* The current ELF ABI specification is available at:
|
||||
* http://www.sco.com/developer/gabi/
|
||||
*
|
||||
* Current header definitions are in:
|
||||
* http://www.sco.com/developer/gabi/latest/ch4.eheader.html
|
||||
*/
|
||||
|
||||
#define ELF32_MACHDEP_ENDIANNESS ELFDATA2LSB
|
||||
#define ELF32_MACHDEP_ID_CASES \
|
||||
case EM_386: \
|
||||
case EM_486: \
|
||||
break;
|
||||
|
||||
#define ELF32_MACHDEP_ID EM_386
|
||||
|
||||
#define ARCH_ELFSIZE 32 /* MD native binary size */
|
||||
|
||||
/* i386 relocations */
|
||||
#define R_386_NONE 0
|
||||
#define R_386_32 1
|
||||
#define R_386_PC32 2
|
||||
#define R_386_GOT32 3
|
||||
#define R_386_PLT32 4
|
||||
#define R_386_COPY 5
|
||||
#define R_386_GLOB_DAT 6
|
||||
#define R_386_JMP_SLOT 7
|
||||
#define R_386_RELATIVE 8
|
||||
#define R_386_GOTOFF 9
|
||||
#define R_386_GOTPC 10
|
||||
/* The following relocations are GNU extensions. */
|
||||
#define R_386_16 20
|
||||
#define R_386_PC16 21
|
||||
#define R_386_8 22
|
||||
#define R_386_PC8 23
|
||||
|
||||
#define R_TYPE(name) __CONCAT(R_386_,name)
|
||||
|
||||
typedef u8 Elf_Byte;
|
||||
|
||||
typedef u32 Elf32_Addr;
|
||||
#define ELF32_FSZ_ADDR 4
|
||||
typedef u32 Elf32_Off;
|
||||
#define ELF32_FSZ_OFF 4
|
||||
typedef s32 Elf32_Sword;
|
||||
#define ELF32_FSZ_SWORD 4
|
||||
typedef u32 Elf32_Word;
|
||||
#define ELF32_FSZ_WORD 4
|
||||
typedef u16 Elf32_Half;
|
||||
#define ELF32_FSZ_HALF 2
|
||||
|
||||
/*
|
||||
* ELF Header
|
||||
*/
|
||||
#define ELF_NIDENT 16
|
||||
|
||||
typedef struct {
|
||||
unsigned char e_ident[ELF_NIDENT]; /* Id bytes */
|
||||
Elf32_Half e_type; /* file type */
|
||||
Elf32_Half e_machine; /* machine type */
|
||||
Elf32_Word e_version; /* version number */
|
||||
Elf32_Addr e_entry; /* entry point */
|
||||
Elf32_Off e_phoff; /* Program hdr offset */
|
||||
Elf32_Off e_shoff; /* Section hdr offset */
|
||||
Elf32_Word e_flags; /* Processor flags */
|
||||
Elf32_Half e_ehsize; /* sizeof ehdr */
|
||||
Elf32_Half e_phentsize; /* Program header entry size */
|
||||
Elf32_Half e_phnum; /* Number of program headers */
|
||||
Elf32_Half e_shentsize; /* Section header entry size */
|
||||
Elf32_Half e_shnum; /* Number of section headers */
|
||||
Elf32_Half e_shstrndx; /* String table index */
|
||||
} Elf32_Ehdr;
|
||||
|
||||
/* e_ident offsets */
|
||||
#define EI_MAG0 0 /* '\177' */
|
||||
#define EI_MAG1 1 /* 'E' */
|
||||
#define EI_MAG2 2 /* 'L' */
|
||||
#define EI_MAG3 3 /* 'F' */
|
||||
#define EI_CLASS 4 /* File class */
|
||||
#define EI_DATA 5 /* Data encoding */
|
||||
#define EI_VERSION 6 /* File version */
|
||||
#define EI_OSABI 7 /* Operating system/ABI identification */
|
||||
#define EI_ABIVERSION 8 /* ABI version */
|
||||
#define EI_PAD 9 /* Start of padding bytes up to EI_NIDENT */
|
||||
|
||||
/* e_ident[ELFMAG0,ELFMAG3] */
|
||||
#define ELFMAG0 0x7f
|
||||
#define ELFMAG1 'E'
|
||||
#define ELFMAG2 'L'
|
||||
#define ELFMAG3 'F'
|
||||
#define ELFMAG "\177ELF"
|
||||
#define SELFMAG 4
|
||||
|
||||
/* e_ident[EI_CLASS] */
|
||||
#define ELFCLASSNONE 0 /* Invalid class */
|
||||
#define ELFCLASS32 1 /* 32-bit objects */
|
||||
#define ELFCLASS64 2 /* 64-bit objects */
|
||||
#define ELFCLASSNUM 3
|
||||
|
||||
/* e_ident[EI_DATA] */
|
||||
#define ELFDATANONE 0 /* Invalid data encoding */
|
||||
#define ELFDATA2LSB 1 /* 2's complement values, LSB first */
|
||||
#define ELFDATA2MSB 2 /* 2's complement values, MSB first */
|
||||
|
||||
/* e_ident[EI_VERSION] */
|
||||
#define EV_NONE 0 /* Invalid version */
|
||||
#define EV_CURRENT 1 /* Current version */
|
||||
#define EV_NUM 2
|
||||
|
||||
/* e_ident[EI_OSABI] */
|
||||
#define ELFOSABI_SYSV 0 /* UNIX System V ABI */
|
||||
#define ELFOSABI_HPUX 1 /* HP-UX operating system */
|
||||
#define ELFOSABI_NETBSD 2 /* NetBSD */
|
||||
#define ELFOSABI_LINUX 3 /* GNU/Linux */
|
||||
#define ELFOSABI_HURD 4 /* GNU/Hurd */
|
||||
#define ELFOSABI_86OPEN 5 /* 86Open */
|
||||
#define ELFOSABI_SOLARIS 6 /* Solaris */
|
||||
#define ELFOSABI_MONTEREY 7 /* Monterey */
|
||||
#define ELFOSABI_IRIX 8 /* IRIX */
|
||||
#define ELFOSABI_FREEBSD 9 /* FreeBSD */
|
||||
#define ELFOSABI_TRU64 10 /* TRU64 UNIX */
|
||||
#define ELFOSABI_MODESTO 11 /* Novell Modesto */
|
||||
#define ELFOSABI_OPENBSD 12 /* OpenBSD */
|
||||
/* Unofficial OSABIs follow */
|
||||
#define ELFOSABI_ARM 97 /* ARM */
|
||||
#define ELFOSABI_STANDALONE 255 /* Standalone (embedded) application */
|
||||
|
||||
/* e_type */
|
||||
#define ET_NONE 0 /* No file type */
|
||||
#define ET_REL 1 /* Relocatable file */
|
||||
#define ET_EXEC 2 /* Executable file */
|
||||
#define ET_DYN 3 /* Shared object file */
|
||||
#define ET_CORE 4 /* Core file */
|
||||
#define ET_NUM 5
|
||||
|
||||
#define ET_LOOS 0xfe00 /* Operating system specific range */
|
||||
#define ET_HIOS 0xfeff
|
||||
#define ET_LOPROC 0xff00 /* Processor-specific range */
|
||||
#define ET_HIPROC 0xffff
|
||||
|
||||
/* e_machine */
|
||||
#define EM_NONE 0 /* No machine */
|
||||
#define EM_M32 1 /* AT&T WE 32100 */
|
||||
#define EM_SPARC 2 /* SPARC */
|
||||
#define EM_386 3 /* Intel 80386 */
|
||||
#define EM_68K 4 /* Motorola 68000 */
|
||||
#define EM_88K 5 /* Motorola 88000 */
|
||||
#define EM_486 6 /* Intel 80486 */
|
||||
#define EM_860 7 /* Intel 80860 */
|
||||
#define EM_MIPS 8 /* MIPS I Architecture */
|
||||
#define EM_S370 9 /* Amdahl UTS on System/370 */
|
||||
#define EM_MIPS_RS3_LE 10 /* MIPS RS3000 Little-endian */
|
||||
/* 11-14 - Reserved */
|
||||
#define EM_RS6000 11 /* IBM RS/6000 XXX reserved */
|
||||
#define EM_PARISC 15 /* Hewlett-Packard PA-RISC */
|
||||
#define EM_NCUBE 16 /* NCube XXX reserved */
|
||||
#define EM_VPP500 17 /* Fujitsu VPP500 */
|
||||
#define EM_SPARC32PLUS 18 /* Enhanced instruction set SPARC */
|
||||
#define EM_960 19 /* Intel 80960 */
|
||||
#define EM_PPC 20 /* PowerPC */
|
||||
#define EM_PPC64 21 /* 64-bit PowerPC */
|
||||
/* 22-35 - Reserved */
|
||||
#define EM_V800 36 /* NEC V800 */
|
||||
#define EM_FR20 37 /* Fujitsu FR20 */
|
||||
#define EM_RH32 38 /* TRW RH-32 */
|
||||
#define EM_RCE 39 /* Motorola RCE */
|
||||
#define EM_ARM 40 /* Advanced RISC Machines ARM */
|
||||
#define EM_ALPHA 41 /* DIGITAL Alpha */
|
||||
#define EM_SH 42 /* Hitachi Super-H */
|
||||
#define EM_SPARCV9 43 /* SPARC Version 9 */
|
||||
#define EM_TRICORE 44 /* Siemens Tricore */
|
||||
#define EM_ARC 45 /* Argonaut RISC Core */
|
||||
#define EM_H8_300 46 /* Hitachi H8/300 */
|
||||
#define EM_H8_300H 47 /* Hitachi H8/300H */
|
||||
#define EM_H8S 48 /* Hitachi H8S */
|
||||
#define EM_H8_500 49 /* Hitachi H8/500 */
|
||||
#define EM_IA_64 50 /* Intel Merced Processor */
|
||||
#define EM_MIPS_X 51 /* Stanford MIPS-X */
|
||||
#define EM_COLDFIRE 52 /* Motorola Coldfire */
|
||||
#define EM_68HC12 53 /* Motorola MC68HC12 */
|
||||
#define EM_MMA 54 /* Fujitsu MMA Multimedia Accelerator */
|
||||
#define EM_PCP 55 /* Siemens PCP */
|
||||
#define EM_NCPU 56 /* Sony nCPU embedded RISC processor */
|
||||
#define EM_NDR1 57 /* Denso NDR1 microprocessor */
|
||||
#define EM_STARCORE 58 /* Motorola Star*Core processor */
|
||||
#define EM_ME16 59 /* Toyota ME16 processor */
|
||||
#define EM_ST100 60 /* STMicroelectronics ST100 processor */
|
||||
#define EM_TINYJ 61 /* Advanced Logic Corp. TinyJ embedded family processor */
|
||||
#define EM_X86_64 62 /* AMD x86-64 architecture */
|
||||
#define EM_PDSP 63 /* Sony DSP Processor */
|
||||
/* 64-65 - Reserved */
|
||||
#define EM_FX66 66 /* Siemens FX66 microcontroller */
|
||||
#define EM_ST9PLUS 67 /* STMicroelectronics ST9+ 8/16 bit microcontroller */
|
||||
#define EM_ST7 68 /* STMicroelectronics ST7 8-bit microcontroller */
|
||||
#define EM_68HC16 69 /* Motorola MC68HC16 Microcontroller */
|
||||
#define EM_68HC11 70 /* Motorola MC68HC11 Microcontroller */
|
||||
#define EM_68HC08 71 /* Motorola MC68HC08 Microcontroller */
|
||||
#define EM_68HC05 72 /* Motorola MC68HC05 Microcontroller */
|
||||
#define EM_SVX 73 /* Silicon Graphics SVx */
|
||||
#define EM_ST19 74 /* STMicroelectronics ST19 8-bit cpu */
|
||||
#define EM_VAX 75 /* Digital VAX */
|
||||
#define EM_CRIS 76 /* Axis Communications 32-bit embedded processor */
|
||||
#define EM_JAVELIN 77 /* Infineon Technologies 32-bit embedded cpu */
|
||||
#define EM_FIREPATH 78 /* Element 14 64-bit DSP processor */
|
||||
#define EM_ZSP 79 /* LSI Logic's 16-bit DSP processor */
|
||||
#define EM_MMIX 80 /* Donald Knuth's educational 64-bit processor */
|
||||
#define EM_HUANY 81 /* Harvard's machine-independent format */
|
||||
#define EM_PRISM 82 /* SiTera Prism */
|
||||
#define EM_AVR 83 /* Atmel AVR 8-bit microcontroller */
|
||||
#define EM_FR30 84 /* Fujitsu FR30 */
|
||||
#define EM_D10V 85 /* Mitsubishi D10V */
|
||||
#define EM_D30V 86 /* Mitsubishi D30V */
|
||||
#define EM_V850 87 /* NEC v850 */
|
||||
#define EM_M32R 88 /* Mitsubishi M32R */
|
||||
#define EM_MN10300 89 /* Matsushita MN10300 */
|
||||
#define EM_MN10200 90 /* Matsushita MN10200 */
|
||||
#define EM_PJ 91 /* picoJava */
|
||||
#define EM_OPENRISC 92 /* OpenRISC 32-bit embedded processor */
|
||||
#define EM_ARC_A5 93 /* ARC Cores Tangent-A5 */
|
||||
#define EM_XTENSA 94 /* Tensilica Xtensa Architecture */
|
||||
#define EM_NS32K 97 /* National Semiconductor 32000 series */
|
||||
|
||||
/* Unofficial machine types follow */
|
||||
#define EM_ALPHA_EXP 36902 /* used by NetBSD/alpha; obsolete */
|
||||
#define EM_NUM 36903
|
||||
|
||||
/*
|
||||
* Program Header
|
||||
*/
|
||||
typedef struct {
|
||||
Elf32_Word p_type; /* entry type */
|
||||
Elf32_Off p_offset; /* offset */
|
||||
Elf32_Addr p_vaddr; /* virtual address */
|
||||
Elf32_Addr p_paddr; /* physical address */
|
||||
Elf32_Word p_filesz; /* file size */
|
||||
Elf32_Word p_memsz; /* memory size */
|
||||
Elf32_Word p_flags; /* flags */
|
||||
Elf32_Word p_align; /* memory & file alignment */
|
||||
} Elf32_Phdr;
|
||||
|
||||
/* p_type */
|
||||
#define PT_NULL 0 /* Program header table entry unused */
|
||||
#define PT_LOAD 1 /* Loadable program segment */
|
||||
#define PT_DYNAMIC 2 /* Dynamic linking information */
|
||||
#define PT_INTERP 3 /* Program interpreter */
|
||||
#define PT_NOTE 4 /* Auxiliary information */
|
||||
#define PT_SHLIB 5 /* Reserved, unspecified semantics */
|
||||
#define PT_PHDR 6 /* Entry for header table itself */
|
||||
#define PT_NUM 7
|
||||
|
||||
/* p_flags */
|
||||
#define PF_R 0x4 /* Segment is readable */
|
||||
#define PF_W 0x2 /* Segment is writable */
|
||||
#define PF_X 0x1 /* Segment is executable */
|
||||
|
||||
#define PF_MASKOS 0x0ff00000 /* Opersting system specific values */
|
||||
#define PF_MASKPROC 0xf0000000 /* Processor-specific values */
|
||||
|
||||
#define PT_LOPROC 0x70000000 /* Processor-specific range */
|
||||
#define PT_HIPROC 0x7fffffff
|
||||
|
||||
#define PT_MIPS_REGINFO 0x70000000
|
||||
|
||||
/*
|
||||
* Section Headers
|
||||
*/
|
||||
typedef struct {
|
||||
Elf32_Word sh_name; /* section name (.shstrtab index) */
|
||||
Elf32_Word sh_type; /* section type */
|
||||
Elf32_Word sh_flags; /* section flags */
|
||||
Elf32_Addr sh_addr; /* virtual address */
|
||||
Elf32_Off sh_offset; /* file offset */
|
||||
Elf32_Word sh_size; /* section size */
|
||||
Elf32_Word sh_link; /* link to another */
|
||||
Elf32_Word sh_info; /* misc info */
|
||||
Elf32_Word sh_addralign; /* memory alignment */
|
||||
Elf32_Word sh_entsize; /* table entry size */
|
||||
} Elf32_Shdr;
|
||||
|
||||
/* sh_type */
|
||||
#define SHT_NULL 0 /* Section header table entry unused */
|
||||
#define SHT_PROGBITS 1 /* Program information */
|
||||
#define SHT_SYMTAB 2 /* Symbol table */
|
||||
#define SHT_STRTAB 3 /* String table */
|
||||
#define SHT_RELA 4 /* Relocation information w/ addend */
|
||||
#define SHT_HASH 5 /* Symbol hash table */
|
||||
#define SHT_DYNAMIC 6 /* Dynamic linking information */
|
||||
#define SHT_NOTE 7 /* Auxiliary information */
|
||||
#define SHT_NOBITS 8 /* No space allocated in file image */
|
||||
#define SHT_REL 9 /* Relocation information w/o addend */
|
||||
#define SHT_SHLIB 10 /* Reserved, unspecified semantics */
|
||||
#define SHT_DYNSYM 11 /* Symbol table for dynamic linker */
|
||||
#define SHT_NUM 12
|
||||
|
||||
#define SHT_LOOS 0x60000000 /* Operating system specific range */
|
||||
#define SHT_HIOS 0x6fffffff
|
||||
#define SHT_LOPROC 0x70000000 /* Processor-specific range */
|
||||
#define SHT_HIPROC 0x7fffffff
|
||||
#define SHT_LOUSER 0x80000000 /* Application-specific range */
|
||||
#define SHT_HIUSER 0xffffffff
|
||||
|
||||
/* sh_flags */
|
||||
#define SHF_WRITE 0x1 /* Section contains writable data */
|
||||
#define SHF_ALLOC 0x2 /* Section occupies memory */
|
||||
#define SHF_EXECINSTR 0x4 /* Section contains executable insns */
|
||||
|
||||
#define SHF_MASKOS 0x0f000000 /* Operating system specific values */
|
||||
#define SHF_MASKPROC 0xf0000000 /* Processor-specific values */
|
||||
|
||||
/*
|
||||
* Symbol Table
|
||||
*/
|
||||
typedef struct {
|
||||
Elf32_Word st_name; /* Symbol name (.symtab index) */
|
||||
Elf32_Word st_value; /* value of symbol */
|
||||
Elf32_Word st_size; /* size of symbol */
|
||||
Elf_Byte st_info; /* type / binding attrs */
|
||||
Elf_Byte st_other; /* unused */
|
||||
Elf32_Half st_shndx; /* section index of symbol */
|
||||
} Elf32_Sym;
|
||||
|
||||
/* Symbol Table index of the undefined symbol */
|
||||
#define ELF_SYM_UNDEFINED 0
|
||||
|
||||
/* st_info: Symbol Bindings */
|
||||
#define STB_LOCAL 0 /* local symbol */
|
||||
#define STB_GLOBAL 1 /* global symbol */
|
||||
#define STB_WEAK 2 /* weakly defined global symbol */
|
||||
#define STB_NUM 3
|
||||
|
||||
#define STB_LOOS 10 /* Operating system specific range */
|
||||
#define STB_HIOS 12
|
||||
#define STB_LOPROC 13 /* Processor-specific range */
|
||||
#define STB_HIPROC 15
|
||||
|
||||
/* st_info: Symbol Types */
|
||||
#define STT_NOTYPE 0 /* Type not specified */
|
||||
#define STT_OBJECT 1 /* Associated with a data object */
|
||||
#define STT_FUNC 2 /* Associated with a function */
|
||||
#define STT_SECTION 3 /* Associated with a section */
|
||||
#define STT_FILE 4 /* Associated with a file name */
|
||||
#define STT_NUM 5
|
||||
|
||||
#define STT_LOOS 10 /* Operating system specific range */
|
||||
#define STT_HIOS 12
|
||||
#define STT_LOPROC 13 /* Processor-specific range */
|
||||
#define STT_HIPROC 15
|
||||
|
||||
/* st_info utility macros */
|
||||
#define ELF32_ST_BIND(info) ((Elf32_Word)(info) >> 4)
|
||||
#define ELF32_ST_TYPE(info) ((Elf32_Word)(info) & 0xf)
|
||||
#define ELF32_ST_INFO(bind,type) ((Elf_Byte)(((bind) << 4) | ((type) & 0xf)))
|
||||
|
||||
/*
|
||||
* Special section indexes
|
||||
*/
|
||||
#define SHN_UNDEF 0 /* Undefined section */
|
||||
|
||||
#define SHN_LORESERVE 0xff00 /* Reserved range */
|
||||
#define SHN_ABS 0xfff1 /* Absolute symbols */
|
||||
#define SHN_COMMON 0xfff2 /* Common symbols */
|
||||
#define SHN_HIRESERVE 0xffff
|
||||
|
||||
#define SHN_LOPROC 0xff00 /* Processor-specific range */
|
||||
#define SHN_HIPROC 0xff1f
|
||||
#define SHN_LOOS 0xff20 /* Operating system specific range */
|
||||
#define SHN_HIOS 0xff3f
|
||||
|
||||
#define SHN_MIPS_ACOMMON 0xff00
|
||||
#define SHN_MIPS_TEXT 0xff01
|
||||
#define SHN_MIPS_DATA 0xff02
|
||||
#define SHN_MIPS_SCOMMON 0xff03
|
||||
|
||||
/*
|
||||
* Relocation Entries
|
||||
*/
|
||||
typedef struct {
|
||||
Elf32_Word r_offset; /* where to do it */
|
||||
Elf32_Word r_info; /* index & type of relocation */
|
||||
} Elf32_Rel;
|
||||
|
||||
typedef struct {
|
||||
Elf32_Word r_offset; /* where to do it */
|
||||
Elf32_Word r_info; /* index & type of relocation */
|
||||
Elf32_Sword r_addend; /* adjustment value */
|
||||
} Elf32_Rela;
|
||||
|
||||
/* r_info utility macros */
|
||||
#define ELF32_R_SYM(info) ((info) >> 8)
|
||||
#define ELF32_R_TYPE(info) ((info) & 0xff)
|
||||
#define ELF32_R_INFO(sym, type) (((sym) << 8) + (unsigned char)(type))
|
||||
|
||||
/*
|
||||
* Dynamic Section structure array
|
||||
*/
|
||||
typedef struct {
|
||||
Elf32_Word d_tag; /* entry tag value */
|
||||
union {
|
||||
Elf32_Addr d_ptr;
|
||||
Elf32_Word d_val;
|
||||
} d_un;
|
||||
} Elf32_Dyn;
|
||||
|
||||
/* d_tag */
|
||||
#define DT_NULL 0 /* Marks end of dynamic array */
|
||||
#define DT_NEEDED 1 /* Name of needed library (DT_STRTAB offset) */
|
||||
#define DT_PLTRELSZ 2 /* Size, in bytes, of relocations in PLT */
|
||||
#define DT_PLTGOT 3 /* Address of PLT and/or GOT */
|
||||
#define DT_HASH 4 /* Address of symbol hash table */
|
||||
#define DT_STRTAB 5 /* Address of string table */
|
||||
#define DT_SYMTAB 6 /* Address of symbol table */
|
||||
#define DT_RELA 7 /* Address of Rela relocation table */
|
||||
#define DT_RELASZ 8 /* Size, in bytes, of DT_RELA table */
|
||||
#define DT_RELAENT 9 /* Size, in bytes, of one DT_RELA entry */
|
||||
#define DT_STRSZ 10 /* Size, in bytes, of DT_STRTAB table */
|
||||
#define DT_SYMENT 11 /* Size, in bytes, of one DT_SYMTAB entry */
|
||||
#define DT_INIT 12 /* Address of initialization function */
|
||||
#define DT_FINI 13 /* Address of termination function */
|
||||
#define DT_SONAME 14 /* Shared object name (DT_STRTAB offset) */
|
||||
#define DT_RPATH 15 /* Library search path (DT_STRTAB offset) */
|
||||
#define DT_SYMBOLIC 16 /* Start symbol search within local object */
|
||||
#define DT_REL 17 /* Address of Rel relocation table */
|
||||
#define DT_RELSZ 18 /* Size, in bytes, of DT_REL table */
|
||||
#define DT_RELENT 19 /* Size, in bytes, of one DT_REL entry */
|
||||
#define DT_PLTREL 20 /* Type of PLT relocation entries */
|
||||
#define DT_DEBUG 21 /* Used for debugging; unspecified */
|
||||
#define DT_TEXTREL 22 /* Relocations might modify non-writable seg */
|
||||
#define DT_JMPREL 23 /* Address of relocations associated with PLT */
|
||||
#define DT_BIND_NOW 24 /* Process all relocations at load-time */
|
||||
#define DT_INIT_ARRAY 25 /* Address of initialization function array */
|
||||
#define DT_FINI_ARRAY 26 /* Size, in bytes, of DT_INIT_ARRAY array */
|
||||
#define DT_INIT_ARRAYSZ 27 /* Address of termination function array */
|
||||
#define DT_FINI_ARRAYSZ 28 /* Size, in bytes, of DT_FINI_ARRAY array */
|
||||
#define DT_NUM 29
|
||||
|
||||
#define DT_LOOS 0x60000000 /* Operating system specific range */
|
||||
#define DT_HIOS 0x6fffffff
|
||||
#define DT_LOPROC 0x70000000 /* Processor-specific range */
|
||||
#define DT_HIPROC 0x7fffffff
|
||||
|
||||
/*
|
||||
* Auxiliary Vectors
|
||||
*/
|
||||
typedef struct {
|
||||
Elf32_Word a_type; /* 32-bit id */
|
||||
Elf32_Word a_v; /* 32-bit id */
|
||||
} Aux32Info;
|
||||
|
||||
/* a_type */
|
||||
#define AT_NULL 0 /* Marks end of array */
|
||||
#define AT_IGNORE 1 /* No meaning, a_un is undefined */
|
||||
#define AT_EXECFD 2 /* Open file descriptor of object file */
|
||||
#define AT_PHDR 3 /* &phdr[0] */
|
||||
#define AT_PHENT 4 /* sizeof(phdr[0]) */
|
||||
#define AT_PHNUM 5 /* # phdr entries */
|
||||
#define AT_PAGESZ 6 /* PAGESIZE */
|
||||
#define AT_BASE 7 /* Interpreter base addr */
|
||||
#define AT_FLAGS 8 /* Processor flags */
|
||||
#define AT_ENTRY 9 /* Entry address of executable */
|
||||
#define AT_DCACHEBSIZE 10 /* Data cache block size */
|
||||
#define AT_ICACHEBSIZE 11 /* Instruction cache block size */
|
||||
#define AT_UCACHEBSIZE 12 /* Unified cache block size */
|
||||
|
||||
/* Vendor specific */
|
||||
#define AT_MIPS_NOTELF 10 /* XXX a_val != 0 -> MIPS XCOFF executable */
|
||||
|
||||
#define AT_SUN_UID 2000 /* euid */
|
||||
#define AT_SUN_RUID 2001 /* ruid */
|
||||
#define AT_SUN_GID 2002 /* egid */
|
||||
#define AT_SUN_RGID 2003 /* rgid */
|
||||
|
||||
/* Solaris kernel specific */
|
||||
#define AT_SUN_LDELF 2004 /* dynamic linker's ELF header */
|
||||
#define AT_SUN_LDSHDR 2005 /* dynamic linker's section header */
|
||||
#define AT_SUN_LDNAME 2006 /* dynamic linker's name */
|
||||
#define AT_SUN_LPGSIZE 2007 /* large pagesize */
|
||||
|
||||
/* Other information */
|
||||
#define AT_SUN_PLATFORM 2008 /* sysinfo(SI_PLATFORM) */
|
||||
#define AT_SUN_HWCAP 2009 /* process hardware capabilities */
|
||||
#define AT_SUN_IFLUSH 2010 /* do we need to flush the instruction cache? */
|
||||
#define AT_SUN_CPU 2011 /* cpu name */
|
||||
/* ibcs2 emulation band aid */
|
||||
#define AT_SUN_EMUL_ENTRY 2012 /* coff entry point */
|
||||
#define AT_SUN_EMUL_EXECFD 2013 /* coff file descriptor */
|
||||
/* Executable's fully resolved name */
|
||||
#define AT_SUN_EXECNAME 2014
|
||||
|
||||
/*
|
||||
* Note Headers
|
||||
*/
|
||||
typedef struct {
|
||||
Elf32_Word n_namesz;
|
||||
Elf32_Word n_descsz;
|
||||
Elf32_Word n_type;
|
||||
} Elf32_Nhdr;
|
||||
|
||||
#define ELF_NOTE_TYPE_ABI_TAG 1
|
||||
|
||||
/* GNU-specific note name and description sizes */
|
||||
#define ELF_NOTE_ABI_NAMESZ 4
|
||||
#define ELF_NOTE_ABI_DESCSZ 16
|
||||
/* GNU-specific note name */
|
||||
#define ELF_NOTE_ABI_NAME "GNU\0"
|
||||
|
||||
/* GNU-specific OS/version value stuff */
|
||||
#define ELF_NOTE_ABI_OS_LINUX 0
|
||||
#define ELF_NOTE_ABI_OS_HURD 1
|
||||
#define ELF_NOTE_ABI_OS_SOLARIS 2
|
||||
|
||||
/* NetBSD-specific note type: Emulation name. desc is emul name string. */
|
||||
#define ELF_NOTE_TYPE_NETBSD_TAG 1
|
||||
|
||||
/* NetBSD-specific note name and description sizes */
|
||||
#define ELF_NOTE_NETBSD_NAMESZ 7
|
||||
#define ELF_NOTE_NETBSD_DESCSZ 4
|
||||
/* NetBSD-specific note name */
|
||||
#define ELF_NOTE_NETBSD_NAME "NetBSD\0\0"
|
||||
|
||||
/*
|
||||
* NetBSD-specific core file information.
|
||||
*
|
||||
* NetBSD ELF core files use notes to provide information about
|
||||
* the process's state. The note name is "NetBSD-CORE" for
|
||||
* information that is global to the process, and "NetBSD-CORE@nn",
|
||||
* where "nn" is the lwpid of the LWP that the information belongs
|
||||
* to (such as register state).
|
||||
*
|
||||
* We use the following note identifiers:
|
||||
*
|
||||
* ELF_NOTE_NETBSD_CORE_PROCINFO
|
||||
* Note is a "netbsd_elfcore_procinfo" structure.
|
||||
*
|
||||
* We also use ptrace(2) request numbers (the ones that exist in
|
||||
* machine-dependent space) to identify register info notes. The
|
||||
* info in such notes is in the same format that ptrace(2) would
|
||||
* export that information.
|
||||
*
|
||||
* Please try to keep the members of this structure nicely aligned,
|
||||
* and if you add elements, add them to the end and bump the version.
|
||||
*/
|
||||
|
||||
#define ELF_NOTE_NETBSD_CORE_NAME "NetBSD-CORE"
|
||||
|
||||
#define ELF_NOTE_NETBSD_CORE_PROCINFO 1
|
||||
|
||||
#define NETBSD_ELFCORE_PROCINFO_VERSION 1
|
||||
|
||||
struct netbsd_elfcore_procinfo {
|
||||
/* Version 1 fields start here. */
|
||||
/* Add version 2 fields below here. */
|
||||
};
|
||||
|
||||
#if defined(ELFSIZE)
|
||||
#define CONCAT(x,y) __CONCAT(x,y)
|
||||
#define ELFNAME(x) CONCAT(elf,CONCAT(ELFSIZE,CONCAT(_,x)))
|
||||
#define ELFNAME2(x,y) CONCAT(x,CONCAT(_elf,CONCAT(ELFSIZE,CONCAT(_,y))))
|
||||
#define ELFNAMEEND(x) CONCAT(x,CONCAT(_elf,ELFSIZE))
|
||||
#define ELFDEFNNAME(x) CONCAT(ELF,CONCAT(ELFSIZE,CONCAT(_,x)))
|
||||
#endif
|
||||
|
||||
#define Elf_Ehdr Elf32_Ehdr
|
||||
#define Elf_Phdr Elf32_Phdr
|
||||
#define Elf_Shdr Elf32_Shdr
|
||||
#define Elf_Sym Elf32_Sym
|
||||
#define Elf_Rel Elf32_Rel
|
||||
#define Elf_Rela Elf32_Rela
|
||||
#define Elf_Dyn Elf32_Dyn
|
||||
#define Elf_Word Elf32_Word
|
||||
#define Elf_Sword Elf32_Sword
|
||||
#define Elf_Addr Elf32_Addr
|
||||
#define Elf_Off Elf32_Off
|
||||
#define Elf_Nhdr Elf32_Nhdr
|
||||
|
||||
#define ELF_R_SYM ELF32_R_SYM
|
||||
#define ELF_R_TYPE ELF32_R_TYPE
|
||||
#define ELFCLASS ELFCLASS32
|
||||
|
||||
#define ELF_ST_BIND ELF32_ST_BIND
|
||||
#define ELF_ST_TYPE ELF32_ST_TYPE
|
||||
#define ELF_ST_INFO ELF32_ST_INFO
|
||||
|
||||
#define AuxInfo Aux32Info
|
||||
|
||||
#ifdef _KERNEL
|
||||
|
||||
#define ELF_AUX_ENTRIES 8 /* Size of aux array passed to loader */
|
||||
#define ELF32_NO_ADDR (~(Elf32_Addr)0) /* Indicates addr. not yet filled in */
|
||||
|
||||
#if defined(ELFSIZE) && (ELFSIZE == 64)
|
||||
#define ELF_NO_ADDR ELF64_NO_ADDR
|
||||
#elif defined(ELFSIZE) && (ELFSIZE == 32)
|
||||
#define ELF_NO_ADDR ELF32_NO_ADDR
|
||||
#endif
|
||||
|
||||
#ifndef ELF32_EHDR_FLAGS_OK
|
||||
#define ELF32_EHDR_FLAGS_OK(eh) 1
|
||||
#endif
|
||||
|
||||
#define ELF_EHDR_FLAGS_OK(eh) ELF32_EHDR_FLAGS_OK(eh)
|
||||
|
||||
#if defined(ELFSIZE)
|
||||
struct elf_args {
|
||||
Elf_Addr arg_entry; /* program entry point */
|
||||
Elf_Addr arg_interp; /* Interpreter load address */
|
||||
Elf_Addr arg_phaddr; /* program header address */
|
||||
Elf_Addr arg_phentsize; /* Size of program header */
|
||||
Elf_Addr arg_phnum; /* Number of program headers */
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifndef _LKM
|
||||
#include "opt_execfmt.h"
|
||||
#endif
|
||||
|
||||
#ifdef EXEC_ELF32
|
||||
int exec_elf32_makecmds __P((struct proc *, struct exec_package *));
|
||||
int elf32_copyargs __P((struct exec_package *, struct ps_strings *,
|
||||
char **, void *));
|
||||
|
||||
int coredump_elf32 __P((struct proc *, struct vnode *, struct ucred *));
|
||||
int coredump_writenote_elf32 __P((struct proc *, struct vnode *,
|
||||
struct ucred *, off_t, Elf32_Nhdr *,
|
||||
const char *, void *));
|
||||
#endif
|
||||
|
||||
/* common */
|
||||
int exec_elf_setup_stack __P((struct proc *, struct exec_package *));
|
||||
|
||||
#endif /* _KERNEL */
|
||||
|
||||
#endif /* !_SYS_EXEC_ELF_H_ */
|
||||
@@ -0,0 +1,87 @@
|
||||
#ifndef ATAPI_H_
|
||||
#define ATAPI_H_
|
||||
|
||||
# include <k/compiler.h>
|
||||
# include <k/types.h>
|
||||
|
||||
/* Device Control Registers */
|
||||
# define PRIMARY_DCR 0x3F6
|
||||
# define SECONDARY_DCR 0x376
|
||||
|
||||
/* DCR bits */
|
||||
# define INTERRUPT_DISABLE (1 << 1)
|
||||
# define SRST (1 << 2)
|
||||
|
||||
/* Drive selection bytes */
|
||||
# define ATA_PORT_MASTER 0x00
|
||||
# define ATA_PORT_SLAVE 0x10
|
||||
|
||||
/* ATA bus IO ports */
|
||||
# define PRIMARY_REG 0x1F0
|
||||
# define SECONDARY_REG 0x170
|
||||
|
||||
/* ATA I/O registers */
|
||||
# define ATA_REG_DATA(PORT) (PORT)
|
||||
# define ATA_REG_FEATURES(PORT) ((PORT) + 1)
|
||||
# define ATA_REG_ERROR_INFO(PORT) ((PORT) + 1)
|
||||
# define ATA_REG_SECTOR_COUNT(PORT) ((PORT) + 2)
|
||||
# define ATA_REG_SECTOR_NB(PORT) ((PORT) + 3)
|
||||
# define ATA_REG_LBA_LO(PORT) ((PORT) + 3)
|
||||
# define ATA_REG_CYLINDER_LOW(PORT) ((PORT) + 4)
|
||||
# define ATA_REG_LBA_MI(PORT) ((PORT) + 4)
|
||||
# define ATA_REG_CYLINDER_HIGH(PORT) ((PORT) + 5)
|
||||
# define ATA_REG_LBA_HI(PORT) ((PORT) + 5)
|
||||
# define ATA_REG_DRIVE(PORT) ((PORT) + 6)
|
||||
# define ATA_REG_HEAD(PORT) ((PORT) + 6)
|
||||
# define ATA_REG_COMMAND(PORT) ((PORT) + 7)
|
||||
# define ATA_REG_STATUS(PORT) ((PORT) + 7)
|
||||
|
||||
/* Status bits */
|
||||
# define ERR (1 << 0)
|
||||
# define DRQ (1 << 3)
|
||||
# define SRV (1 << 4)
|
||||
# define DF (1 << 5)
|
||||
# define RDY (1 << 6)
|
||||
# define BSY (1 << 7)
|
||||
|
||||
# define ABRT (1 << 2)
|
||||
|
||||
/* ATAPI signature */
|
||||
# define ATAPI_SIG_SC 0x01
|
||||
# define ATAPI_SIG_LBA_LO 0x01
|
||||
# define ATAPI_SIG_LBA_MI 0x14
|
||||
# define ATAPI_SIG_LBA_HI 0xEB
|
||||
|
||||
/* ATA commands */
|
||||
# define IDENTIFY_PACKET_DEVICE 0xA1
|
||||
# define PACKET 0xA0
|
||||
|
||||
/* SCSI commands */
|
||||
# define READ_12 0xA8
|
||||
|
||||
# define DPO (1 << 4)
|
||||
|
||||
# define ATAPI_BLK_CACHE_SZ 256
|
||||
# define CD_BLOCK_SZ 2048
|
||||
# define PACKET_SZ 12
|
||||
|
||||
# define PACKET_AWAIT_COMMAND 1
|
||||
# define PACKET_DATA_TRANSMIT 2
|
||||
# define PACKET_COMMAND_COMPLETE 3
|
||||
|
||||
struct SCSI_packet {
|
||||
u8 op_code;
|
||||
u8 flags_lo;
|
||||
u8 lba_hi;
|
||||
u8 lba_mihi;
|
||||
u8 lba_milo;
|
||||
u8 lba_lo;
|
||||
u8 transfer_length_hi;
|
||||
u8 transfer_length_mihi;
|
||||
u8 transfer_length_milo;
|
||||
u8 transfer_length_lo;
|
||||
u8 flags_hi;
|
||||
u8 control;
|
||||
} __packed;
|
||||
|
||||
#endif /* !ATAPI_H_ */
|
||||
@@ -0,0 +1,39 @@
|
||||
#ifndef BLOCKDEV_H_
|
||||
#define BLOCKDEV_H_
|
||||
|
||||
# include <assert.h>
|
||||
# include <k/types.h>
|
||||
|
||||
struct blockdev;
|
||||
|
||||
struct blk_ops {
|
||||
void *(*read)(struct blockdev *, size_t);
|
||||
void (*free_blk)(struct blockdev *, void *);
|
||||
};
|
||||
|
||||
struct blockdev {
|
||||
size_t blk_size;
|
||||
|
||||
struct blk_ops *ops;
|
||||
void *blocks;
|
||||
};
|
||||
|
||||
static inline void *block_read(struct blockdev *bd, size_t lba)
|
||||
{
|
||||
assert(bd);
|
||||
assert(bd->ops);
|
||||
assert(bd->ops->read);
|
||||
|
||||
return bd->ops->read(bd, lba);
|
||||
}
|
||||
|
||||
static inline void block_free(struct blockdev *bd, void *ptr)
|
||||
{
|
||||
assert(bd);
|
||||
assert(bd->ops);
|
||||
assert(bd->ops->free_blk);
|
||||
|
||||
bd->ops->free_blk(bd, ptr);
|
||||
}
|
||||
|
||||
#endif /* BLOCKDEV_H_ */
|
||||
@@ -0,0 +1,8 @@
|
||||
#ifndef COMPILER_H
|
||||
#define COMPILER_H
|
||||
|
||||
#define array_size(arr) (sizeof(arr) / sizeof(*arr))
|
||||
#define __packed __attribute__((__packed__))
|
||||
#define align_up(addr, bytes) (((addr) + (bytes) - 1) & ~((bytes) - 1))
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,138 @@
|
||||
/*
|
||||
* This file is part of my_read_iso.
|
||||
*
|
||||
* my_read_iso is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* my_read_iso is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with my_read_iso; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Copyright Alexandre Becoulet, 2003
|
||||
* contact : alexandre.becoulet@epita.fr
|
||||
*/
|
||||
|
||||
#ifndef ISO9660_H
|
||||
# define ISO9660_H
|
||||
|
||||
# define __packed __attribute__((__packed__))
|
||||
|
||||
/* Structures used for twin values */
|
||||
|
||||
struct endian32 {
|
||||
u32 le; /* little endian value */
|
||||
u32 be; /* big endian value */
|
||||
} __packed;
|
||||
|
||||
struct endian16 {
|
||||
u16 le; /* little endian value */
|
||||
u16 be; /* big endian value */
|
||||
} __packed;
|
||||
|
||||
# define ISO_BLOCK_SIZE 2048
|
||||
|
||||
/* ISO9660 Path table structure */
|
||||
|
||||
struct iso_path_table_le {
|
||||
u8 idf_len; /* Identifier name length */
|
||||
u8 ext_size; /* Extended attribute record length */
|
||||
u32 data_blk; /* File data block index */
|
||||
u16 parent_dir; /* Number of the parent dir */
|
||||
char idf[0]; /* directory name */
|
||||
} __packed;
|
||||
|
||||
/* ISO9660 directory structure */
|
||||
|
||||
# define MAX_DIR_DEPTH 8
|
||||
# define ISO_DATE_LEN 7
|
||||
|
||||
enum iso_file_type {
|
||||
ISO_FILE_HIDDEN = 1, /* File is Hidden */
|
||||
ISO_FILE_ISDIR = 2, /* Entry is a Directory */
|
||||
ISO_FILE_ASSOCIAT = 4, /* Entry is an Associated */
|
||||
ISO_FILE_USEEXT = 8,
|
||||
/* Information is structured according to the extended attribute record */
|
||||
ISO_FILE_USEPERM = 16,
|
||||
/* Permissions are specified in the extended attribute record */
|
||||
ISO_FILE_MULTIDIR = 128 /* File has more than one directory record */
|
||||
};
|
||||
|
||||
struct iso_dir {
|
||||
u8 dir_size; /* Length of directory record */
|
||||
u8 ext_size; /* Extended attribute record length */
|
||||
struct endian32 data_blk; /* File data block index */
|
||||
struct endian32 file_size; /* File size */
|
||||
char date[ISO_DATE_LEN];
|
||||
u8 type; /* File type (enum iso_file_type) */
|
||||
|
||||
/* only valid if the file is recorded in interleave mode */
|
||||
u8 unit_size; /* File Unit Size */
|
||||
u8 gap_size; /* Interleave Gap Size */
|
||||
|
||||
struct endian16 vol_seq;
|
||||
u8 idf_len;
|
||||
char idf[0]; /* file name */
|
||||
} __packed;
|
||||
|
||||
/* ISO9660 Primary volume descriptor structure */
|
||||
|
||||
# define ISO_PRIM_VOLDESC_BLOCK 16
|
||||
|
||||
# define ISO_SYSIDF_LEN 32
|
||||
# define ISO_VOLIDF_LEN 32
|
||||
# define ISO_VOLSET_LEN 128
|
||||
# define ISO_PUBIDF_LEN 128
|
||||
# define ISO_DPREP_LEN 128
|
||||
# define ISO_APP_LEN 128
|
||||
# define ISO_CPRFIL_LEN 37
|
||||
# define ISO_ABSFIL_LEN 37
|
||||
# define ISO_BIBFIL_LEN 37
|
||||
# define ISO_LDATE_LEN 17
|
||||
|
||||
struct iso_prim_voldesc {
|
||||
u8 vol_desc_type; /* Volume Descriptor Type (1) */
|
||||
char std_identifier[5]; /* Standard Identifier (CD001) */
|
||||
u8 vol_desc_version; /* Volume Descriptor Version (1) */
|
||||
u8 unused1; /* Unused Field */
|
||||
char syidf[ISO_SYSIDF_LEN]; /* System Identifier */
|
||||
char vol_idf[ISO_VOLIDF_LEN]; /* Volume Identifier */
|
||||
u8 unused2[8]; /* Unused Field */
|
||||
struct endian32 vol_blk_count;
|
||||
/* Number of logical blocks in the Volume (LE)*/
|
||||
u8 unused4[32]; /* Unused Field */
|
||||
struct endian16 vol_set_size; /* The Volume Set size of the Volume */
|
||||
struct endian16 vol_seq_num; /* The number of the volume in the Set */
|
||||
struct endian16 vol_blk_size; /* The size in bytes of a Logical Block */
|
||||
struct endian32 path_table_size; /* Length in bytes of the path table */
|
||||
u32 le_path_table_blk; /* LittleEndian path table block index */
|
||||
u32 le_opath_table_blk;
|
||||
/* LittleEndian optional path table block index */
|
||||
u32 be_path_table_blk; /* BigEndian path table block index */
|
||||
u32 be_opath_table_blk; /* BigEndian optional path table block index */
|
||||
|
||||
struct iso_dir root_dir; /* Root directory entry */
|
||||
u8 unused5[34 - sizeof (struct iso_dir)];/* padding */
|
||||
|
||||
char volset_idf[ISO_VOLSET_LEN]; /* Name of the multiple volume set */
|
||||
char pub_idf[ISO_PUBIDF_LEN]; /* Publisher name */
|
||||
char dprep_idf[ISO_DPREP_LEN]; /* Data preparer name */
|
||||
char app_idf[ISO_APP_LEN]; /* Application name */
|
||||
|
||||
char copyright_file[ISO_CPRFIL_LEN]; /* Copyright file name in root dir */
|
||||
char abstract_file[ISO_ABSFIL_LEN]; /* Abstract file name in root dir */
|
||||
char bibli_file[ISO_BIBFIL_LEN]; /* Bibliographic file name in root dir */
|
||||
char date_creat[ISO_LDATE_LEN]; /* Creation date */
|
||||
char date_modif[ISO_LDATE_LEN]; /* Modification date */
|
||||
char date_expir[ISO_LDATE_LEN]; /* Expiration date */
|
||||
char date_effect[ISO_LDATE_LEN]; /* Effective date */
|
||||
u8 filestrutc_version; /* File Structure Version (1) */
|
||||
} __packed;
|
||||
|
||||
#endif /* !ISO9660_H */
|
||||
@@ -0,0 +1,92 @@
|
||||
#ifndef K_KFS_H
|
||||
#define K_KFS_H
|
||||
|
||||
#include <k/types.h>
|
||||
|
||||
#define KFS_MAGIC 0xd35f9caa
|
||||
|
||||
#define KFS_MIN_BLK_SZ 512
|
||||
|
||||
#define KFS_BLK_SZ 4096
|
||||
|
||||
#define KFS_BLK_DATA_SZ (KFS_BLK_SZ - 3 * 4)
|
||||
|
||||
#define KFS_DIRECT_BLK 10
|
||||
|
||||
#define KFS_INDIRECT_BLK 16
|
||||
|
||||
#define KFS_INDIRECT_BLK_CNT 16
|
||||
|
||||
#define KFS_FNAME_SZ 32
|
||||
|
||||
#define KFS_NAME_SZ 32
|
||||
|
||||
#define __packed __attribute__((__packed__))
|
||||
|
||||
struct kfs_block {
|
||||
u32 idx;
|
||||
u32 usage;
|
||||
u32 cksum;
|
||||
u8 data[KFS_BLK_DATA_SZ];
|
||||
} __packed;
|
||||
|
||||
struct kfs_iblock {
|
||||
u32 idx;
|
||||
u32 blk_cnt;
|
||||
u32 blks[KFS_INDIRECT_BLK_CNT];
|
||||
u32 cksum;
|
||||
} __packed;
|
||||
|
||||
struct kfs_inode {
|
||||
u32 inumber;
|
||||
char filename[KFS_FNAME_SZ];
|
||||
u32 file_sz;
|
||||
u32 idx;
|
||||
u32 blk_cnt;
|
||||
u32 next_inode;
|
||||
u32 d_blk_cnt;
|
||||
u32 i_blk_cnt;
|
||||
u32 d_blks[KFS_DIRECT_BLK];
|
||||
u32 i_blks[KFS_INDIRECT_BLK];
|
||||
u32 cksum;
|
||||
} __packed;
|
||||
|
||||
struct kfs_blk {
|
||||
union {
|
||||
struct kfs_block blk;
|
||||
struct kfs_iblock iblk;
|
||||
struct kfs_inode ino;
|
||||
u8 whole_blk[KFS_BLK_SZ];
|
||||
};
|
||||
};
|
||||
|
||||
struct kfs_superblock {
|
||||
u32 magic;
|
||||
char name[KFS_NAME_SZ];
|
||||
s32 ctime;
|
||||
u32 blk_cnt;
|
||||
u32 inode_cnt;
|
||||
u32 inode_idx;
|
||||
u32 cksum;
|
||||
} __packed;
|
||||
|
||||
#define ADLER32_MOD 65521
|
||||
|
||||
/**
|
||||
* @brief Adler32 checksum.
|
||||
*/
|
||||
static inline unsigned int kfs_checksum(const void *data, size_t size)
|
||||
{
|
||||
unsigned int a = 1;
|
||||
unsigned int b = 0;
|
||||
size_t i = 0;
|
||||
const u8 *buf = data;
|
||||
|
||||
while (i < size) {
|
||||
a += buf[i++];
|
||||
b += a;
|
||||
}
|
||||
return ((b % ADLER32_MOD) << 16) | (a % ADLER32_MOD);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,154 @@
|
||||
/*
|
||||
* Copyright (c) LSE
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY LSE AS IS AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL LSE BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef K_KSTD_H_
|
||||
#define K_KSTD_H_
|
||||
|
||||
#include <k/types.h>
|
||||
|
||||
typedef s32 ssize_t;
|
||||
typedef s32 off_t;
|
||||
|
||||
struct melody {
|
||||
unsigned long freq;
|
||||
unsigned long duration;
|
||||
};
|
||||
|
||||
/*
|
||||
** constants
|
||||
*/
|
||||
|
||||
/* console */
|
||||
enum e_cons_codes {
|
||||
CONS_ESCAPE = 255,
|
||||
CONS_CLEAR = 1,
|
||||
CONS_COLOR = 2,
|
||||
CONS_SETX = 3,
|
||||
CONS_SETY = 4,
|
||||
CONS_BLACK = 0,
|
||||
CONS_BLUE = 1,
|
||||
CONS_GREEN = 2,
|
||||
CONS_CYAN = 3,
|
||||
CONS_RED = 4,
|
||||
CONS_MAGENTA = 5,
|
||||
CONS_YELLOW = 6,
|
||||
CONS_WHITE = 7,
|
||||
CONS_BLINK = (1 << 7),
|
||||
CONS_LIGHT = (1 << 3)
|
||||
};
|
||||
|
||||
#define CONS_FRONT(Color) (Color)
|
||||
#define CONS_BACK(Color) (Color << 4)
|
||||
|
||||
/* keyboard */
|
||||
enum e_kbd_codes {
|
||||
KEY_ESC = 1,
|
||||
KEY_F1 = 59,
|
||||
KEY_F2 = 60,
|
||||
KEY_F3 = 61,
|
||||
KEY_F4 = 62,
|
||||
KEY_F5 = 63,
|
||||
KEY_F6 = 64,
|
||||
KEY_F7 = 65,
|
||||
KEY_F8 = 66,
|
||||
KEY_f9 = 67,
|
||||
KEY_F10 = 68,
|
||||
KEY_F11 = 87,
|
||||
KEY_F12 = 88,
|
||||
KEY_1 = 2,
|
||||
KEY_2 = 3,
|
||||
KEY_3 = 4,
|
||||
KEY_4 = 5,
|
||||
KEY_5 = 6,
|
||||
KEY_6 = 7,
|
||||
KEY_7 = 8,
|
||||
KEY_8 = 9,
|
||||
KEY_9 = 10,
|
||||
KEY_0 = 11,
|
||||
KEY_TAB = 15,
|
||||
KEY_MAJLOCK = 58,
|
||||
KEY_LSHIFT = 42,
|
||||
KEY_RSHIFT = 54,
|
||||
KEY_ALT = 56,
|
||||
KEY_SPACE = 57,
|
||||
KEY_CTRL = 29,
|
||||
KEY_ENTER = 28,
|
||||
KEY_BACKSPACE = 14,
|
||||
KEY_LEFT = 75,
|
||||
KEY_RIGHT = 77,
|
||||
KEY_UP = 72,
|
||||
KEY_DOWN = 80,
|
||||
KEY_PAUSE = 69,
|
||||
KEY_SYST = 55,
|
||||
KEY_INSER = 82,
|
||||
KEY_SUPPR = 83,
|
||||
};
|
||||
|
||||
enum e_k_mode {
|
||||
KEY_PRESSED,
|
||||
KEY_RELEASED,
|
||||
};
|
||||
|
||||
/* mouse */
|
||||
enum e_mouse_codes {
|
||||
BUTTON_LEFT = 1,
|
||||
BUTTON_RIGHT = 2
|
||||
};
|
||||
|
||||
/* misc */
|
||||
#define O_RDONLY 0
|
||||
#define SEEK_SET 0
|
||||
#define SEEK_CUR 1
|
||||
#define SEEK_END 2
|
||||
#define VIDEO_GRAPHIC 0
|
||||
#define VIDEO_TEXT 1
|
||||
|
||||
/*
|
||||
** syscalls
|
||||
*/
|
||||
|
||||
#define SYSCALL_WRITE 1
|
||||
#define SYSCALL_SBRK 2
|
||||
#define SYSCALL_GETKEY 3
|
||||
#define SYSCALL_GETTICK 4
|
||||
#define SYSCALL_OPEN 5
|
||||
#define SYSCALL_READ 6
|
||||
#define SYSCALL_SEEK 7
|
||||
#define SYSCALL_CLOSE 8
|
||||
#define SYSCALL_SETVIDEO 9
|
||||
#define SYSCALL_SWAP_FRONTBUFFER 10
|
||||
#define SYSCALL_PLAYSOUND 11
|
||||
#define SYSCALL_SETPALETTE 12
|
||||
|
||||
#define SYSCALL_GETMOUSE 13
|
||||
#define NR_SYSCALL (SYSCALL_GETMOUSE + 1)
|
||||
|
||||
#define ENOMEM 1 /* Not enough space */
|
||||
#define ENOENT 2 /* No such file or directory */
|
||||
#define EIO 3 /* I/O error */
|
||||
#define EINVAL 4 /* Invalid argument */
|
||||
#define ENOSYS 5 /* Invalid system call number */
|
||||
#define EBADF 6 /* fd is not an open file descriptor */
|
||||
#define EAGAIN 7 /* Temporary unavailable */
|
||||
|
||||
#endif /* !KSTD_H_ */
|
||||
@@ -0,0 +1,15 @@
|
||||
#ifndef K_TYPES_H
|
||||
#define K_TYPES_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
typedef unsigned char u8;
|
||||
typedef signed char s8;
|
||||
typedef unsigned short u16;
|
||||
typedef signed short s16;
|
||||
typedef unsigned int u32;
|
||||
typedef signed int s32;
|
||||
typedef unsigned long long u64;
|
||||
typedef signed long long s64;
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,34 @@
|
||||
#ifndef IO_H_
|
||||
#define IO_H_
|
||||
|
||||
#include <k/types.h>
|
||||
|
||||
static inline void outb(u16 port, u8 val)
|
||||
{
|
||||
asm volatile ("outb %0, %1" : /* No output */ : "a"(val), "d"(port));
|
||||
}
|
||||
|
||||
static inline u8 inb(u16 port)
|
||||
{
|
||||
u8 res;
|
||||
|
||||
asm volatile ("inb %1, %0" : "=&a"(res) : "d"(port));
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static inline void outw(u16 port, u16 val)
|
||||
{
|
||||
asm volatile ("outw %0, %1" : /* No output */ : "a"(val), "d"(port));
|
||||
}
|
||||
|
||||
static inline u16 inw(u16 port)
|
||||
{
|
||||
u16 res;
|
||||
|
||||
asm volatile ("inw %1, %0" : "=&a"(res) : "d"(port));
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
#endif /* !IO_H_ */
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (c) LSE
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY LSE AS IS AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL LSE BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include <k/kstd.h>
|
||||
|
||||
#include "multiboot.h"
|
||||
|
||||
|
||||
void k_main(unsigned long magic, multiboot_info_t *info)
|
||||
{
|
||||
(void)magic;
|
||||
(void)info;
|
||||
|
||||
char star[4] = "|/-\\";
|
||||
char *fb = (void *)0xb8000;
|
||||
|
||||
for (unsigned i = 0; ; ) {
|
||||
*fb = star[i++ % 4];
|
||||
}
|
||||
|
||||
for (;;)
|
||||
asm volatile ("hlt");
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (c) LSE
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY LSE AS IS AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL LSE BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
OUTPUT_FORMAT("elf32-i386")
|
||||
OUTPUT_ARCH("i386")
|
||||
ENTRY(k_entry)
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
. = 0x100000 + SIZEOF_HEADERS;
|
||||
|
||||
.text :
|
||||
{
|
||||
*(.multiboot) *(.text) *(.text.*)
|
||||
}
|
||||
|
||||
.rodata :
|
||||
{
|
||||
*(.rodata) *(.rodata.*)
|
||||
}
|
||||
|
||||
.data :
|
||||
{
|
||||
*(.data) *(.data.*)
|
||||
}
|
||||
|
||||
.bss :
|
||||
{
|
||||
*(.bss) *(.bss.*) *(COMMON)
|
||||
}
|
||||
|
||||
PROVIDE(_end = .);
|
||||
}
|
||||
+251
@@ -0,0 +1,251 @@
|
||||
/*
|
||||
* Copyright (c) LSE
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY LSE AS IS AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL LSE BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include <k/compiler.h>
|
||||
|
||||
#include "libvga.h"
|
||||
#include "io.h"
|
||||
|
||||
/*
|
||||
** Use to save the VGA plane 2, which contains the text font,
|
||||
** when we switch into graphic mode.
|
||||
*/
|
||||
static unsigned char libvga_txt_mode_font[320 * 200];
|
||||
|
||||
/*
|
||||
** Registers value for graphic mode.
|
||||
*/
|
||||
static unsigned char libvga_regs_320x200x256[] = {
|
||||
/* MISC */
|
||||
0x63,
|
||||
/* SEQ */
|
||||
0x03, 0x01, 0x0F, 0x00, 0x0E,
|
||||
/* CRTC */
|
||||
0x5F, 0x4F, 0x50, 0x82, 0x54, 0x80, 0xBF, 0x1F,
|
||||
0x00, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x9C, 0x0E, 0x8F, 0x28, 0x40, 0x96, 0xB9, 0xA3,
|
||||
0xFF,
|
||||
/* GC */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,
|
||||
0xFF,
|
||||
/* AC */
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
|
||||
0x41, 0x00, 0x0F, 0x00, 0x00
|
||||
};
|
||||
|
||||
/*
|
||||
** Registers value for basic text mode.
|
||||
*/
|
||||
static unsigned char libvga_regs_80x25xtext[] = {
|
||||
/* MISC */
|
||||
0x67,
|
||||
/* SEQ */
|
||||
0x03, 0x00, 0x03, 0x00, 0x02,
|
||||
/* CRTC */
|
||||
0x5F, 0x4F, 0x50, 0x82, 0x55, 0x81, 0xBF, 0x1F,
|
||||
0x00, 0x4F, 0x0D, 0x0E, 0x00, 0x00, 0x00, 0x50,
|
||||
0x9C, 0x0E, 0x8F, 0x28, 0x1F, 0x96, 0xB9, 0xA3,
|
||||
0xFF,
|
||||
/* GC */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0E, 0x00,
|
||||
0xFF,
|
||||
/* AC */
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07,
|
||||
0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
|
||||
0x0C, 0x00, 0x0F, 0x08, 0x00
|
||||
};
|
||||
|
||||
/*
|
||||
** Basic Windows BITMAP pallet.
|
||||
** This palette is automatically loaded when switching to mode 13h
|
||||
*/
|
||||
static unsigned int libvga_default_palette[256] = {
|
||||
0x0, 0x800000, 0x8000, 0x808000,
|
||||
0x80, 0x800080, 0x8080, 0xc0c0c0,
|
||||
0xc0dcc0, 0xa6caf0, 0x402000, 0x602000,
|
||||
0x802000, 0xa02000, 0xc02000, 0xe02000,
|
||||
0x4000, 0x204000, 0x404000, 0x604000,
|
||||
0x804000, 0xa04000, 0xc04000, 0xe04000,
|
||||
0x6000, 0x206000, 0x406000, 0x606000,
|
||||
0x806000, 0xa06000, 0xc06000, 0xe06000,
|
||||
0x8000, 0x208000, 0x408000, 0x608000,
|
||||
0x808000, 0xa08000, 0xc08000, 0xe08000,
|
||||
0xa000, 0x20a000, 0x40a000, 0x60a000,
|
||||
0x80a000, 0xa0a000, 0xc0a000, 0xe0a000,
|
||||
0xc000, 0x20c000, 0x40c000, 0x60c000,
|
||||
0x80c000, 0xa0c000, 0xc0c000, 0xe0c000,
|
||||
0xe000, 0x20e000, 0x40e000, 0x60e000,
|
||||
0x80e000, 0xa0e000, 0xc0e000, 0xe0e000,
|
||||
0x40, 0x200040, 0x400040, 0x600040,
|
||||
0x800040, 0xa00040, 0xc00040, 0xe00040,
|
||||
0x2040, 0x202040, 0x402040, 0x602040,
|
||||
0x802040, 0xa02040, 0xc02040, 0xe02040,
|
||||
0x4040, 0x204040, 0x404040, 0x604040,
|
||||
0x804040, 0xa04040, 0xc04040, 0xe04040,
|
||||
0x6040, 0x206040, 0x406040, 0x606040,
|
||||
0x806040, 0xa06040, 0xc06040, 0xe06040,
|
||||
0x8040, 0x208040, 0x408040, 0x608040,
|
||||
0x808040, 0xa08040, 0xc08040, 0xe08040,
|
||||
0xa040, 0x20a040, 0x40a040, 0x60a040,
|
||||
0x80a040, 0xa0a040, 0xc0a040, 0xe0a040,
|
||||
0xc040, 0x20c040, 0x40c040, 0x60c040,
|
||||
0x80c040, 0xa0c040, 0xc0c040, 0xe0c040,
|
||||
0xe040, 0x20e040, 0x40e040, 0x60e040,
|
||||
0x80e040, 0xa0e040, 0xc0e040, 0xe0e040,
|
||||
0x80, 0x200080, 0x400080, 0x600080,
|
||||
0x800080, 0xa00080, 0xc00080, 0xe00080,
|
||||
0x2080, 0x202080, 0x402080, 0x602080,
|
||||
0x802080, 0xa02080, 0xc02080, 0xe02080,
|
||||
0x4080, 0x204080, 0x404080, 0x604080,
|
||||
0x804080, 0xa04080, 0xc04080, 0xe04080,
|
||||
0x6080, 0x206080, 0x406080, 0x606080,
|
||||
0x806080, 0xa06080, 0xc06080, 0xe06080,
|
||||
0x8080, 0x208080, 0x408080, 0x608080,
|
||||
0x808080, 0xa08080, 0xc08080, 0xe08080,
|
||||
0xa080, 0x20a080, 0x40a080, 0x60a080,
|
||||
0x80a080, 0xa0a080, 0xc0a080, 0xe0a080,
|
||||
0xc080, 0x20c080, 0x40c080, 0x60c080,
|
||||
0x80c080, 0xa0c080, 0xc0c080, 0xe0c080,
|
||||
0xe080, 0x20e080, 0x40e080, 0x60e080,
|
||||
0x80e080, 0xa0e080, 0xc0e080, 0xe0e080,
|
||||
0xc0, 0x2000c0, 0x4000c0, 0x6000c0,
|
||||
0x8000c0, 0xa000c0, 0xc000c0, 0xe000c0,
|
||||
0x20c0, 0x2020c0, 0x4020c0, 0x6020c0,
|
||||
0x8020c0, 0xa020c0, 0xc020c0, 0xe020c0,
|
||||
0x40c0, 0x2040c0, 0x4040c0, 0x6040c0,
|
||||
0x8040c0, 0xa040c0, 0xc040c0, 0xe040c0,
|
||||
0x60c0, 0x2060c0, 0x4060c0, 0x6060c0,
|
||||
0x8060c0, 0xa060c0, 0xc060c0, 0xe060c0,
|
||||
0x80c0, 0x2080c0, 0x4080c0, 0x6080c0,
|
||||
0x8080c0, 0xa080c0, 0xc080c0, 0xe080c0,
|
||||
0xa0c0, 0x20a0c0, 0x40a0c0, 0x60a0c0,
|
||||
0x80a0c0, 0xa0a0c0, 0xc0a0c0, 0xe0a0c0,
|
||||
0xc0c0, 0x20c0c0, 0x40c0c0, 0x60c0c0,
|
||||
0x80c0c0, 0xa0c0c0, 0xfffbf0, 0xa0a0a4,
|
||||
0x808080, 0xff0000, 0xff00, 0xffff00,
|
||||
0xff, 0xff00ff, 0xffff, 0xffffff
|
||||
};
|
||||
|
||||
static void libvga_write_regs(unsigned char *regs)
|
||||
{
|
||||
unsigned int i;
|
||||
unsigned int a;
|
||||
|
||||
/* write the MISC register */
|
||||
outb(VGA_MISC_WRITE, *regs);
|
||||
regs++;
|
||||
|
||||
/* write SEQ registers */
|
||||
for (i = 0; i < VGA_NUM_SEQ_REGS; i++) {
|
||||
outb(VGA_SEQ_INDEX, i);
|
||||
outb(VGA_SEQ_DATA, *regs);
|
||||
regs++;
|
||||
}
|
||||
|
||||
/* write CRTC registers */
|
||||
outb(VGA_CRTC_INDEX, 0x03);
|
||||
a = inb(VGA_CRTC_DATA);
|
||||
outb(VGA_CRTC_DATA, a | 0x80);
|
||||
outb(VGA_CRTC_INDEX, 0x11);
|
||||
a = inb(VGA_CRTC_DATA);
|
||||
outb(VGA_CRTC_DATA, a & ~0x80);
|
||||
regs[0x03] |= 0x80;
|
||||
regs[0x11] &= ~0x80;
|
||||
for (i = 0; i < VGA_NUM_CRTC_REGS; i++) {
|
||||
outb(VGA_CRTC_INDEX, i);
|
||||
outb(VGA_CRTC_DATA, *regs);
|
||||
regs++;
|
||||
}
|
||||
|
||||
/* write GC registers */
|
||||
for (i = 0; i < VGA_NUM_GC_REGS; i++) {
|
||||
outb(VGA_GC_INDEX, i);
|
||||
outb(VGA_GC_DATA, *regs);
|
||||
regs++;
|
||||
}
|
||||
|
||||
/* write AC registers */
|
||||
inb(VGA_INSTAT_READ);
|
||||
for (i = 0; i < VGA_NUM_AC_REGS; i++) {
|
||||
outb(VGA_AC_INDEX, i);
|
||||
outb(VGA_AC_WRITE, *regs);
|
||||
regs++;
|
||||
}
|
||||
inb(VGA_INSTAT_READ);
|
||||
outb(VGA_AC_INDEX, 0x20);
|
||||
|
||||
/* write the default palette to the DAC */
|
||||
outb(VGA_DAC_MASK, 0xFF);
|
||||
libvga_set_palette(libvga_default_palette, array_size(libvga_default_palette));
|
||||
}
|
||||
|
||||
void libvga_set_palette(unsigned int *new_palette, size_t size)
|
||||
{
|
||||
outb(VGA_DAC_WRITE_INDEX, 0);
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
outb(VGA_DAC_DATA, ((new_palette[i] >> 16) >> 2) & 0xFF);
|
||||
outb(VGA_DAC_DATA, ((new_palette[i] >> 8) >> 2) & 0xFF);
|
||||
outb(VGA_DAC_DATA, ((new_palette[i]) >> 2) & 0xFF);
|
||||
}
|
||||
}
|
||||
|
||||
char *libvga_get_framebuffer(void)
|
||||
{
|
||||
unsigned int mmap_select;
|
||||
|
||||
outb(VGA_GC_INDEX, 6);
|
||||
mmap_select = inb(VGA_GC_DATA);
|
||||
mmap_select >>= 2;
|
||||
mmap_select &= 3;
|
||||
switch (mmap_select) {
|
||||
case 0:
|
||||
case 1:
|
||||
return (char *)0xA0000;
|
||||
case 2:
|
||||
return (char *)0xB0000;
|
||||
case 3:
|
||||
return (char *)0xB8000;
|
||||
}
|
||||
return (char *)0;
|
||||
}
|
||||
|
||||
void libvga_switch_mode13h(void)
|
||||
{
|
||||
libvga_write_regs(libvga_regs_320x200x256);
|
||||
|
||||
// plane 2 is now map in the memory, save it
|
||||
char *vram = libvga_get_framebuffer();
|
||||
for (size_t i = 0; i < array_size(libvga_txt_mode_font); i++)
|
||||
libvga_txt_mode_font[i] = vram[i];
|
||||
}
|
||||
|
||||
void libvga_switch_mode3h(void)
|
||||
{
|
||||
// restore the VGA plane 2 to the text font
|
||||
char *vram = libvga_get_framebuffer();
|
||||
for (size_t i = 0; i < array_size(libvga_txt_mode_font); i++)
|
||||
vram[i] = libvga_txt_mode_font[i];
|
||||
|
||||
libvga_write_regs(libvga_regs_80x25xtext);
|
||||
}
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (c) LSE
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY LSE AS IS AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL LSE BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef LIBVGA_H
|
||||
#define LIBVGA_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#define VGA_AC_INDEX 0x3C0
|
||||
#define VGA_AC_WRITE 0x3C0
|
||||
#define VGA_AC_READ 0x3C1
|
||||
#define VGA_MISC_WRITE 0x3C2
|
||||
#define VGA_SEQ_INDEX 0x3C4
|
||||
#define VGA_SEQ_DATA 0x3C5
|
||||
#define VGA_DAC_MASK 0x3C6
|
||||
#define VGA_DAC_READ_INDEX 0x3C7
|
||||
#define VGA_DAC_WRITE_INDEX 0x3C8
|
||||
#define VGA_DAC_DATA 0x3C9
|
||||
#define VGA_MISC_READ 0x3CC
|
||||
#define VGA_GC_INDEX 0x3CE
|
||||
#define VGA_GC_DATA 0x3CF
|
||||
|
||||
#define VGA_CRTC_INDEX 0x3D4
|
||||
#define VGA_CRTC_DATA 0x3D5
|
||||
#define VGA_INSTAT_READ 0x3DA
|
||||
|
||||
#define VGA_NUM_SEQ_REGS 5
|
||||
#define VGA_NUM_CRTC_REGS 25
|
||||
#define VGA_NUM_GC_REGS 9
|
||||
#define VGA_NUM_AC_REGS 21
|
||||
|
||||
void libvga_set_palette(unsigned int *new_palette, size_t size);
|
||||
|
||||
char *libvga_get_framebuffer(void);
|
||||
|
||||
void libvga_switch_mode13h(void);
|
||||
|
||||
void libvga_switch_mode3h(void);
|
||||
|
||||
#endif /* !LIBVGA_H */
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* This list data structure is verbatim copy from wayland-util.h from the
|
||||
* Wayland project; except that wl_ prefix has been removed.
|
||||
*/
|
||||
|
||||
#include "list.h"
|
||||
|
||||
void list_init(struct list *list)
|
||||
{
|
||||
list->prev = list;
|
||||
list->next = list;
|
||||
}
|
||||
|
||||
void list_insert(struct list *list, struct list *elm)
|
||||
{
|
||||
elm->prev = list;
|
||||
elm->next = list->next;
|
||||
list->next = elm;
|
||||
elm->next->prev = elm;
|
||||
}
|
||||
|
||||
void list_remove(struct list *elm)
|
||||
{
|
||||
elm->prev->next = elm->next;
|
||||
elm->next->prev = elm->prev;
|
||||
elm->next = NULL;
|
||||
elm->prev = NULL;
|
||||
}
|
||||
|
||||
int list_empty(const struct list *list)
|
||||
{
|
||||
return list->next == list;
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
#ifndef LIST_H
|
||||
#define LIST_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
/*
|
||||
* This list data structure is a verbatim copy from wayland-util.h from the
|
||||
* Wayland project; except that wl_ prefix has been removed.
|
||||
*/
|
||||
|
||||
struct list {
|
||||
struct list *prev;
|
||||
struct list *next;
|
||||
};
|
||||
|
||||
void list_init(struct list *list);
|
||||
void list_insert(struct list *list, struct list *elm);
|
||||
void list_remove(struct list *elm);
|
||||
int list_empty(const struct list *list);
|
||||
|
||||
#define container_of(ptr, type, member) \
|
||||
(__typeof__(type) *)((char *)(ptr) - \
|
||||
offsetof(__typeof__(type), member))
|
||||
|
||||
#define list_first_entry(head, pos, member) \
|
||||
container_of((head)->next, __typeof__(*pos), member)
|
||||
|
||||
#define list_for_each(pos, head, member) \
|
||||
for (pos = 0, pos = list_first_entry(head, pos, member); \
|
||||
&pos->member != (head); \
|
||||
pos = list_first_entry(&pos->member, pos, member))
|
||||
|
||||
#define list_for_each_safe(pos, tmp, head, member) \
|
||||
for (pos = 0, tmp = 0, \
|
||||
pos = list_first_entry(head, pos, member), \
|
||||
tmp = list_first_entry(&pos->member, tmp, member); \
|
||||
&pos->member != (head); \
|
||||
pos = tmp, \
|
||||
tmp = list_first_entry(&pos->member, tmp, member))
|
||||
|
||||
#endif /* LIST_H */
|
||||
+267
@@ -0,0 +1,267 @@
|
||||
#include "memory.h"
|
||||
|
||||
#include <k/types.h>
|
||||
#include <stdio.h>
|
||||
|
||||
static struct list memory_map = {&memory_map, &memory_map};
|
||||
static struct cache *memory_map_cache;
|
||||
static struct cache *metadata_cache;
|
||||
|
||||
static void *__memory_reserve_ex(unsigned int base_addr, size_t size, int in_extend);
|
||||
static void *__cache_alloc(struct cache *cache, int in_extend);
|
||||
|
||||
static void cache_initialize(struct cache *c, void *p, size_t sz, size_t bsize)
|
||||
{
|
||||
list_init(&c->freelist);
|
||||
list_init(&c->caches);
|
||||
c->base = p;
|
||||
c->size = sz;
|
||||
c->bsize = bsize;
|
||||
|
||||
for (size_t i = 0; i < sz / bsize; ++i) {
|
||||
struct list *l = (struct list *)((char *) p + i * bsize);
|
||||
list_init(l);
|
||||
list_insert(c->freelist.prev, l);
|
||||
}
|
||||
}
|
||||
|
||||
static void cache_extend(struct cache *old, void *p, size_t sz, size_t bsize, int in_extend)
|
||||
{
|
||||
struct cache *c = __cache_alloc(metadata_cache, in_extend);
|
||||
cache_initialize(c, p, sz, bsize);
|
||||
list_insert(old->caches.prev, &c->caches);
|
||||
}
|
||||
|
||||
struct cache *cache_new(void *base, size_t nmemb, size_t bsize)
|
||||
{
|
||||
struct cache *c = cache_alloc(metadata_cache);
|
||||
|
||||
cache_initialize(c, base, nmemb * bsize, bsize);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
static size_t freelist_size(struct cache *cache)
|
||||
{
|
||||
if (list_empty(&cache->freelist))
|
||||
return 0;
|
||||
|
||||
size_t len = 1;
|
||||
|
||||
struct list *l = cache->freelist.next;
|
||||
|
||||
for (; l != &cache->freelist; l = l->next) {
|
||||
len++;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static size_t cache_remaining(struct cache *cache)
|
||||
{
|
||||
size_t len = freelist_size(cache);
|
||||
|
||||
struct cache *c;
|
||||
list_for_each(c, &cache->caches, caches) {
|
||||
len += freelist_size(c);
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static void *__cache_alloc(struct cache *cache, int in_extend)
|
||||
{
|
||||
try_alloc:
|
||||
if (!list_empty(&cache->freelist)) {
|
||||
struct list *l = cache->freelist.next;
|
||||
list_remove(l);
|
||||
return (void *)l;
|
||||
}
|
||||
|
||||
struct cache *c;
|
||||
list_for_each(c, &cache->caches, caches) {
|
||||
if (!list_empty(&c->freelist)) {
|
||||
return cache_alloc(c);
|
||||
}
|
||||
}
|
||||
|
||||
if (cache_remaining(metadata_cache) <= 2 && !in_extend) {
|
||||
void *p = __memory_reserve_ex(0, metadata_cache->size, 1);
|
||||
cache_extend(metadata_cache, p,
|
||||
metadata_cache->size,
|
||||
metadata_cache->bsize, 1);
|
||||
}
|
||||
|
||||
void *p = memory_reserve(c->size);
|
||||
cache_extend(c, p, c->size, c->bsize, 0);
|
||||
|
||||
goto try_alloc;
|
||||
}
|
||||
|
||||
void *cache_alloc(struct cache *cache)
|
||||
{
|
||||
return __cache_alloc(cache, 0);
|
||||
}
|
||||
|
||||
static int cache_try_free(struct cache *cache, void *ptr)
|
||||
{
|
||||
if ((size_t)cache->base <= (size_t)ptr
|
||||
&& (size_t)cache->base + cache->size > (size_t)ptr) {
|
||||
list_init(ptr);
|
||||
list_insert(&cache->freelist, ptr);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void cache_free(struct cache *cache, void *ptr)
|
||||
{
|
||||
if (cache_try_free(cache, ptr)) {
|
||||
return;
|
||||
}
|
||||
struct cache *c;
|
||||
list_for_each(c, &cache->caches, caches) {
|
||||
if (cache_try_free(c, ptr)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
/* FIXME: handle the case when the pointer does not belong to the cache */
|
||||
}
|
||||
|
||||
static void memory_initialize(struct memory_map *m,
|
||||
unsigned addr, unsigned size, int type)
|
||||
{
|
||||
list_init(&m->list);
|
||||
m->base_addr = addr;
|
||||
m->size = size;
|
||||
m->type = type;
|
||||
}
|
||||
|
||||
void memory_dump()
|
||||
{
|
||||
struct memory_map *m;
|
||||
list_for_each(m, &memory_map, list) {
|
||||
printf("{.base_addr=%p, .length=0x%x, .type=%u}\n",
|
||||
m->base_addr, m->size, m->type);
|
||||
}
|
||||
}
|
||||
|
||||
extern void *_end[]; /* kernel data end address */
|
||||
|
||||
#define BASE_METADATA_CACHE_NMEMB 10
|
||||
|
||||
void memory_init(multiboot_info_t *info)
|
||||
{
|
||||
unsigned int last_loaded_addr = info->mods_count
|
||||
? ((multiboot_module_t *)info->mods_addr)[info->mods_count - 1].mod_end
|
||||
: 0;
|
||||
|
||||
if (last_loaded_addr < (u32)_end) {
|
||||
last_loaded_addr = (u32)_end; /* XXX: needs to align up */
|
||||
}
|
||||
|
||||
/* take the first good memory region */
|
||||
unsigned int reservation_addr = last_loaded_addr;
|
||||
unsigned int reservation_len = (BASE_METADATA_CACHE_NMEMB + 1) * sizeof(struct cache);
|
||||
|
||||
unsigned int num_mem_zone = info->mmap_length / sizeof(multiboot_memory_map_t);
|
||||
|
||||
metadata_cache = (void *)reservation_addr;
|
||||
cache_initialize(metadata_cache, metadata_cache + 1, BASE_METADATA_CACHE_NMEMB * sizeof(struct cache),
|
||||
sizeof(struct cache));
|
||||
|
||||
memory_map_cache = cache_new((void *)(reservation_addr + reservation_len),
|
||||
num_mem_zone * 2, sizeof(struct memory_map));
|
||||
|
||||
reservation_len += num_mem_zone * 2 * sizeof(struct memory_map);
|
||||
|
||||
multiboot_memory_map_t *map = (void *)info->mmap_addr;
|
||||
|
||||
for (size_t i = 0; i < num_mem_zone; ++i) {
|
||||
struct memory_map *m = cache_alloc(memory_map_cache);
|
||||
|
||||
memory_initialize(m, (u32)map[i].addr, (u32)map[i].len,
|
||||
map[i].type - 1);
|
||||
|
||||
list_insert(memory_map.prev, &m->list);
|
||||
}
|
||||
|
||||
/* reserve all low memory to avoid overwriting grub data */
|
||||
memory_reserve_ex(0, info->mem_lower * 1024);
|
||||
/* reserve kernel and fs data */
|
||||
memory_reserve_ex(0x100000, last_loaded_addr - 0x100000);
|
||||
/* reserve initial cache datas */
|
||||
memory_reserve_ex(reservation_addr, reservation_len);
|
||||
}
|
||||
|
||||
static void *memory_split(struct memory_map *m, size_t size)
|
||||
{
|
||||
struct memory_map *t = cache_alloc(memory_map_cache);
|
||||
memory_initialize(t, m->base_addr, size, 2);
|
||||
|
||||
list_insert(m->list.prev, &t->list);
|
||||
|
||||
m->size -= size;
|
||||
m->base_addr += size;
|
||||
|
||||
return (void *)t->base_addr;
|
||||
}
|
||||
|
||||
static void *__memory_reserve_ex(unsigned int base_addr, size_t size, int in_extend)
|
||||
{
|
||||
if (cache_remaining(memory_map_cache) <= 2 && !in_extend) {
|
||||
void *p = __memory_reserve_ex(0, 10 * sizeof(struct cache), 1);
|
||||
cache_extend(memory_map_cache, p, 10 * sizeof(struct cache),
|
||||
sizeof(struct cache), 0);
|
||||
}
|
||||
|
||||
struct memory_map *m;
|
||||
list_for_each(m, &memory_map, list) {
|
||||
if (m->type)
|
||||
continue;
|
||||
|
||||
if (!base_addr && m->size >= size) {
|
||||
if (m->size == size) {
|
||||
m->type = 2;
|
||||
return (void *)m->base_addr;
|
||||
}
|
||||
return memory_split(m, size);
|
||||
} else if (base_addr >= m->base_addr && base_addr < m->base_addr + m->size) {
|
||||
if (base_addr + size >= m->base_addr + m->size) {
|
||||
return NULL;
|
||||
}
|
||||
unsigned first_size = base_addr - m->base_addr;
|
||||
if (first_size) {
|
||||
memory_split(m, first_size);
|
||||
return memory_reserve_ex(base_addr, size);
|
||||
}
|
||||
|
||||
return memory_split(m, size);
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *memory_reserve_ex(unsigned int base_addr, size_t size)
|
||||
{
|
||||
return __memory_reserve_ex(base_addr, size, 0);
|
||||
}
|
||||
|
||||
void *memory_reserve(size_t size)
|
||||
{
|
||||
return memory_reserve_ex(0, size);
|
||||
}
|
||||
|
||||
void memory_release(void *ptr)
|
||||
{
|
||||
struct memory_map *m;
|
||||
list_for_each(m, &memory_map, list) {
|
||||
if (m->base_addr == (unsigned int)ptr) {
|
||||
m->type = 0;
|
||||
/* FIXME: need to merge free blocks */
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
#ifndef MEMORY_H
|
||||
#define MEMORY_H
|
||||
|
||||
#include "list.h"
|
||||
#include "multiboot.h"
|
||||
|
||||
struct memory_map {
|
||||
struct list list;
|
||||
unsigned int base_addr;
|
||||
unsigned int size;
|
||||
int type;
|
||||
};
|
||||
|
||||
void memory_dump();
|
||||
void memory_init(multiboot_info_t *info);
|
||||
void *memory_reserve(size_t size);
|
||||
void *memory_reserve_ex(unsigned int base_addr, size_t size);
|
||||
void memory_release(void *ptr);
|
||||
|
||||
struct cache {
|
||||
struct list freelist;
|
||||
struct list caches;
|
||||
void *base;
|
||||
size_t size;
|
||||
size_t bsize;
|
||||
};
|
||||
|
||||
struct cache *cache_new(void *base, size_t nmemb, size_t bsize);
|
||||
void *cache_alloc(struct cache *cache);
|
||||
void cache_free(struct cache *cache, void *ptr);
|
||||
|
||||
#endif /* MEMORY_H */
|
||||
+262
@@ -0,0 +1,262 @@
|
||||
/* 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 __ASSEMBLER__
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
#endif /* ! ASM_FILE */
|
||||
|
||||
#endif /* ! MULTIBOOT_HEADER */
|
||||