mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-08 18:26:48 +00:00
🔧 使cpu支持SSE(目前会出现#GP)
This commit is contained in:
parent
ae52d9c2d2
commit
40a551d154
@ -545,6 +545,7 @@ Label_Set_SVGA_Mode:
|
||||
|
||||
mov eax, cr0
|
||||
or eax, 1 ; 启用保护模式
|
||||
or eax, 0x22 ; 启用x87浮点运算单元
|
||||
mov cr0, eax
|
||||
|
||||
; 跳转到保护模式下的第一个程序
|
||||
@ -632,6 +633,15 @@ GO_TO_TMP_Protect:
|
||||
bts eax, 31 ; 开启分页管理机制
|
||||
mov cr0, eax
|
||||
|
||||
;now enable SSE and the like
|
||||
mov eax, cr0
|
||||
and ax, 0xFFFB ;clear coprocessor emulation CR0.EM
|
||||
or ax, 0x2 ;set coprocessor monitoring CR0.MP
|
||||
mov cr0, eax
|
||||
mov eax, cr4
|
||||
or ax, 3 << 9 ;set CR4.OSFXSR and CR4.OSXMMEXCPT at the same time
|
||||
mov cr4, eax
|
||||
|
||||
|
||||
; === 通过此条远跳转指令,处理器跳转到内核文件进行执行,正式进入IA-32e模式
|
||||
|
||||
|
@ -1,14 +1,17 @@
|
||||
SUBDIR_ROOTS := . common
|
||||
DIRS := . $(shell find $(SUBDIR_ROOTS) -type d)
|
||||
GARBAGE_PATTERNS := *.o *.s~ *.s *.S~ *.c~ *.h~ kernel *.a
|
||||
GARBAGE_PATTERNS := *.o *.s~ *.s *.S~ *.c~ *.h~ kernel
|
||||
GARBAGE := $(foreach DIR,$(DIRS),$(addprefix $(DIR)/,$(GARBAGE_PATTERNS)))
|
||||
|
||||
DIR_LIB=lib
|
||||
lib_patterns := *.a
|
||||
LIB_FILES := $(foreach DIR,$(DIR_LIB),$(addprefix $(DIR)/,$(lib_patterns)))
|
||||
all: kernel
|
||||
objcopy -I elf64-x86-64 -S -R ".eh_frame" -R ".comment" -O binary kernel ../bin/kernel/kernel.bin
|
||||
|
||||
|
||||
kernel: head.o entry.o main.o printk.o trap.o
|
||||
ld -b elf64-x86-64 -z muldefs -o kernel head.o exception/entry.o main.o common/printk.o exception/trap.o -T link.lds
|
||||
kernel: head.o entry.o main.o printk.o trap.o mm.o
|
||||
ld -b elf64-x86-64 -z muldefs -o kernel head.o exception/entry.o main.o common/printk.o exception/trap.o mm/mm.o -T link.lds
|
||||
|
||||
head.o: head.S
|
||||
gcc -E head.S > head.s # 预处理
|
||||
@ -21,14 +24,17 @@ entry.o: exception/entry.S
|
||||
main.o: main.c
|
||||
# -fno-builtin: 不使用C语言内建函数
|
||||
# The -m64 option sets int to 32bits and long and pointer to 64 bits and generates code for AMD’s x86-64 architecture.
|
||||
gcc -mcmodel=large -fno-builtin -m64 -c main.c -o main.o -fno-stack-protector
|
||||
gcc -mcmodel=large -fno-builtin -m64 -c main.c -o main.o
|
||||
|
||||
|
||||
printk.o: common/printk.c
|
||||
gcc -mcmodel=large -fno-builtin -m64 -c common/printk.c -o common/printk.o -fno-stack-protector
|
||||
gcc -mcmodel=large -fno-builtin -m64 -c common/printk.c -o common/printk.o
|
||||
|
||||
trap.o: exception/trap.c
|
||||
gcc -mcmodel=large -fno-builtin -m64 -c exception/trap.c -o exception/trap.o -fno-stack-protector
|
||||
gcc -mcmodel=large -fno-builtin -m64 -c exception/trap.c -o exception/trap.o
|
||||
|
||||
mm.o: mm/mm.c
|
||||
gcc -mcmodel=large -fno-builtin -m64 -c mm/mm.c -o mm/mm.o
|
||||
|
||||
clean:
|
||||
rm -rf $(GARBAGE)
|
@ -24,13 +24,20 @@
|
||||
#define io_lfence() __asm__ __volatile__("lfence\n\t" :: \
|
||||
: "memory") // 在lfence指令前的读操作当必须在lfence指令后的读操作前完成。
|
||||
|
||||
#define ABS(x) ((x) > 0 ? (x) : -(x)) // 绝对值
|
||||
|
||||
// 定义类型的缩写
|
||||
typedef unsigned long ul;
|
||||
typedef unsigned long long ull;
|
||||
typedef long long ll;
|
||||
|
||||
#define ABS(x) ((x) > 0 ? (x) : -(x)) // 绝对值
|
||||
|
||||
// 四舍五入成整数
|
||||
ul round(double x)
|
||||
{
|
||||
return (ul)(x+0.5);
|
||||
}
|
||||
|
||||
|
||||
//链表数据结构
|
||||
struct List
|
||||
{
|
||||
|
@ -2,7 +2,6 @@
|
||||
// Created by longjin on 2022/1/22.
|
||||
//
|
||||
#include "printk.h"
|
||||
#include <math.h>
|
||||
//#include "linkage.h"
|
||||
|
||||
struct screen_info pos;
|
||||
@ -351,6 +350,18 @@ static int vsprintf(char *buf, const char *fmt, va_list args)
|
||||
|
||||
*ip = str - buf;
|
||||
break;
|
||||
case 'f':
|
||||
// 默认精度为3
|
||||
//printk("1111\n");
|
||||
//va_arg(args, double);
|
||||
//printk("222\n");
|
||||
|
||||
if (precision < 0)
|
||||
precision = 3;
|
||||
str = write_float_point_num(str, va_arg(args, double), field_width, precision, flags);
|
||||
|
||||
|
||||
break;
|
||||
|
||||
//对于不识别的控制符,直接输出
|
||||
default:
|
||||
@ -460,7 +471,98 @@ static char *write_num(char *str, long long num, int base, int field_width, int
|
||||
|
||||
while (js_num-- > 0)
|
||||
*str++ = tmp_num[js_num];
|
||||
|
||||
|
||||
while (field_width-- > 0)
|
||||
*str++ = ' ';
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
static char *write_float_point_num(char *str, double num, int field_width, int precision, int flags)
|
||||
{
|
||||
/**
|
||||
* @brief 将浮点数按照指定的要求转换成对应的字符串
|
||||
*
|
||||
* @param str 要返回的字符串
|
||||
* @param num 要打印的数值
|
||||
* @param field_width 区域宽度
|
||||
* @param precision 精度
|
||||
* @param flags 标志位
|
||||
*/
|
||||
|
||||
char pad, sign, tmp_num_z[100], tmp_num_d[350];
|
||||
|
||||
const char *digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
// 显示小写字母
|
||||
if (flags & SMALL)
|
||||
digits = "0123456789abcdefghijklmnopqrstuvwxyz";
|
||||
|
||||
// 设置填充元素
|
||||
pad = (flags & PAD_ZERO) ? '0' : ' ';
|
||||
|
||||
sign = 0;
|
||||
if (flags & SIGN && num < 0)
|
||||
{
|
||||
sign = '-';
|
||||
num = -num;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 设置符号
|
||||
sign = (flags & PLUS) ? '+' : ((flags & SPACE) ? ' ' : 0);
|
||||
}
|
||||
|
||||
// sign占用了一个宽度
|
||||
if (sign)
|
||||
--field_width;
|
||||
|
||||
int js_num_z = 0, js_num_d = 0; // 临时数字字符串tmp_num_z tmp_num_d的长度
|
||||
ul num_z = (ul)(num); // 获取整数部分
|
||||
ul num_decimal = (ul)(round((num - num_z) * precision)); // 获取小数部分
|
||||
|
||||
if (num == 0)
|
||||
tmp_num_z[js_num_z++] = '0';
|
||||
else
|
||||
{
|
||||
//存储整数部分
|
||||
while (num_z > 0)
|
||||
{
|
||||
tmp_num_z[js_num_z++] = digits[num_z % 10]; // 注意这里,输出的数字,是小端对齐的。低位存低位
|
||||
num_z /= 10;
|
||||
}
|
||||
}
|
||||
|
||||
while (num_decimal > 0)
|
||||
{
|
||||
tmp_num_d[js_num_d++] = digits[num_decimal % 10];
|
||||
num_decimal /= 10;
|
||||
}
|
||||
|
||||
field_width -= (precision + 1 + js_num_z);
|
||||
|
||||
// 靠右对齐
|
||||
if (!(flags & LEFT))
|
||||
while (field_width-- > 0)
|
||||
*str++ = pad;
|
||||
|
||||
if (sign)
|
||||
*str++ = sign;
|
||||
|
||||
// 输出整数部分
|
||||
while (js_num_z-- > 0)
|
||||
*str++ = tmp_num_z[js_num_z];
|
||||
|
||||
*str++ = '.';
|
||||
|
||||
// 输出小数部分
|
||||
while (js_num_d-- > 0)
|
||||
*str++ = tmp_num_d[js_num_d];
|
||||
|
||||
while (js_num_d < precision)
|
||||
{
|
||||
--precision;
|
||||
*str++ = '0';
|
||||
}
|
||||
|
||||
while (field_width-- > 0)
|
||||
*str++ = ' ';
|
||||
|
@ -94,6 +94,9 @@ static int vsprintf(char *buf, const char *fmt, va_list args);
|
||||
*/
|
||||
static char* write_num(char *str, long long num, int base, int field_width, int precision, int flags);
|
||||
|
||||
|
||||
static char *write_float_point_num(char *str, double num, int field_width, int precision, int flags);
|
||||
|
||||
/**
|
||||
* @brief 在屏幕上指定位置打印字符
|
||||
*
|
||||
|
@ -211,7 +211,7 @@ void do_general_protection(unsigned long rsp, unsigned long error_code)
|
||||
printk("[ ");
|
||||
printk_color(RED, BLACK, "ERROR");
|
||||
printk(" ] do_general_protection(13),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\n", error_code, rsp, *rip);
|
||||
|
||||
return;
|
||||
while (1)
|
||||
;
|
||||
}
|
||||
|
@ -6,8 +6,10 @@
|
||||
#include "common/printk.h"
|
||||
#include "exception/gate.h"
|
||||
#include "exception/trap.h"
|
||||
#include "mm/mm.h"
|
||||
|
||||
int *FR_address = (int *)0xffff800000a00000; //帧缓存区的地址
|
||||
char fxsave_region[512] __attribute__((aligned(16)));
|
||||
|
||||
void show_welcome()
|
||||
{
|
||||
@ -67,11 +69,16 @@ void init()
|
||||
// 初始化任务状态段表
|
||||
ul tss_item_addr = 0xffff800000007c00;
|
||||
set_TSS64(tss_item_addr, tss_item_addr, tss_item_addr, tss_item_addr, tss_item_addr,
|
||||
tss_item_addr, tss_item_addr, tss_item_addr, tss_item_addr, tss_item_addr);
|
||||
tss_item_addr, tss_item_addr, tss_item_addr, tss_item_addr, tss_item_addr);
|
||||
|
||||
// 初始化中断描述符表
|
||||
init_sys_vector();
|
||||
|
||||
|
||||
asm volatile(" fxsave %0 " ::"m"(fxsave_region));
|
||||
// 初始化内存管理单元
|
||||
printk("[ DragonOS ] Initializing memory manage unit...\n");
|
||||
mm_init();
|
||||
}
|
||||
//操作系统内核从这里开始执行
|
||||
void Start_Kernel(void)
|
||||
@ -80,13 +87,10 @@ void Start_Kernel(void)
|
||||
init();
|
||||
show_welcome();
|
||||
|
||||
|
||||
|
||||
//test_printk();
|
||||
|
||||
//int t = 1 / 0; // 测试异常处理模块能否正常工作 触发除法错误
|
||||
int t = *(int*) 0xffff80000aa00000; // 触发页故障
|
||||
|
||||
// int t = *(int *)0xffff80000aa00000; // 触发页故障
|
||||
|
||||
while (1)
|
||||
;
|
||||
|
29
kernel/mm/mm.c
Normal file
29
kernel/mm/mm.c
Normal file
@ -0,0 +1,29 @@
|
||||
#include "mm.h"
|
||||
#include "../common/printk.h"
|
||||
|
||||
ul Total_Memory = 0;
|
||||
void mm_init()
|
||||
{
|
||||
// 实模式下获取到的信息的起始地址,转换为ARDS指针
|
||||
struct ARDS *ards_ptr = (struct ARDS *)0xffff800000007e00;
|
||||
|
||||
for (int i = 0; i < 32; ++i)
|
||||
{
|
||||
printk("Addr = %#10lx,%8lx\tLength = %#10lx,%8lx\tType = %#10lx\n",
|
||||
ards_ptr->BaseAddrH, ards_ptr->BaseAddrL, ards_ptr->LengthH, ards_ptr->LengthL, ards_ptr->type);
|
||||
|
||||
//可用的内存
|
||||
if (ards_ptr->type == 1)
|
||||
{
|
||||
Total_Memory += ards_ptr->LengthL;
|
||||
Total_Memory += ((ul)(ards_ptr->LengthH)) << 32;
|
||||
}
|
||||
|
||||
++ards_ptr;
|
||||
|
||||
// 脏数据
|
||||
if (ards_ptr->type > 4)
|
||||
break;
|
||||
}
|
||||
printk_color(ORANGE, BLACK, "Total amount of RAM DragonOS can use: %ld bytes\n", Total_Memory);
|
||||
}
|
21
kernel/mm/mm.h
Normal file
21
kernel/mm/mm.h
Normal file
@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
#include"../common/glib.h"
|
||||
|
||||
// Address Range Descriptor Structure 地址范围描述符
|
||||
struct ARDS
|
||||
{
|
||||
unsigned int BaseAddrL; // 基地址低32位
|
||||
unsigned int BaseAddrH; // 基地址高32位
|
||||
unsigned int LengthL; // 内存长度低32位 以字节为单位
|
||||
unsigned int LengthH; // 内存长度高32位
|
||||
unsigned int type; // 本段内存的类型
|
||||
// type=1 表示可以被操作系统使用
|
||||
// type=2 ARR - 内存使用中或被保留,操作系统不能使用
|
||||
// 其他 未定义,操作系统需要将其视为ARR
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
void mm_init();
|
Loading…
x
Reference in New Issue
Block a user