我正在编写一个启动加载程序,我已经掌握了大部分细节,但我不确定为什么有些启动加载程序会在开始大量执行之前将它们重新定位在内存中.
有谁能解释一下?
此行为的一个示例是原始的v0.01 Linux内核引导加载程序,其中包含以下注释:
boot.s由bios-startup例程加载到0x7c00,并自行移动到地址0x90000,并跳转到那里.
我设置了Kamikaze工具链(来自openwrt),并为AMCC PPC405ex kilauea参考板编译了Linux 2.6.30.x内核.但是,出于某种原因,我在uBoot中做错了,因为我无法从squashfs图像运行内核.图像在tftp上加载正常并解压缩,但控制台输出无法启动.
我没有更改Linux内核命令行,它看起来很好(console=ttyS0,115200 root=/dev/mtdblock).我也有点困惑uboot中的fdt是什么?
我不完全确定它是否真的属于stackoverflow,但是这又不是一个真正的superuser.com问题(因为这与开发环境有关,它肯定是编程相关的,即使不是一个编程问题)
以下站点"编写引导扇区代码"提供了一个代码示例,可在系统引导时将"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) 我一直在看这个代码,我对rep cmpsb线感到困惑.
.LOOP:
push cx
mov cx, 0x000B ; eleven character name
mov si, ImageName ; image name to find
push di
rep cmpsb ; test for entry match
pop di
je LOAD_FAT
pop cx
add di, 0x0020 ; queue next directory entry
loop .LOOP
jmp FAILURE
Run Code Online (Sandbox Code Playgroud)
我明白它会重复cmpsb cx次,但是如何比较这两个字符串呢?比如说比较"Hey\0"和"hey\0",这个循环比较4个字符串.第一个字符是不同的,因此将设置EFlags寄存器.但是,重复cmpsb指令,下一个字符将是相同的.我可能误解了cmpsb是如何工作的,但看起来这个循环没有正确地比较两个字符串.这个循环实际上有效吗?
我正在为Stellaris LM3S1607芯片开发一个引导加载程序.我正在使用Keil MicroVision4 C编译器.我们的想法是创建2个独立的固件,一个将更新另一个.在firmware1中,我下载了firmware2文件,并将其写入地址0x3200的闪存中.直到这里它才有效.我还验证了数据写入闪存是否正确.现在我在flash中有两个应用程序.一个是我的uip引导装载程序,而seoncd就是我的主要项目.我想知道如何从第一个程序跳转到位于0x3200的第二个程序.
如果有人能帮我跳,那就太好了.谢谢
我对这两个文件的启动配置非常困惑.他们似乎在做同样的事情,我不明白为什么我需要或者.
如果我使用uEnv.txt,我将其设置为
bootargs=console=ttyS0,115200 root=/dev/mmcblk0p2 rootwait panic=10 ${extra}
aload_script=fatload mmc 0 0x43000000 script.bin;
aload_kernle=fatload mmc 0 0x48000000 uImage; bootm 0x43000000 - 0x48000000;
uenvcmd=setenv run aload_script aload_kernel
Run Code Online (Sandbox Code Playgroud)
或者,我可以创建boot.cmd:
setenv bootargs console=console=ttyS0,115200 root=/dev/mmcblk0p2 rootwait panic=10 ${extra}
fatload mmc 0 0x43000000 script.bin
fatload mmc 0 0x48000000 uImage
bootm 0x48000000
Run Code Online (Sandbox Code Playgroud)
他们都工作......
在学习装配的过程中,我正在编写一个操作系统.我已成功编写了将第二个512字节扇区附加到初始512字节引导加载程序所需的代码:
%define KBDINT 0x16
%define VIDINT 0x10
%define DISKINT 0x13
%define TTYOUT 0x0E
%define VIDMODE 0x0000
%define NUL 0x00
%define CR 0x0D
%define LF 0x0A
%define START 0x7C00
%macro PRINT 1
mov si, %1
call print
%endmacro
bits 16 ; 16 bit real mode
org START ; loader start in memory
start: jmp main
print: jmp .init
.loop: mov bx, VIDMODE
mov ah, TTYOUT
int VIDINT
inc si
.init: mov al, [si]
cmp al, NUL
jne .loop
ret
main: cli …Run Code Online (Sandbox Code Playgroud) 我一直在用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) 我目前正在编写一个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中.
编辑:如果可能的话,某些方法来验证堆栈是否在正确的位置也非常有用.
我在程序集中编写了一个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)