标签: bootloader

实模式组装:在引导时不使用INT指令将字符打印到屏幕

以下站点"编写引导扇区代码"提供了一个代码示例,可在系统引导时将"A"打印到屏幕上.从我一直在阅读的不是你必须使用INT操作码让BIOS做某些事情?以下代码如何从上面引用的站点工作而不使用中断?代码的哪一部分实际告诉硬件将"A"打印到屏幕上?

有问题的代码:

.code16
.section .text
.globl _start
_start:
  mov $0xb800, %ax
  mov %ax, %ds
  movb $'A', 0
  movb $0x1e, 1
idle:
  jmp idle 
Run Code Online (Sandbox Code Playgroud)

附加原始问题

如果我使用以下代码,BIOS调用是否会为我写入文本缓冲区?缓冲区从地址0xb800开始?

   # Author: Matthew Hoggan
   # Date Created: Tuesday, Mar 6, 2012
   .code16                        # Tell assembler to work in 16 bit mode (directive)
   .section .text
   .globl _start                  # Help linker find start of program
   _start:
       movb $0x0e,     %ah        # Function to print a character to the screen                 
       movb $0x00,     %bh        # Indicate the page …
Run Code Online (Sandbox Code Playgroud)

assembly bios bootloader

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

如何在Stellaris中的程序之间跳转

我正在为Stellaris LM3S1607芯片开发一个引导加载程序.我正在使用Keil MicroVision4 C编译器.我们的想法是创建2个独立的固件,一个将更新另一个.在firmware1中,我下载了firmware2文件,并将其写入地址0x3200的闪存中.直到这里它才有效.我还验证了数据写入闪存是否正确.现在我在flash中有两个应用程序.一个是我的uip引导装载程序,而seoncd就是我的主要项目.我想知道如何从第一个程序跳转到位于0x3200的第二个程序.

如果有人能帮我跳,那就太好了.谢谢

c embedded bootloader keil

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

错误:无法识别的指令 [ORG]

我试图编写一个引导加载程序以在 dos-box 中使用我编写了以下代码

[BITS 16]   ;tell the assembler that its a 16 bit code
[ORG 0x7C00]    ;Origin, tell the assembler that where the code will
;be in memory after it is been loaded

JMP $       ;infinite loop

TIMES 510 - ($ - $$) db 0   ;fill the rest of sector with 0
DW 0xAA55           ; add boot signature at the end of bootloader
Run Code Online (Sandbox Code Playgroud)

我试图通过以下命令使用 nasm 组装它

nasm -f elf myfile.asm
Run Code Online (Sandbox Code Playgroud)

然后我看到那个错误

错误:无法识别的指令 [ORG]

我使用的是ubuntu 14.04 LTS,nasm的版本是2.10.09

assembly nasm bootloader dosbox

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

什么会在Int 13h中导致磁盘读取错误?

我一直在用NASM编写一个测试程序,该函数用于int 13h从引导磁盘读取扇区,但每次使用sudo qemu-system-i386 load_disk.bin运行汇编程序时,它都会为我提供以下输出:

磁盘读取错误!磁盘读取错误!磁盘读取错误!*磁盘读取错误!*磁盘读取错误!*

如果设置了进位标志(CF),则可以预期。我一直在寻找答案的几天,并尝试了许多不同的解决方案(跳转到ES:BX之后jc test,将启动驱动器保存在DL...中),但似乎没有任何效果。
这是我的程序:

[bits 16]                       ;real mode 
[org 0x7c00] 

mov [DISK], dl                  ;save boot drive value 

xor ax, ax                      ;setting up stack 
cli 
mov ss, ax 
mov sp, 0x7c00 
sti 

