Изменить битность операционной системы, которую я пишу сам?
Я пишу ОС. Из-за того, что у меня мало опыта, я умею только заниматься этим для 32-бит (моя ОС получается 32-битная), но я хочу сделать ее 64-битной.
Что мне делать?
Вот код моего кернела конкретно для ассемблера:
.set MAGIC, 0x1badb002
.set FLAGS, (1<<0 | 1<<1)
.set CHECKSUM, -(MAGIC + FLAGS)
.section .multiboot
.long MAGIC
.long FLAGS
.long CHECKSUM
.section .text
.extern kernelMain
.global loader
loader:
mov $kernel_stack, %esp
push %eax
push %ebx
call kernelMain
_stop:
cli
hlt
jmp _stop
.section .bss
.space 2*1024*1024; # 2 megabytes of space
kernel_stack:
Хотел еще добавить, что он скорее всего еще не готов, это примерно 3/4.
На всякий случай кидаю kernel.cpp:
#include "types.h"
#include "gdt.h"
void print(char* str) {
unsigned short* VideoMemory = (unsigned short*)0xb8000;
static uint8_t x = 0, y = 0;
for(int i = 0; str[i] != '\0'; ++i) {
switch(str[i]) {
case '\n':
y++;
x = 0;
break;
default:
VideoMemory[80*y+x] = (VideoMemory[80*y+x] & 0xFF00) | str[i];
x++;
break;
}
if(x >= 80) {
y++;
x = 0;
}
if (y >= 25) {
for(y = 0; y < 25; y++)
for(x = 0; x < 80; x++)
VideoMemory[80*y+x] = (VideoMemory[80*y+x] & 0xFF00) | ' ';
x = 0;
y = 0;
}
}
}
extern "C" void kernelMain(void* multiboot_structure, unsigned int magicnumber) {
print("something\n");
GlobalDescriptorTable gdt;
while(1);
}
А, и еще немного информации:
Я компилирую свой код на ассемблере при помощи as в Ubuntu; C++ код при помощи g++.
Если найдете дупликаты, пожалуйста, скиньте ссылку.
Ответы (1 шт):
Приведенный код совсем не похож на код операционной системы. У вас просто происходит вызов функции kernelMain и последующий бесконечный цикл ожидания аппаратных прерываний. Преобразовывать в 64-битный режим тут нечего, этот код будет выглядеть идентично в любом режиме.
Переход в 64-битный режим в процессорах Intel x86 осуществляется установкой флага LME (бит 8) в регистре Extended Feature Enable Register (EFER). См. Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 3: System Programming Guide, раздел 2.2.1
Инструкция, которая заполняет этот регистр - wrmsr.
После этого нужно заполнить GDT так, чтобы в ней был сегмент кода с флагом 64-битного режима (21 бит в дескрипторе), и, соответственно, выполнить код в этом сегменте. Подробнее можно почитать здесь: https://wiki.osdev.org/User:Stephanvanschaik/Setting_Up_Long_Mode
