我正在编写小型操作系统 - 用于练习.我从bootloader开始.
我想创建一个以16位实模式运行的小命令系统(现在).
我创建了重置驱动器的bootloader,然后在bootloader之后加载扇区.
问题是因为jmp功能后没有任何实际发生.
我不想尝试在0x7E00加载下一个扇区(我不完全确定如何使用es:bx指向地址,这可能是一个问题,我相信它的地址:偏移),就在引导加载程序之后.
这是代码:
;
; SECTOR 0x0
;
;dl is number of harddrive where is bootloader
org 0x7C00
bits 16
;reset hard drive
xor ah,ah
int 0x13
;read sectors
clc
mov bx,0x7E00
mov es,bx
xor bx,bx
mov ah,0x02 ;function
mov al,0x1 ;sectors to read
mov ch,0x0 ;tracks
mov cl,0x1 ;sector
mov dh,0x0 ;head
int 0x13
;if not readed jmp to error
jc error
;jump to 0x7E00 - executed only if loaded
jmp 0x7E00 …Run Code Online (Sandbox Code Playgroud) 我正在编写自己的操作系统.到目前为止,我的代码超过512字节,这太大了,无法容纳在简单的引导扇区中.
据我所知,我现在必须编写一个读取任意代码的引导加载程序,这些代码可能会也可能不会超过一个512字节的扇区.
引导程序需要:
这也是提出涉及操作系统开发的Stack Overflow问题的一个很好的起点.程序员经常很难创建一个Minimal,Complete和Verifiable示例.一个常见的样板/模板将允许其他Stack Overflow用户希望通过有限的大惊小怪来帮助测试代码.
我将如何构建这样一个可重用的引导程序?
我正在阅读《 RISC-V读者:开放式体系结构图集》一书。为了解释ISA(指令集体系结构)与特定实现(即微体系结构)的隔离,作者写道:
架构师的诱惑是将说明包含在ISA中,以帮助在特定时间实现一种实现的性能或成本,但会给不同的或将来的实现带来负担。
据我了解,它指出,在设计ISA时,ISA应该理想地避免公开实现它的特定微体系结构的细节。
请牢记上面的引号:当涉及程序计数器时,在RISC-V ISA上,程序计数器(pc)指向当前正在执行的指令。另一方面,在x86 ISA上,程序计数器(eip)不包含当前正在执行的指令的地址,而是包含当前指令之后的指令的地址。
x86程序计数器是否从微体系结构中抽象出来了?
我正在使用 DOS 启动并启动我的应用程序test.exe。该程序以实模式启动 BSP(引导处理器)并访问 APIC 表FEE0:0000以启用偏移量处的 SVI(伪向量中断)0x0F0并INIT-SIPI-SIPI使用ICR_low(偏移量 0x300)和ICR_high(偏移量 0x310)发送序列。BSP 进入循环jmp $以停止执行并让 AP(应用处理器)在地址处执行代码0000:8000并打印一个字符。
似乎消息没有发送到 AP,因为我没有看到它们中的任何一个在显示器上打印任何内容。
我在实模式下使用 FreeDos。编译我使用FASM(平面汇编程序)
我使用了OsDev手册,其中包含我用来测试的代码(经过一些修改)尽可能简单,看看我是否可以让它工作。我还参考了英特尔程序员手册和其他规范以及 Code Project 中的教程。
我只是想唤醒 AP 并执行一些简单的代码。我发现的所有示例都进入了虚幻模式、保护模式、长模式或专注于多核处理。我写这段代码只是为了理解它是如何工作的。
我的代码是:
format MZ
USE16
start:
mov ax, cs
mov ds, ax
mov es, ax
mov ss, ax
xor sp, sp
cld
;Clear screen
mov ax, 03h
int 10h
;Move payload to the desired address
mov …Run Code Online (Sandbox Code Playgroud) 我正在尝试编写自己的bootloader.虽然它在QEMU,Bochs和VirtualBox中运行良好,但我似乎无法在笔记本电脑上运行.
在我的笔记本电脑上,引导加载程序与所有模拟器的行为完全不同,挂起看似随机的地方,拒绝打印,甚至跳过一些jmp $指令.
虽然我对"真实硬件"有很多麻烦,但我认为它们都有一个原因.
以下代码是一个短引导加载程序,应该打印"TEST"消息3次,然后跳转到同一位置挂起:
[BITS 16]
[ORG 0x7C00]
jmp 0x0000:start_16 ; In case bootloader is at 0x07C0:0x0000
start_16:
xor ax, ax
mov ds, ax
mov es, ax
cli ; Disable interrupts
mov ss, ax
mov sp, 0x7C00
sti ; Enable interrupts
cld ; Clear Direction Flag
; Store the drive number
mov [drive_number], dl
; Print message(s)
mov si, msg
call print_string
mov si, msg
call print_string
mov si, msg
call print_string
jmp $ ; HALT
; …Run Code Online (Sandbox Code Playgroud) 我正在用汇编语言开发一个操作系统。\n在某个时间我从 NASM 收到此错误:
\n\n\n\n\nos.asm:113: 错误: TIMES 值 -138 为负数
\n
我想把这个项目进行到底。只有这样的错误才让我绝望!
\n\n这是代码:
\n\nBITS 16\n\nstart:\n mov ax, 07C0h ; Set up 4K stack space after this bootloader\n add ax, 288 ; (4096 + 512) / 16 bytes per paragraph\n mov ss, ax\n mov sp, 4096\n mov ax, 07C0h ; Set data segment to where we're loaded\n mov ds, ax\n call cls\n MOV AH, 06h ; Scroll up function\n XOR AL, AL ; Clear entire screen\n XOR …Run Code Online (Sandbox Code Playgroud) 我将引导加载程序从CHS更改为LBA,因此我将其替换int 13h 02h为int 13h 42h.它在QEMU中正常工作,但是,我在使用Bochs和笔记本电脑时遇到了麻烦.
我把bootloader写入了USB闪存盘dd if=main.bin of=/dev/sdb bs=512.笔记本电脑加载英特尔UNDI并给我以下错误:No bootable device - insert boot disk and press any key.
所以我尝试用Bochs调试它,并注意到Bochs将这个二进制文件识别为可引导的.但是,int 13h执行后没有加载任何内容.
然后我尝试从这个闪存驱动器加载我的旧PC,它的工作原理!它加载程序并正确执行它.QEMU给了我相同的结果.
这是引导加载程序代码:
org 0x7c00
bits 16
boot:
cli
; Overlap CS and DS
mov ax, cs
mov ds, ax
mov es, ax
; Setup 4K stack before this bootloader
mov ax, 0x07c0
mov ss, ax
mov sp, 4096
; Load next sectors
mov si, DAP
mov ah, 42h
; …Run Code Online (Sandbox Code Playgroud) 我正在编写一个简单的引导程序,并且有一个getch功能。
char getch()
{
uint16_t inchar;
__asm__ __volatile__ ("int $0x16\n\t"
: "=a"(inchar)
: "0"(0x0));
return (char)inchar;
}
Run Code Online (Sandbox Code Playgroud)
我尝试了第一个显而易见的解决方案,即删除inchar变量对char的强制转换,但是当我打印它时,仍然返回char而不是代码。
我的println实现:
void println(char *str)
{
while (*str)
{
// AH=0x0e, AL=char to print, BH=page, BL=fg color
__asm__ __volatile__ ("int $0x10"
:
: "a" ((0x0e<<8) | *str++),
"b" (0x0000));
}
}
Run Code Online (Sandbox Code Playgroud)
链接描述文件:
ENTRY(start);
SECTIONS
{
. = 0x7C00;
.text : {
/* Place the code in hw.o before all other code */
boot.o(.text);
*(.text);
}
/* Place …Run Code Online (Sandbox Code Playgroud) 我无法找到一个明确的例子来理解
1. XLAT指令有什么作用?
2.我们为什么要使用它?(应用程序).
我的书描述XLAT
XLAT简化了查找表的实现[1]
但我不明白作者在谈论哪个表格?
任何帮助都会很明显!
[1] 8088和8086微处理器.Walter A. Triebel
Avtar Singh