mov di, 5       `               ;counter for number of tries 
read_disk:                      
mov ah, 0x00                    ;resetting disk 
int 0x13 
mov bx, 0x9000                  ;data buffer 
mov es, bx 
mov bx ,0x0000                   
mov ah, 0x02                    ; function number …
Run Code Online (Sandbox Code Playgroud)

assembly bios nasm bootloader x86-16

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

如何在i386中正确设置ss和sp寄存器

我目前正在编写一个bootloader并且已经开始耗尽我的512B空间,所以我开始在512B之外编写更多代码并打算使用bootloader将其读入内存.我添加到我的代码的末尾:

stack_start:
    resb 4096
stack_end:
Run Code Online (Sandbox Code Playgroud)

这样我就可以在操作系统代码的末尾为堆栈分配空间.目前在我的引导程序中,我在引导加载程序之后为堆栈分配4KiB,使用以下我从这里获取:

mov ax, 07c0h           ; 4K stack space after the bootloader -- code is running at 0x07c0
add ax, 288             ; (4096 + 512)/16 bytes per paragraph (288 paragraphs)
mov ss, ax
mov sp, 4096            ; moves the stack pointer
Run Code Online (Sandbox Code Playgroud)

但是现在我需要一种方法来将堆栈分配到我的操作系统代码的末尾,这将是一个未知的大小.

我相信我理解这些是如何建立的 - 类似于使用es,我ss用于扩展寻址空间,但我找不到任何能够很好地解释我的知识水平的东西.我也不确定如何正确设置它以使我的堆栈结束.我用过:

mov ax, stack_start
mov ss, ax
mov sp, 4096
Run Code Online (Sandbox Code Playgroud)

并没有遇到过错误; 但是我想知道这是否正确,或者我是否真的只为堆栈分配了一些空间,同时用更高的地址填充内存.

ss实际上如何运作?我如何使用它并sp在代码末尾为堆栈分配内存?

这是在使用nasm的i386中.

编辑:如果可能的话,某些方法来验证堆栈是否在正确的位置也非常有用.

assembly operating-system nasm bootloader i386

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

为什么我的根目录没有被加载?(FAT12)

我在程序集中编写了一个stage 1 bootloader,我试图将FAT12文件系统加载到内存中,以便我可以加载我的stage 2 bootloader.我已经设法将FAT加载到内存中,但是我很难将根目录加载到内存中.

我目前正在使用作为参考,并产生了以下内容:

.load_root:
    ;es is 0x7c0
    xor dx, dx              ; blank dx for division
    mov si, fat_loaded      ; inform user that FAT is loaded
    call print
    mov al, [FATcount]      ; calculate how many sectors into the disk must be loaded
    mul word [SectorsPerFAT]
    add al, [ReservedSectors]
    div byte [SectorsPerTrack]
    mov ch, ah              ; Store quotient in ch for cylinder number
    mov cl, al              ; Store remainder in cl for sector number

    xor dx, dx …
Run Code Online (Sandbox Code Playgroud)

x86 assembly nasm bootloader fat

5
推荐指数
2
解决办法
353
查看次数

为什么 ROM 的闪存扇区在起始地址处较小?

最近经常使用闪存 ROM,我发现在芯片的内部闪存以及外部 SPI 闪存设备中,扇区的大小通常都是这样的:

STM32F405/415 的闪存布局

我很好奇为什么起始地址空间的扇区比后面的地址小。我怀疑使用引导加载程序之类的东西会更方便。由于引导加载程序通常小于 128k,因此这将允许引导加载程序写入前 2 或 3 个扇区。这使得主空间应用程序有更多的扩展空间,因为要对其进行编程,我们需要从新扇区的开头开始。如果我们只有 128k 大小的扇区,那么我们基本上就会浪费128k - bootloader_size空间。

我的怀疑正确吗?或者这样做还有其他原因吗?真的很想知道这里的设计决策是什么。

embedded firmware flash-memory bootloader rom

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

kexec转换为ELF x86_64二进制文件后,页表的状态是什么?

我将kexec压缩为一个二进制文件,并将其编写为x86_64 ELF。运行正常。

由于它是64位二进制文​​件,因此我知道处理器必须处于64位长模式。这需要使用分页,所以我知道必须打开分页。

我的问题是,这些页表的状态是什么?是否有某些区域(例如我加载的二进制文件)可以保证进行身份映射?是否所有可用的RAM标识都已映射?由于启用了分页,因此页面在哪里?

执行完kexec'之后,我想对整个地址空间进行身份映射。为此,我需要在我知道物理地址的地址处构建一些页表结构,然后将该结构的地址写入CR3。

如果我知道加载到内存中的小精灵二进制文件是身份映射的,则可以在其中静态构建页表,然后进行无缝切换。如果kexec之后没有标识映射的页面,则需要关闭分页,退出long模式,然后进行设置,然后重新进入long 64位模式。

谢谢!

linux elf linux-kernel bootloader

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

在引导加载程序启动时读取堆栈安全吗?

背景

我正在尝试制作一个适用于两种架构的引导加载程序:x86 和 PDP-11。主操作系统是为 PDP-11 兼容机器编写的,但从 x86 启动也应该可以工作,启动模拟器。

AFAIK,如果最后两个字节是, x86 加载第一个磁盘扇区0x7c00并跳转到那里。相反,如果第一个命令是且最后两个字节是 ,则 PDP-11 兼容机将第一个扇区加载到(八进制)并执行它。然而,由于一些硬件细节的原因,加载的数据实际上是颠倒的——例如,x86 读取的数据,另一台机器读取的数据。在这种情况下,这在某种程度上是一个功能,因为如果我制作最后两个字节,它们将适用于两台机器。0x55 0xaa0o20000NOP0xaa 0x550x120xed0x55 0xaa

总之,PDP-11兼容机需要前两个字节包含NOP命令,即0o000240,或0x00a0。数据被反转,因此 x86 实际上会读取0xff5f

问题

0x5f是 x86 中的真实命令。不幸的是,它是pop di. AFAIK,spss值都没有指定,所以这个命令读取谁知道什么。

我的问题是:

  • 在实践中,我可以假设它们要么指向有效的堆栈,要么都设置为某个占位符,例如0x0000:0x0000or 0xffff:0xffff
  • 可能ss:sp指向读取不安全的内存映射硬件寄存器?如果是的话,如果我读了它们,会发生什么更糟糕的事情?我不想意外损坏笔记本电脑。
  • 可能ss:sp指向不可用的内存,即可能pop di触发总线错误?如果是,BIOS 将如何从中恢复,即它将重新启动、显示消息或执行其他操作?

x86 assembly bootloader x86-16 stack-pointer

5
推荐指数
0
解决办法
130
查看次数

从引导加载程序跳转到应用程序之前设置堆栈指针

我正在为 Nucleo-F429ZI 编写引导加载程序。我有两个不同的 STM32 项目,一个用于引导加载程序本身,另一个用于从引导加载程序跳转的应用程序。

引导加载程序的链接器脚本

MEMORY
{
  CCMRAM    (xrw)    :  ORIGIN = 0x10000000,   LENGTH = 64K
  RAM    (xrw)    :     ORIGIN = 0x20000000,   LENGTH = 32K
  FLASH    (rx)    :    ORIGIN = 0x8000000,   LENGTH = 32K
}   
Run Code Online (Sandbox Code Playgroud)

应用程序的链接器脚本

_estack = ORIGIN(RAM) + LENGTH(RAM);
MEMORY
{
  CCMRAM    (xrw)    :  ORIGIN = 0x10000000,   LENGTH = 64K
  RAM    (xrw)    :     ORIGIN = 0x20000000,   LENGTH = 192K
  FLASH    (rx)    :    ORIGIN = 0x8008000,   LENGTH = 64K
}   
Run Code Online (Sandbox Code Playgroud)

我没有忘记设置应用程序的闪光偏移。

system_stm32f4xx.c(在应用程序项目中)

#define VECT_TAB_BASE_ADDRESS   FLASH_BASE   // 0x8000000
#define …
Run Code Online (Sandbox Code Playgroud)

c arm stm32 bootloader cortex-m

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