miniOS
x86_64 hobby kernel with SMP, VFS, and POSIX process model
Loading...
Searching...
No Matches
segment.h
Go to the documentation of this file.
1
// MIT License
2
//
3
// Copyright (c) 2026 Christian Spoo
4
//
5
// Permission is hereby granted, free of charge, to any person obtaining a copy
6
// of this software and associated documentation files (the "Software"), to deal
7
// in the Software without restriction, including without limitation the rights
8
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
// copies of the Software, and to permit persons to whom the Software is
10
// furnished to do so, subject to the following conditions:
11
//
12
// The above copyright notice and this permission notice shall be included in all
13
// copies or substantial portions of the Software.
14
//
15
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
// SOFTWARE.
22
23
#ifndef _MINIOS_ARCH_X86_64_SEGMENT_H_
24
#define _MINIOS_ARCH_X86_64_SEGMENT_H_
25
26
#ifndef ASM_SOURCE
27
28
#include <
miniOS/types.h
>
29
30
// ********************************************************
31
// CPU privilege levels
32
// ********************************************************
33
34
#define KERN_PRIVILEGE_LEVEL 0
35
#define USER_PRIVILEGE_LEVEL 3
36
37
// ********************************************************
38
// x86 segment types
39
// ********************************************************
40
41
#define GDT_CS_TYPE 0x9A
// present, system, Ring 0, r-x
42
#define GDT_DS_TYPE 0x92
// present, system, Ring 0, rw-
43
#define GDT_TSS_TYPE 0x89
// present, system, Ring 0, 32-bit TSS
44
#define GDT_LDT_TYPE 0x82
// present, system, Ring 0, LDT
45
46
#define USER_CS_TYPE 0xFA
// present, non-system, Ring 3, r-x
47
#define USER_DS_TYPE 0xF2
// present, non-system, Ring 3, rw-
48
49
// ********************************************************
50
// Global Descriptor Tables
51
// ********************************************************
52
53
// The NULL descriptor doesn't get a number ;-)
54
#define GDT_CS_INDEX 1
// Kernel code segment
55
#define GDT_DS_INDEX 2
// Kernel data segment
56
#define USER_DS_INDEX 3
// User mode data segment (before UserCS for SYSRET STAR formula)
57
#define USER_CS_INDEX 4
// User mode code segment
58
#define GDT_TSS_INDEX 5
// Task state selector segment
59
#define GDT_LDT_INDEX 6
// Local Descriptor Table
60
61
// ********************************************************
62
// Precomputed segment register values (selector values)
63
// ********************************************************
64
65
/* Kernel selectors: RPL=0, TI=0 (GDT) */
66
#define KERNEL_CS_SEL SEG_REG_VAL(KERN_PRIVILEGE_LEVEL, 0, GDT_CS_INDEX)
/* 0x08 */
67
#define KERNEL_SS_SEL SEG_REG_VAL(KERN_PRIVILEGE_LEVEL, 0, GDT_DS_INDEX)
/* 0x10 */
68
69
/* User selectors: RPL=3, TI=0 (GDT). *
70
* USER_DS_INDEX=3 (0x1B) placed before USER_CS_INDEX=4 (0x23) in GDT for *
71
* SYSRETQ STAR formula: CS=STAR[63:48]+16, SS=STAR[63:48]+8. */
72
#define USER_CS_SEL SEG_REG_VAL(USER_PRIVILEGE_LEVEL, 0, USER_CS_INDEX)
/* 0x23 */
73
#define USER_DS_SEL SEG_REG_VAL(USER_PRIVILEGE_LEVEL, 0, USER_DS_INDEX)
/* 0x1B */
74
75
// ********************************************************
76
// RFLAGS constants
77
// ********************************************************
78
79
/* RFLAGS_IF: RFLAGS value with only IF (bit 1) and reserved bit 1 set. *
80
* Used as initial rflags for all kernel and user threads so that *
81
* hlt/sti sequences work correctly and user code runs with interrupts on. */
82
#define RFLAGS_IF 0x202ULL
83
84
#define GDT_CS SEG_REG_VAL(KERN_PRIVILEGE_LEVEL, 0, GDT_CS_INDEX)
85
#define GDT_DS SEG_REG_VAL(KERN_PRIVILEGE_LEVEL, 0, GDT_DS_INDEX)
86
#define GDT_TSS SEG_REG_VAL(KERN_PRIVILEGE_LEVEL, 0, GDT_TSS_INDEX)
87
#define GDT_LDT SEG_REG_VAL(KERN_PRIVILEGE_LEVEL, 0, GDT_LDT_INDEX)
88
89
// ********************************************************
90
// Local Descriptor Table
91
// ********************************************************
92
93
#define NR_LDT_ENTRIES 2
94
95
#define LDT_CS_INDEX 0
// Process code segment
96
#define LDT_DS_INDEX 1
// Process data segment
97
98
/* Structure is also used in IA-32e mode, however in that case all addresses can be set to 0 */
99
struct
segment_descriptor
{
100
uint16_t
limit_15_0
;
101
uint16_t
base_addr_15_0
;
102
uint8_t
base_addr_23_16
;
103
104
uint8_t
access
;
105
uint8_t
limit_19_16
:4;
106
uint8_t
u
:1;
107
uint8_t
long_mode
:1;
108
uint8_t
size
:1;
109
uint8_t
granularity
:1;
// length byte (0=1B..1MB, 1=4K..4GB)
110
uint8_t
base_addr_31_24
;
111
}
__attribute__
((__packed__));
112
113
#define __BUILD_SEG_DESC(base_addr, limit, _access, _long_mode, _size, _granularity) \
114
((struct segment_descriptor) { \
115
.limit_15_0 = (limit) & 0xffff, \
116
.limit_19_16 = ((limit) >> 16) & 0xf, \
117
.base_addr_15_0 = (base_addr) & 0xffff, \
118
.base_addr_23_16 = ((base_addr) >> 16) & 0xff, \
119
.base_addr_31_24 = ((base_addr) >> 24) & 0xff, \
120
.u = 0, \
121
.long_mode = (_long_mode), \
122
.size = (_size), \
123
.granularity = (_granularity), \
124
.access = (_access) \
125
})
126
127
/* Build a byte granular segment descriptor. */
128
#define BUILD_SEG_DESC(base_addr, limit, access, long_mode, size) \
129
__BUILD_SEG_DESC(base_addr, limit, access, long_mode, size, 0)
130
131
/* Build a 4KB granular segment descriptor. */
132
#define BUILD_4KB_SEG_DESC(base_addr, limit, access, long_mode, size) \
133
__BUILD_SEG_DESC(base_addr, (limit >> 12), access, long_mode, size, 1)
134
135
#define SEG_ADDR(seg_desc) \
136
(((seg_desc)->base_addr_31_24 << 24) | \
137
((seg_desc)->base_addr_23_16 << 16) | \
138
(seg_desc)->base_15_0)
139
140
#define SEG_SIZE(seg_desc) \
141
((seg_desc)->granularity ? \
142
((((seg_desc)->limit_19_16 << 16) | (seg_desc)->limit_15_0) << 12) : \
143
(((seg_desc)->limit_19_16 << 16) | (seg_desc)->limit_15_0))
144
145
#endif
146
147
// Construct segment register value
148
#define SEG_REG_VAL(privilege, in_ldt, segment_index) \
149
(((segment_index) << 3) | ((in_ldt) << 2) | (privilege))
150
151
// Return Request Privilege level of the specified segment selector
152
#define SEG_REG_RPL(seg_reg_val) ((seg_reg_val) & 0x3)
153
154
#define restore_system_segments \
155
pushq %rax; \
156
mov $GDT_DS, %ax; \
157
mov %ax, %ds; \
158
mov %ax, %es; \
159
mov %ax, %fs; \
160
mov %ax, %gs; \
161
popq %rax;
162
163
#endif
segment_descriptor
Definition
segment.h:99
segment_descriptor::size
uint8_t size
Definition
segment.h:108
segment_descriptor::u
uint8_t u
Definition
segment.h:106
segment_descriptor::base_addr_15_0
uint16_t base_addr_15_0
Definition
segment.h:101
segment_descriptor::base_addr_31_24
uint8_t base_addr_31_24
Definition
segment.h:110
segment_descriptor::base_addr_23_16
uint8_t base_addr_23_16
Definition
segment.h:102
segment_descriptor::long_mode
uint8_t long_mode
Definition
segment.h:107
segment_descriptor::access
uint8_t access
Definition
segment.h:104
segment_descriptor::limit_15_0
uint16_t limit_15_0
Definition
segment.h:100
segment_descriptor::granularity
uint8_t granularity
Definition
segment.h:109
segment_descriptor::limit_19_16
uint8_t limit_19_16
Definition
segment.h:105
types.h
uint16_t
unsigned short uint16_t
Definition
types.h:31
uint8_t
unsigned char uint8_t
Definition
types.h:28
__attribute__
typedef __attribute__
include
miniOS
arch
x86_64
segment.h
Generated by
1.16.1