我知道它使用物理地址=段寄存器<< 4 +偏移寄存器.虽然这两个寄存器是16位,8086如何处理20位加法操作?
我不知道如何为 16 位实模式编译我的 C 内核。我尝试了各种编译器,但都没有运气。我的引导加载程序只是将原始扇区从软盘(我的内核位于磁盘上的第一个扇区之后)加载到物理内存地址 1000h:0000h,然后跳转到它。如何编译我的 C 内核以在 16 位实模式下工作?
我的基本内核:
void OSmain()
{
unsigned char *videoram = (unsigned char *) 0xb8000;
videoram[0] = 65; /* character 'A' */
videoram[1] = 0x07; /* forground, background color. */
while( 0 )
{
}
}
Run Code Online (Sandbox Code Playgroud)
我尝试过的编译器是 GCC、tinyCC 和 DMC。我的目标是获得一个可以跳转到开始执行的平面二进制文件。
我正在研究原始的x86实模式USB访问项目.这涉及自定义引导程序,第二阶段引导加载程序和一些简单的硬件驱动程序.
最终目标是提供一个引导产品,通过USB接口发送数据,通过USB接口接收数据,并将结果值打印到屏幕上.我有USB接入完成的一切.
我已经发现BIOS不提供对板载USB的访问.我经历了从osdevver到破碎的几十个网站.我甚至看过USB 2.0规范.
没有人,无处可提供有关在x86实模式下使用x86程序集直接访问USB根集线器的任何相关或有用信息,而无需通过某些预先存在的操作系统.
是否没有为USB Root Hub设置标准的IN/OUT端口?如果有,那么文档指定标准通信的确切位置允许软件告诉Hub要发送哪些数据以及将数据发送到哪个连接设备?
我正在编写在加载任何操作系统之前以实模式运行的代码。我的程序的一部分涉及将信息转储到视频显示,而标准 80x25 文本模式无法剪切它。
许多版本的 Windows 和其他操作系统在显示内核恐慌时似乎可以毫无困难地切换到更大的文本模式,我认为是 43 行。我知道更大的文本模式已经存在很长时间了,所以我希望至少有一种标准模式。
这里有一个相当大的 BIOS 视频模式列表:
http://www.columbia.edu/~em36/wpdos/videomodes.txt
不幸的是,相同的模式编号在芯片组之间的含义似乎有很大差异。
曾几何时,我似乎记得使用过一种名为 VESA BIOS 的东西以独立于设备的方式访问超级 VGA 图形模式,但我似乎还记得涉及必须加载的 DOS TSR。这不是一个选项这里因为 DOS 没有运行。
我正在寻找一种能够在最广泛的硬件上运行的模式,包括 VMware ESXi 中的虚拟视频适配器。更改模式的代码也需要紧凑,所以我希望一个简单的 Int 10h 就能做到这一点。
有任何想法吗?Windows 和 VMware 内核恐慌是如何发生的?
我对实际模式中的段大小有一个疑问,因为它们不能超过64K但可能小于 64K .我的问题是如何初始化这些段大小和基址?就像GDT和LDT处于保护模式一样.实模式段也可以重叠,不相交或相邻.像BIOS有一些保留区域用于特定的事情,如启动代码,视频缓冲区等装配程序需要做类似的事情吗?
作为学习练习,我为x86 bios系统编写了一个16位的引导程序。它在QEMU上似乎运行良好。我将其添加到用于旧式amd-turion计算机(x86_64)的驱动器上,当我尝试引导该计算机时,它将进入BIOS屏幕,然后黑屏上的光标闪烁。
我的问题是,QEMU的x86仿真器和绝对使用BIOS而不是UEFI的真实x86(64位)计算机之间可能有什么区别?我是否需要针对实际计算机而不是QEMU编写代码?是我将信息复制到驱动器的方式吗?计算机是否采用了某些硬件级别的安全性规定?
我知道它在VirtualBox上也不起作用。
看来加载第二阶段是有问题的(通过在真实硬件上成功地打印第一阶段的字符)。
我的第一阶段引导程序使用以下文件中的代码:
stage_one.asm
[bits 16]
[org 0x7c00]
LOAD_ADDR: equ 0x9000 ; This is where I'm loading the 2nd stage in RAM.
start:
xor ax, ax ; nullify ax so we can set
mov ds, ax ; ds to 0
mov sp, bp ; relatively out of the way
mov bp, 0x8000 ; set up the stack
call disk_load ; load the new instructions
; at …Run Code Online (Sandbox Code Playgroud) 我是操作系统开发的新手,我很好奇我在开发自己的bootloader时遇到的问题.我的操作系统将以汇编语言编写,并将以16位实模式运行.
我知道堆栈是什么,我的印象是它向下扩展到内存中.如果我错了,请纠正我.我知道如何从软盘中将基本内核加载到内存中,我不相信这是问题所在.
我遇到的问题是我不确定在哪里放置堆栈并将内核加载到内存中.我试过像这样创建我的堆栈,我遇到了问题:
mov ax, 0x0000
mov ss, ax
mov sp, 0xFFFF
Run Code Online (Sandbox Code Playgroud)
我正在加载我的内核0x1000:0x0000.当我推送并稍后在我的函数中弹出易失性寄存器时print,我的内核只是第二次挂起call print.这是我的print功能:
print:
push ax
push bx
push cx
mov al, [si]
cmp al, 0
je p_Done
cmp al, 9
je p_Tab
mov ah, 0xE
int 0x10
cmp al, 10
je p_NewLine
p_Return:
inc si
jmp print
p_Tab:
xor cx, cx
p_Tab_Repeat:
cmp cx, 8
je p_Return
mov ah, 0xE
mov al, " " …Run Code Online (Sandbox Code Playgroud) 因此,目前我正在将屏幕缓冲区(screenbuffer db 64000 DUP(0))复制到视频内存(从 0a0000h 开始)以清除屏幕。但我想知道像这样再次设置视频模式是否更好:
mov ax, 13h
int 10h
Run Code Online (Sandbox Code Playgroud)
这似乎也清除了屏幕。
或者有没有更好的方法来清除屏幕?
有没有办法在实模式下列出BIOS驱动器索引(例如0x80,0x81 ......)?
我没有找到任何负责列出驱动器号码的中断!!
正如标题中所解释的,我需要让这段代码能够做与仅使用 16 位相同的事情,但将 .386 添加到代码中,以便我可以使用 32 位寄存器。但是当我现在添加 .386 时,我的代码没有打印任何内容,不知道如何解决这个问题。我的 mov as 有问题吗,@data 还是我需要添加其他东西?我正在使用 TASM
TITLE Programa de prueba(prueba.asm)
.386
.model small
.stack
.data
escoga db 10,13,7, 'Escoga la operacion: 1. x and y, 2. x or y, 3. not x, 4. x xor y, 5. terminar:
', '$'
digite1 db 10,13,7, 'Digite el primer numero hexadecimal: ', '$'
digite2 db 10,13,7, 'Digite el segundo numero hexadecimal: ', '$'
Yval db "Enter Y hexadecimal value: ",0
resultStr db "The result is: …Run Code Online (Sandbox Code Playgroud)