相关疑难解决方法(0)

引导加载程序不会跳转到内核代码

我正在编写小型操作系统 - 用于练习.我从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)

assembly virtualbox nasm bootloader x86-16

15
推荐指数
1
解决办法
4475
查看次数

传统BIOS引导加载程序在第二阶段引导实模式代码

我正在编写自己的操作系统.到目前为止,我的代码超过512字节,这太大了,无法容纳在简单的引导扇区中.

据我所知,我现在必须编写一个读取任意代码的引导加载程序,这些代码可能会也可能不会超过一个512字节的扇区.

引导程序需要:

  • 用作具有磁盘签名0xaa55的引导记录.
  • 从存储器地址0x7E00开始读取从LBA 1(LBA 0是引导扇区)开始的任意长度的第二阶段(测试代码).
  • 使用FAR JMP将控制转移到0x0000:0x7E00.
  • 可用作1.44 MiB软盘映像,用于QEMU,BOCHS,VirtualBox等仿真器.
  • 可以在USB记忆棒上传输和使用,以便在BIOS设置为使用软盘驱动器(FDD)仿真启动USB的情况下在真实硬件上进行测试.注意:放置在USB驱动器上时,某些引导加载程序无法正常工作.
  • 将启动驱动器传递到DL中的第二阶段.
  • 将所有段寄存器清零并将SS:SP设置为0x0000:0x7C00(从引导加载程序下方向下增长).

这也是提出涉及操作系统开发的Stack Overflow问题的一个很好的起点.程序员经常很难创建一个Minimal,Complete和Verifiable示例.一个常见的样板/模板将允许其他Stack Overflow用户希望通过有限的大惊小怪来帮助测试代码.

我将如何构建这样一个可重用的引导程序?

usb x86 assembly osdev bootloader

14
推荐指数
1
解决办法
391
查看次数

从微体系结构抽象的x86程序计数器?

我正在阅读《 RISC-V读者:开放式体系结构图集》一书。为了解释ISA(指令集体系结构)与特定实现(即微体系结构)的隔离,作者写道:

架构师的诱惑是将说明包含在ISA中,以帮助在特定时间实现一种实现的性能或成本,但会给不同的或将来的实现带来负担。

据我了解,它指出,在设计ISA时,ISA应该理想地避免公开实现它的特定微体系结构的细节。


请牢记上面的引号:当涉及程序计数器时,在RISC-V ISA上,程序计数器(pc)指向当前正在执行的指令。另一方面,在x86 ISA上,程序计数器(eip)不包含当前正在执行的指令的地址,而是包含当前指令之后的指令的地址。

x86程序计数器是否从微体系结构中抽象出来了?

x86 instruction-set cpu-architecture program-counter riscv

9
推荐指数
2
解决办法
198
查看次数

是否可以使用 INIT-SIPI-SIPI 序列唤醒所有内核都处于实模式的英特尔内核?

我正在使用 DOS 启动并启动我的应用程序test.exe。该程序以实模式启动 BSP(引导处理器)并访问 APIC 表FEE0:0000以启用偏移量处的 SVI(伪向量中断)0x0F0INIT-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)

x86 assembly multicore dos fasm

7
推荐指数
1
解决办法
688
查看次数

Bootloader在真实硬件上打印垃圾

我正在尝试编写自己的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)

x86 assembly bios osdev bootloader

5
推荐指数
1
解决办法
377
查看次数

如何用汇编语言修复“os.asm:113:错误:TIMES值-138为负数”

我正在用汇编语言开发一个操作系统。\n在某个时间我从 NASM 收到此错误:

\n\n
\n

os.asm:113: 错误: TIMES 值 -138 为负数

\n
\n\n

我想把这个项目进行到底。只有这样的错误才让我绝望!

\n\n

这是代码:

\n\n
BITS 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)

assembly nasm osdev bootloader x86-16

3
推荐指数
1
解决办法
2027
查看次数

int 13h 42h在Bochs中没有加载任何东西

我将引导加载程序从CHS更改为LBA,因此我将其替换int 13h 02hint 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)

x86 bios nasm bootloader bochs

2
推荐指数
1
解决办法
1257
查看次数

获取INT 16h键扫描代码而不是字符

我正在编写一个简单的引导程序,并且有一个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)

x86 gcc linker-errors inline-assembly bootloader

1
推荐指数
1
解决办法
211
查看次数

XLAT指令在8086中做了什么?

我无法找到一个明确的例子来理解

1. XLAT指令有什么作用?
2.我们为什么要使用它?(应用程序).

我的书描述XLAT

XLAT 简化了查找表的实现[1]

但我不明白作者在谈论哪个表格?
任何帮助都会很明显!

[1] 8088和8086微处理器.Walter A. Triebel
Avtar Singh

x86 assembly

-3
推荐指数
2
解决办法
1万
查看次数