
New features: - support of kernel tasks in 64bit mode - support of LwIP in 64bit mode Missing features in 64bit mode - user-level support - APIC support => SMP support To create a 64bit version of the MetalSVM kernel, the compiler flags “-m64 -mno-red-zone” and the assembler flags “-felf64” has to be used. Please use qemu-system-x86_64 as test platform. Notice, metalsvm.elf is a 32bit ELF file. However, it contains (beside the startup code) only 64bit code. This is required because GRUB doesn’t boot 64bit ELF kernels. Therefore, for disassembling via objdump the flag “-M x86-64” has to be used.
124 lines
3.2 KiB
C
124 lines
3.2 KiB
C
/*
|
|
* Copyright 2010 Stefan Lankes, Chair for Operating Systems,
|
|
* RWTH Aachen University
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*
|
|
* This file is part of MetalSVM.
|
|
*/
|
|
|
|
/**
|
|
* @file arch/x86/include/asm/gdt.h
|
|
* @brief Definitions and functions related to segmentation
|
|
* @author Stefan Lankes
|
|
*
|
|
* This file defines the interface for segmentation as like structures to describe segments.\n
|
|
* There are also some other gdt-private functions in the gdt.c file defined.
|
|
*/
|
|
|
|
#ifndef __ARCH_GDT_H__
|
|
#define __ARCH_GDT_H__
|
|
|
|
#include <metalsvm/stddef.h>
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/// This segment is a data segment
|
|
#define GDT_FLAG_DATASEG 0x02
|
|
/// This segment is a code segment
|
|
#define GDT_FLAG_CODESEG 0x0a
|
|
#define GDT_FLAG_TSS 0x09
|
|
#define GDT_FLAG_TSS_BUSY 0x02
|
|
|
|
#define GDT_FLAG_SEGMENT 0x10
|
|
/// Privilege level: Ring 0
|
|
#define GDT_FLAG_RING0 0x00
|
|
/// Privilege level: Ring 1
|
|
#define GDT_FLAG_RING1 0x20
|
|
/// Privilege level: Ring 2
|
|
#define GDT_FLAG_RING2 0x40
|
|
/// Privilege level: Ring 3
|
|
#define GDT_FLAG_RING3 0x60
|
|
/// Segment is present
|
|
#define GDT_FLAG_PRESENT 0x80
|
|
/**
|
|
* @brief Granularity of segment limit
|
|
* - set: segment limit unit is 4 KB (page size)
|
|
* - not set: unit is bytes
|
|
*/
|
|
#define GDT_FLAG_4K_GRAN 0x80
|
|
/**
|
|
* @brief Default operand size
|
|
* - set: 32 bit
|
|
* - not set: 16 bit
|
|
*/
|
|
#define GDT_FLAG_16_BIT 0x00
|
|
#define GDT_FLAG_32_BIT 0x40
|
|
#define GDT_FLAG_64_BIT 0x20
|
|
|
|
/** @brief Defines a GDT entry
|
|
*
|
|
* A global descriptor table entry consists of:
|
|
* - 32 bit base address (chunkwise embedded into this structure)
|
|
* - 20 bit limit
|
|
*/
|
|
typedef struct {
|
|
/// Lower 16 bits of limit range
|
|
uint16_t limit_low;
|
|
/// Lower 16 bits of base address
|
|
uint16_t base_low;
|
|
/// middle 8 bits of base address
|
|
uint8_t base_middle;
|
|
/// Access bits
|
|
uint8_t access;
|
|
/// Granularity bits
|
|
uint8_t granularity;
|
|
/// Higher 8 bits of base address
|
|
uint8_t base_high;
|
|
} __attribute__ ((packed)) gdt_entry_t;
|
|
|
|
/** @brief defines the GDT pointer structure
|
|
*
|
|
* This structure tells the address and size of the table.
|
|
*/
|
|
typedef struct {
|
|
/// Size of the table in bytes (not the number of entries!)
|
|
uint16_t limit;
|
|
/// Address of the table
|
|
size_t base;
|
|
} __attribute__ ((packed)) gdt_ptr_t;
|
|
|
|
/// Defines the maximum number of GDT entries
|
|
#define GDT_ENTRIES (5+MAX_TASKS)
|
|
#if GDT_ENTRIES > 8192
|
|
#error Too many GDT entries!
|
|
#endif
|
|
|
|
/** @brief Installs the global descriptor table
|
|
*
|
|
* The installation involves the following steps:
|
|
* - set up the special GDT pointer
|
|
* - set up the entries in our GDT
|
|
* - finally call gdt_flush() in our assembler file
|
|
* in order to tell the processor where the new GDT is
|
|
* - update the new segment registers
|
|
*/
|
|
void gdt_install(void);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif
|