我正在使用准系统教程作为我正在研究的操作系统的基础,它似乎是一个较旧的教程:它已经将内核编译成软盘映像,然后用GRUB加载它.
基本上,我仍然想使用GRUB,但我想让我的操作系统从CD运行.主要原因是我实际上没有可用的真正软盘驱动器(我目前在VirtualBox中测试),因此我无法在真实硬件上测试我的操作系统.
我一直在网上闲逛,我可以找到许多从软盘映像创建可引导CD的实用程序,但这些似乎都需要一个真正的软盘驱动器,而且它并不是我真正想要的.我希望能够在我的制作步骤中最终得到可引导的CD,而不需要首先将图像放在软盘上,这看起来毫无意义.
我想回答这个问题的简单方法是:如何设置GRUB以从CD读取我的内核映像?我需要一个特殊的工具来从Windows执行此操作吗?(内核无法编译自己,这不适合于looong)
谢谢!
我已经grub v1.98安装并在拆解MBR后发现以下我不理解的代码片段:
xor ax,ax
mov [si+0x4],ax
inc ax
mov [si-0x1],al
mov [si+0x2],ax
mov word [si],0x10
mov ebx,[0x7c5c]
mov [si+0x8],ebx
mov ebx,[0x7c60]
mov [si+0xc],ebx
mov word [si+0x6],0x7000
mov ah,0x42
int 0x13
Run Code Online (Sandbox Code Playgroud)
看来这段代码试图设置阶段1.5代码的磁盘地址,然后加载并运行它.但是,我怎么能弄清楚它试图读取哪个物理块?更重要的是,舞台1.5代码的目的地是什么?0x7000?
我指的是Windows 7的MBR,其中加载了后续的启动代码0x7c00.鉴于MBR首先被装载在地址0x7c00,它包含了一段代码从复制MBR 0x7c00到0x0600,然后分支到0x0600在壳体的原代码损坏.将加载阶段1.5代码解决0x7000冲突的原始代码?更重要的是,我还发现:
jmp short 0x65
nop
sar byte [si+0x7c00],1
mov es,ax
mov ds,ax
mov si,0x7c00
mov di,0x600
mov cx,0x200
cld
rep movsb
push ax
push word 0x61c
retf
Run Code Online (Sandbox Code Playgroud)
在MBR的开头.似乎代码尝试执行与Windows 7的MBR中相同的操作来将原始MBR复制0x7c00到0x0600 …
我使用gdb调试了小程序.
我有GRUB的源代码.GRUB的第二阶段是用C语言编写的.我可以使用gdb进行调试吗?
是否可以调试引导加载程序?如果是,那怎么样?
从过去的一周开始,我很困惑的问题是,当第二阶段处于复杂的文件系统时,grub第一阶段启动加载器(仅446字节)如何能够搜索第二阶段!它如何定位第二阶段?
当windows和linux的复杂分区方案到位,并且linux系统完全在扩展分区中时,第1阶段如何找到第2阶段?即使是1.5阶段?
所有grub教程都浏览了这个重要部分.我通过互联网搜索但找不到任何解释这个的东西.可悲的是,我不是集会程序员.
我想要了解启动过程中硬盘的哪些扇区(以及大致如何)的复杂启动过程.*请指出一个很好的资源或在这里回答.它将极大地帮助我明智地玩grub.*
搜索的一些资源:
我试图按照这里的说明构建一个简单的操作系统内核:http://mikeos.sourceforge.net/write-your-own-os.html
除了从软盘启动,我想创建一个基于grub的ISO映像并在模拟器中启动多重启动CD.对于多引导头,我已将以下内容添加到该页面上列出的源:
MBALIGN equ 1<<0 ; align loaded modules on page boundaries
MEMINFO equ 1<<1 ; provide memory map
FLAGS equ MBALIGN | MEMINFO ; this is the Multiboot 'flag' field
MAGIC equ 0x1BADB002 ; 'magic number' lets bootloader find the header
CHECKSUM equ -(MAGIC + FLAGS) ; checksum of above, to prove we are multiboot
section .multiboot
align 4
dd MAGIC
dd FLAGS
dd CHECKSUM
Run Code Online (Sandbox Code Playgroud)
我正在做以下事情来创建图像:
nasm -felf32 -o init.bin init.s
cp init.bin target/boot/init.bin
grub2-mkrescue -o …Run Code Online (Sandbox Code Playgroud) 我的问题的原因是,Starman似乎相信GRUB Legacy作者的解释(请参阅以下无法解释的代码:
7C4B EA507C0000 JMP 0000:7C50 ; Long Jump to the next instruction
; because some bogus BIOSes jump to
; 07C0:0000 instead of 0000:7C00.
Run Code Online (Sandbox Code Playgroud)
当我执行Intel指定的算法在第一个存储器参考上构造有效地址时,我将07C0:乘以16(实际上将其移位4位或半个字节).然后我添加偏移量:0000并得到小数地址31,744.
如果我左移第二个存储器的段参考四位我仍然有0000:并且偏移:7C00仍然寻址位置31,744.所以我的直觉反应是这个GRUB Legacy引导扇区代码的作者拉我们的腿.无论任何BIOS的内存引用形式如何,如果有效地址计算为十进制31,744,那么看起来这个Long Jump正在解决没有问题.
假设代码的作者只是以一种看起来与正确的物理位置相同的方式表达虚假的物理内存位置,我开始考虑如何处理将一个发送到错误地址的BIOS.五字节跳远似乎不是任何解决方案.五个NOP将用于相同的目的(事实上,简单地开始提前五个字节的引导扇区代码并且消除长跳跃将具有与到下一个指令的长跳转相同的效果).
如果BIOS跳转到正确的位置(7C00),没问题.如果BIOS跳转到7C00以上的位置,则7C00上没有加载的代码可以解决该问题.如果BIOS跳转到7C00和7C4B之间的位置,那么存储在该区域中的数据(或者解释为缺少字节的数据)可能会导致崩溃.如果BIOS跳转到7C4B,则TEST指令将被覆盖(通过跳转),并且将根据BIOS中执行的最后一次数学运算执行JNZ至7C54.
对于低于7C4B的BIOS跳转,再次错误对齐的指令可能会导致崩溃.祝你好运,引导扇区代码的某些部分将被执行.这种执行的结果将取决于BIOS确实跳到的"虚假"内存地址.那么这个启动扇区代码的作者是如何用一个关于"虚假的BIOS跳到错误的位置"的故事拉我们的腿?
我在Luke Luo的BLOG中注意到,GRUB2引导扇区虽然与GRUB Legacy引导扇区不同,却保留了这种莫名其妙的跳远.因此,如果GRUB Legacy引导扇区的原作者对我们开玩笑,这是一个相当成功的笑话(它完全重写了GRUB后幸存下来).我选择相信一个关于一些未命名的BIOS的令人难以置信的断言以及解决这样一个问题的解决方案,这个问题似乎实际上什么也没做,或者相信原始引导扇区的作者对我们开玩笑.
Luke Luo似乎接受了向7C66和7C67写入NOP指令,作为他没有跳到错误位置的BIOS的证据.由Linux Mint 13写入我的闪存驱动器的GRUB2引导扇区具有相同的NOP.然而写入我的笔记本电脑硬盘驱动器的GRUB2引导扇区(由Debian Etch提供)与7C66和7C67的下一条指令短暂跳转(注意Luke Luo向我们展示了原始引导扇区存储在/ usr/lib/grub/i386-pc/boot.img具有Debian值).两种选择都具有相同的效果(执行它们之后的指令),因此两个引导扇区都有效.在引导扇区中我没有预期的效率,其中只有大约450个字节可用于必须加载另一个扇区并执行它的代码(包括错误消息,用于当该简单操作出现问题时以及该字节的8字节地址时部门本身).
所以我错过了什么,或者我确定了应该从GRUB引导扇区中删除的kludge(为更有意义的代码腾出空间)?
我正在尝试为80386处理器制作一个小内核,主要用于学习目的,并希望获得可用RAM的完整内存映射.
我已经读过,在GRUB的帮助下,直接查询BIOS是可能的,也是更好的.
任何人都可以告诉我该怎么办?
特别是,为了在实模式下使用bios功能,我们使用bios中断并在某些寄存器中获得所需的值,当我们想要使用GRUB提供的函数时,实际的等效方式是什么?
我写了一个简单的内核,试图将两个字符写入帧缓冲区.
如果我在内核中定义一个字符串文字,我在启动时会得到以下输出:
Booting 'os'
kernel /boot/kernel.elf
Error 13: Invalid or unsupported executable format
Press any key to continue...
Run Code Online (Sandbox Code Playgroud)
否则,如果我定义了两个字符,我得到以下内容(注意输出开头的'ab'):
abBooting 'os'
kernel /boot/kernel.elf
[Multiboot-elf, <0x100000:0x201:0x0>, <0x101000:0x0:0x1000>, shtab=0x102168,
entry=0x1001f0]
Run Code Online (Sandbox Code Playgroud)
我在装配中写了装载器:
global loader ; the entry symbol for ELF
MAGIC_NUMBER equ 0x1BADB002 ; define the magic number constant
FLAGS equ 0x0 ; multiboot flags
CHECKSUM equ -MAGIC_NUMBER ; calculate the checksum
; (magic number + checksum + flags should equal 0)
KERNEL_STACK_SIZE equ 4096 ; size of stack in bytes
section …Run Code Online (Sandbox Code Playgroud) GRUB 脚本中是否可以进行文件名通配符扩展?
就像是:
for i in directory/*; do echo $i; done
Run Code Online (Sandbox Code Playgroud)
我的目的是让 GRUB 加载位于某些目录中的不同 cfg 文件。
在具有AMD64架构的UEFI系统上使用Grub 2.02.我想将grub的超时计数器从1秒间隔更改为1/10秒或1/100秒间隔.原因是使gfxmenu循环进度倒计时不那么"波涛汹涌".下面的引导GIF显示循环1秒"块"中的5秒倒计时:
成功更改源代码并重新编译后,/etc/default/grub将更改如下:
GRUB_TIMEOUT=25.GRUB_TIMEOUT=250.我已经下载了这里描述的源:如何从源代码构建grub2 bootloader并使用qemu模拟器测试它并花时间浏览源文件.但是有477k行搜索:
~/src/grub-2.02$ wc -l **/*
20 asm-tests/arm.S
18 asm-tests/i386-pc.S
4 asm-tests/i386.S
11 asm-tests/mips.S
8 asm-tests/powerpc.S
(... SNIP ...)
115 util/spkmodem-recv.c
477316 total
Run Code Online (Sandbox Code Playgroud)
我在Ask Ubuntu中做了很多bash项目,但这将是我的第一个C/Assembler Linux项目.作为一个"新手",我的想法是:
请注意,只有第一个问题是相关的.其他问题是作者选择更详细的答案.