我已经在Assembly中完成了一部分操作系统,但是现在我也想为其构建一个自举程序,而不是使用GRUB。当我在Assembly中开发测试操作系统时,我记得我是这样启动的:
org 0x7c00
bits 16
; OS Kernel Here
times 510 - ($-$$) db 0
dw 0xAA55
Run Code Online (Sandbox Code Playgroud)
这我已经知道了。现在,我要使用它并执行“真实”操作系统,它将是一个* .bin文件,写入软盘的第二个扇区。那我想知道一点
我正在制作一个自定义操作系统.我有两个nasm文件:
boot.asm:
[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
INT 0x13
JMP $ ;infinite loop
TIMES 510 - ($ - $$) db 0 ;fill the rest of sector with 0
DW 0xAA55 ; add boot signature
Run Code Online (Sandbox Code Playgroud)
start.asm:
[BITS 16]
MOV AL, 72
CALL PrintCharacter
MOV AL, 101
CALL PrintCharacter
MOV AL, 108
CALL PrintCharacter
MOV AL, 108 …Run Code Online (Sandbox Code Playgroud) 我正在尝试编写一个bootloader.我想编译一些C代码,以便引导加载程序可以将其加载到内存中并跳转到那里.
我有两个问题:
我听说可以使用内置的bootloader和你编写的内核为PIC单片机编写一个操作系统.我也听说它必须是RTOS.
谢谢!
最近我在x86 Assembly中编写了一个bootloader.引导程序现在没有做任何特殊的事情,但我打算用这个引导加载程序加载我自己的内核.我能够将引导程序写入我的FAT32格式的USB闪存驱动器,它将由BIOS正确加载.
如何通过BIOS和UEFI使USB闪存驱动器可启动?
我的自定义引导加载程序中的代码将内存中的512字节缓冲区的内存复制0x8E00到高内存中0x100000.这在某些计算机上工作正常,并且在其他计算机上崩溃(我认为是三重故障).此代码在Bochs x86仿真器中也可以正常工作.
我尝试用一个rep movsb设置esi和edi相应的地址替换自定义段偏移复制循环,并在某些计算机上发现这也是错误.这有什么理由会失败吗?
Bootload.asm:
; Portions of this code are under the MikeOS license, as follows:
;
; ==================================================================
; Copyright (C) 2006 - 2014 MikeOS Developers -- http://mikeos.sourceforge.net
;
; All rights reserved.
;
; Redistribution and use in source and binary forms, with or without
; modification, are permitted provided that the following conditions are met:
;
; * Redistributions of source code must retain …Run Code Online (Sandbox Code Playgroud) 我使用了第一个扇区中的所有内存,现在我想在第二个扇区(第二个阶段)中存储一个新的变量字符串并打印它.例如:
hello db 'Hello World'
Run Code Online (Sandbox Code Playgroud)
新字符串应该在另一个扇区中(因为第一个扇区中没有更多的内存).我用INT 13h做了这个,啊= 2读取第二个磁盘扇区到地址900h:0000.我将变量存储hello在该扇区以及要打印的代码中.当我在这样的代码中使用INT 10h/ah = 13h时,它无法打印我的字符串:
mov ax, 7c0h
mov es, ax
mov bp, hello
mov ah,13h ; function 13 - write string
mov al,01h ; attrib in bl, move cursor
mov bl,0bh ; attribute - magenta
mov cx,30 ; length of string
mov dh,1 ; row to put string
mov dl,4 ; column to put string
int 10h ; call BIOS service
Run Code Online (Sandbox Code Playgroud)
当变量位于第一个扇区时,它打印得很好,但是当我将它存储在第二个扇区时,它不会打印,即使我这样做:
mov ax, 900h …Run Code Online (Sandbox Code Playgroud) 我发现通常程序员在启动加载程序的第一行就对寄存器(有时是段)进行修正,并且他们通常会为此建议。例如:
inc cx
dec bx
inc bp
dec di
xor ax, ax
Run Code Online (Sandbox Code Playgroud)
我不知道我知道的是:BIOS在引导过程中清除了所有寄存器。
在引导加载程序中初始化寄存器和段是个好习惯吗?如果是,默认寄存器,段和指针值是什么(可能取决于芯片组)?
关于标题类似的stackoverflow有很多问题。我读了所有这些文章,但没有一个回答我的问题。这就是为什么我打开这个问题。
我正在用汇编器和C创建一个操作系统。我发现必须将C代码编译为二进制格式,提取文本部分并将其保存为文件,然后将其转换为ISO,然后将其安装到diskete的虚拟光驱中,然后在VirtualBox中加载我的操作系统。因此,这是我要避免的许多工作。我不想每次都将二进制文件转换为ISO。
因此,我决定将操作系统的二进制计算机代码放入虚拟硬盘驱动器(VDI文件),然后将其设置为引导顺序的顶部并加载,而不是从虚拟光盘驱动器加载ISO。
我正在研究VDI工作原理,发现它通常是按名称分配的,并且只存储数据的开头。因此,的开头VDI代表标题,其余的代表存储在虚拟驱动器上的实际数据。因此,我发现数据从某个地址开始(就我而言,它是0x00200000从VDI文件的开头开始)。
然后,我基本上VDI使用pattern 从该地址填充到文件末尾55 AA。因此,我想它现在意味着磁盘是可引导的(因为第一个扇区的末尾仍是签名55 AA)。
我启动了虚拟机,它说:
找不到可启动媒体!系统停止
有什么办法解决这个问题?为什么我的虚拟磁盘仍然无法启动?
这是实际的VDI文件:1.vdi
所以我想在bootsector中添加填充.比方说,目前只有一个无限循环:jmp ..扇区需要512字节长.此外,0xaa55需要在最后添加的幻数.
jmp .
.skip 508, 0
.word 0xaa55
Run Code Online (Sandbox Code Playgroud)
但是,如果我想打印一些但不想将所有字节计算到适当大小的内容,该怎么办?
在Intel/NASM中,语法是:
; print something
times 510-($-$$) db 0
dw 0xaa55
Run Code Online (Sandbox Code Playgroud)
但在AT&T语法中呢?好了,循环(.rept)在这里不起作用,因为这里.不需要给出绝对值.我们和.skip/ 有同样的问题.space,他们也需要一个绝对值.
是否有使用某种循环/ .align/ .skip/ etc 添加填充的方法?
编辑:我as用来构建和链接,ld -Ttext 0x7c00 --oformat binary直到yasmAT&T语法足够稳定.