我想用 Grub2 启动一个自定义内核。我使用了旧的(grub 1)多重引导头:
.set flags, 0x0
.set magic, 0x1badb002
.set checksum, -(magic + flags)
.align 4
.long magic
.long flags
.long checksum
...
movl %eax, magic
Run Code Online (Sandbox Code Playgroud)
但它不适用于 Grub2,所以我搜索了新的 Multiboot 规范并找到了它:http ://bzr.savannah.gnu.org/lh/grub/branches/multiboot2/annotate/head:/doc/multiboot2 .h (它不是真正的规范,它只是一个头文件)
所以,现在我正在使用这个多重引导头:
.set flags, 0x0
.set magic, 0xe85250d6
.set magic_the_second, 0x36d76289
.set checksum, -(magic + flags)
.align 4
.long magic
.long flags
.long checksum
...
movl %eax, magic_the_second
Run Code Online (Sandbox Code Playgroud)
但它也不起作用:没有多重引导头
有什么建议?
谢谢!
我想将用户输入的号码输入寄存器。这是我自己的操作系统。所以,我不能使用这个:
mov al,0x01
int 0x21
mov dl,al ;move the integer entered by the user, into dl
Run Code Online (Sandbox Code Playgroud)
因为 int 0x21 调用 ms-dos。那么我可以使用什么中断呢?
我正在按照本教程制作一个简单的 32 位操作系统。我已经到了第 4 节,我正在写入帧缓冲区。基本上我正在尝试创建自己的 println 函数。这是我的函数的代码:
/** fb_write_cell:
* Writes a character with the given foreground and background to position i
* in the framebuffer.
*
* @param i The location in the framebuffer
* @param c The character
* @param fg The foreground color
* @param bg The background color
*/
static void fb_write_cell(unsigned int i, char c, unsigned char fg, unsigned bg) {
fb[i] = c;
fb[i + 1] = ((fg & 0x0F) << 4) …Run Code Online (Sandbox Code Playgroud) 我试图在学习汇编的同时学习内核的工作原理,并且在学习如何成功创建可引导的 x86_64 内核的过程中,我遇到了一个问题:
我试图在“main.c”中成功输出一些带有函数的文本(下面的所有文件)通过使用 VGA 缓冲区0xB8000,与我使用 32 位版本的内核原型相同,但不同的是启动文件不同。
这里的问题是,当我对 32 位版本使用完全相同的功能时,它成功地打印到屏幕上,但是当使用新文件达到长模式(multiboot.S和start.S)时,这不会发生,屏幕会变黑在 qemu 中测试时,几秒钟后它崩溃并显示错误消息:
warning: TCG doesn't support requested feature: CPUID.01H:ECX.vmx [bit 5]
qemu-system-x86_64: Trying to execute code outside RAM or ROM at 0x00000000000a0000
Run Code Online (Sandbox Code Playgroud)
为什么会发生这种情况?VGA 缓冲区不在0xB8000,*.S 文件有问题?提前致谢!
我将在此处粘贴内核文件:
内核由 4 个文件组成:“main.c”、“start.S”、“multiboot.S”和链接描述文件“linker.ld”。
这3个文件被链接和编译没有任何错误,文件如下:这是main.c(你会看到一个“basiccolors.h”,这个文件只是定义了vga颜色代码)
#include "basiccolors.h"
#include <stddef.h>
#include <stdint.h>
volatile uint16_t* vga_buffer = (uint16_t*)0xB8000; /* memory location of the VGA textmode buffer */
/* Columns and rows of the VGA buffer */
const int …Run Code Online (Sandbox Code Playgroud) 我尝试将以下代码用于 Multiboot2 兼容内核的标头,但是当我multiboot2在 grub 中尝试该命令时,它给出了以下错误消息:
错误:不支持的标签:0xc
我的 Multiboot2 标头定义为:
section .multiboot align=4096
mbhead: dd 0xe85250d6
dd 0
dd 76
dd 0 - 76 - 0xe85250d6 ; TODO the linker and assembler get angry if we calculate this with symbols, we need to do this by hand
dw 1 ; multiboot information request
dw 0
dd 20
dd 1
dd 2
dd 6
dw 4 ; console flags
dw 0
dd 12
dd 0x3
dw 5 ; framebuffer settings …Run Code Online (Sandbox Code Playgroud) 我目前正在编写自己的操作系统(只是为了好玩,我 16 岁)并且我创建的 outprint 函数有问题。我想更改文本颜色(不是背景颜色),但它不起作用。
我已经创建了自己的printf函数SystemOutPrint/ln(以 Java 命名,因为那是我的“主要”语言,对于那些受伤的人)并发现我可以通过在 AH 寄存器中写入来更改背景颜色。在此功能之前,我在内核中什么也没做,引导加载程序只将 GDT、LDT 和模式从 16 位设置为 32 位。所以在 mov ebx, 0xb8000 之前,视频内存是不变的。
相关代码:
kmain:
mov ebx, 0xb8000 ;Video Memory
mov esi, kernelVersion
mov ah, 0x0
;setting ah to 0x0 is not neccessary, because its the default but if you
;would put in A for example it would be light green, etc.
call SystemOutPrintln
SystemOutPrintln:
mov ecx, ebx
.printChar:
lodsb
test al,al
jz .newLine
or eax,0x0F00
mov word …Run Code Online (Sandbox Code Playgroud) 以下代码如何重启系统,任何人都可以提供有关此方面的文档
#define KEYBOARD_PORT 0x64
ioperm(KEYBOARD_PORT, 0x01, 0x01);
outb(0xfe, KEYBOARD_PORT);
Run Code Online (Sandbox Code Playgroud)
在键盘端口上写入“ 0xfe”的意义是什么?
我有一个每磁道有 63 个扇区的磁盘。(我假设,根据我的观察)我想使用 int 13h 读取 16 位引导加载程序上的扇区。例如,如果我想读取扇区号 63,我将执行以下操作:
mov dl,0x80;Drive number
mov dh,0 ;This is head number/platter number
mov ch,0 ;This is cylinder number
mov cl,63 ;Sector number
mov ah,0x02 ;interrupt function
mov al,1 ;Number of sectors to be read
xor bx,bx
mov es,bx ;Making es=0
mov bx,0x8000 ;Any random buffer address
int 0x13
Run Code Online (Sandbox Code Playgroud)
上面的代码按预期工作。
现在我想读取扇区 64。我相信它将是柱面 0,磁头 1,扇区 1。我使用:
mov dl,0x80;Drive number
mov dh,1 ;This is head number/platter number
mov ch,0 ;This is cylinder number
mov cl,1 ;Sector …Run Code Online (Sandbox Code Playgroud) 为什么我们必须将mov cr0和jmp指令放入身份映射的页面中?
我一直在使用谷歌搜索这个问题,但我无法理解结果。
这是调用 insl 的函数。
void ide_read_buffer(unsigned char channel, unsigned char reg, unsigned int buffer,
unsigned int quads) {
/* WARNING: This code contains a serious bug. The inline assembly trashes ES and
* ESP for all of the code the compiler generates between the inline
* assembly blocks.
*/
if (reg > 0x07 && reg < 0x0C)
ide_write(channel, ATA_REG_CONTROL, 0x80 | channels[channel].nIEN);
asm("pushw %es; movw %ds, %ax; movw %ax, %es");
if (reg < 0x08)
insl(channels[channel].base + reg - 0x00, buffer, quads); …Run Code Online (Sandbox Code Playgroud)