我知道这是一个相当难以回答的问题,主要是因为有很多事情可能是错误的,很难把事情搞得一团糟.但我会尽可能多地提供信息; 希望这会有所帮助.
我开始使用D语言和Digital Mars D编译器编写自己的内核,并且在弄清楚如何生成可以重新定位的平面二进制文件之后遇到了很多麻烦,我终于提出了生成普通PE文件的想法.地址0xC0000000,并用字节0x90(NOP操作码)替换所有标头.这非常好用,我能够在屏幕上编写内容,设置分页,完全进入保护模式等,当然还有16位基于汇编的引导加载程序的帮助.
一切都很顺利,也就是说,我决定将D运行时库移植到我的内核中.我设法提取了库的一个子集并对其进行修改以使其编译到我的应用程序中.然后我运行了我的程序.(注意:我根本没有 使用该库;我的代码是在引导后执行的第一个代码 - 第一件事就是打印"Kernel"到屏幕上,之前没有调用运行时代码.)
AD数组(因此字符串,因为字符串只是一个char[])只不过是一个带有指针和大小成员的结构,因此在32位系统上它将是8字节大.有趣的是,当我运行我的程序时,结构的成员显示为零 - 也就是说,指针和大小都为零.(我通过将指针的值打印到屏幕以及长度成员来验证这一点 - 两者都是零.)一旦我删除了运行时的源代码(从未执行过),它们工作正常.
我把它缩小到两种可能性:
堆栈在某种程度上没有正确设置:我排除了这一点,因为没有运行时库,一切正常,我确认在我的代码之前没有通过反汇编文件执行其他代码.
PE文件部分很有趣:我检查过,并发现在运行时版本中有两个TLS(线程局部)变量.果然,当我让它们共享(而不是线程本地)时,我的代码工作了!但是,当我调用我在不同文件中编写的代码时,我的代码仍然会出现同样的问题 - 只有kernel.d启动文件才能正确处理字符串; 在其他文件中,数组再次为零.
现在,有没有人猜到为什么会发生这种情况?
如果需要更多信息,我很乐意发布.
谢谢!
我必须为我可以运行计算器的操作系统编写代码.它就像一个桌面计算器.为此,我正在阅读我已经完成第二阶段bootloader的breaknthorn操作开发系列引导加载程序处于实模式.在此之后,作者正在解释保护模式.我不想使用保护模式.我没有时间.所以我想通过使用bios中断在实模式下编写计算器.可能吗?我认为它可以写在引导程序的第二阶段(我不确定.)意味着我不必使用内核(我不确定).我不知道如何使用BIOS中断来处理键盘.任何人都可以给我一个链接来帮助我吗?如果我认为上面的任何错误是错误的,请纠正我.谢谢.
我使用gdb调试了小程序.
我有GRUB的源代码.GRUB的第二阶段是用C语言编写的.我可以使用gdb进行调试吗?
是否可以调试引导加载程序?如果是,那怎么样?
如何使用小代码空间减少十六进制ASCII字符转换的代码空间?
在嵌入式应用程序中,我有非常有限的空间(注1).我需要将字节从串行I/O转换为ASCII值'0'到'9'和'A'到'F'到通常的十六进制值0到15.此外,所有其他240种组合,包括' a'到'f',需要被检测到(作为错误).
图书馆的功能,例如scanf(), atoi(), strtol()是远太大而不能使用.
速度不是问题.代码大小是限制因素.
我现在的方法将256字节代码重新映射成256个代码,使得"0"到"9"和"A"到"Z"具有0到35的值.关于如何减少或不同方法的任何想法都是值得 赞赏的.
unsigned char ch = GetData(); // Fetch 1 byte of incoming data;
if (!(--ch & 64)) { // decrement, then if in the '0' to '9' area ...
ch = (ch + 7) & (~64); // move 0-9 next to A-Z codes
}
ch -= 54; // -= 'A' - 10 - 1
if (ch > 15) {
; // handle error …Run Code Online (Sandbox Code Playgroud) 为什么fw_setenv工具只为一种环境设置变量值?
我正在使用带有冗余环境的uboot(#define CONFIG_ENV_OFFSET 0xc0000、#define CONFIG_ENV_OFFSET_REDUND 0x100000),并且我将从linux设置uboot环境变量的值。有 fw_setenv/fw_printenv 工具可以执行此操作:
# fw_printenv rootfs
rootfs=mtd6
# fw_setenv rootfs mtd7
Run Code Online (Sandbox Code Playgroud)
检查它是否确实已设置:
# fw_printenv rootfs
rootfs=mtd7
Run Code Online (Sandbox Code Playgroud)
看起来没问题,但是重启系统并进入u-boot控制台后,rootfs变量的值是以前的值。uboot读取以前的值:
=> printenv
rootfs=mtd6
Run Code Online (Sandbox Code Playgroud)
然后我查看了 uboot env 放置的 mtd 设备的 hexdump 输出。
# hexdump -C /dev/mtd3 | 头-n 200
. . . . .
000000a0 65 6c 61 79 3d 35 00 62 61 75 64 72 61 74 65 3d |elay=5.baudrate=|
000000b0 31 31 35 32 30 30 00 72 6f 6f 74 66 73 3d …Run Code Online (Sandbox Code Playgroud) 我正在阅读这篇关于操作系统编程的精彩剧本
http://www.cs.bham.ac.uk/~exr/lectures/opsys/10_11/lectures/os-dev.pdf
在第 12 页上有一个简单的引导加载程序。
如果我理解正确,显示的代码是您必须在 NASM 中编写的代码才能让 BIOS 打印出字符。
我不明白的是:
它说
we need interrupt 0x10 and to set ah to 0x0e (to indicate tele-type mode)
and al to the ASCII code of the character we wish to print.
Run Code Online (Sandbox Code Playgroud)
但第一条指令是:
mov ah , 0x0e ;int 10/ ah = 0eh -> scrolling teletype BIOS routine
Run Code Online (Sandbox Code Playgroud)
我不明白该行的评论。为什么第一行代码没有说:
mov ah, 0xeh
int 0x10
Run Code Online (Sandbox Code Playgroud)
如果那是你需要做的?
感谢帮助!
集会:
[BITS 16]
global _start
_start:
mov ax, 0x07C0
mov ds, ax
mov si, hw
call print_string
jmp $
print_string:
mov ah, 0x0E
.char:
lodsb
cmp al, 0
je .exit
int 0x10
jmp .char
.exit: ret
times 0x100-($-$$) db 0
hw: db "Hello, World!", 0
times 510-($-$$) db 0
dw 0xAA55
Run Code Online (Sandbox Code Playgroud)
组装这个:
$ nasm file.asm -felf -o file.o
Run Code Online (Sandbox Code Playgroud)
然后将其与:
$ ld -melf_i386 -o file.bin file.o --oformat binary
Run Code Online (Sandbox Code Playgroud)
给出以下错误:
file.asm:(.text+0x6): relocation truncated to fit: R_386_16 against `.text'
Run Code Online (Sandbox Code Playgroud)
在稍微摆弄代码后,我发现更改mov si, hw …
计算机如何知道引导加载程序位于文件系统中的位置?所有操作系统和所有计算机(也许不是所有计算机,而是所有体系结构)之间是否存在指向引导加载程序的通用文件?我知道Raspberry Pi总是从SD卡的第一个分区加载bootcode.bin。PC 是否共享这样的公共文件?
有没有办法检查代码是否已解锁设备的引导加载程序?不是设备是否植根,只是引导加载程序状态。
当然有这个命令:
fastboot oem device-info
Run Code Online (Sandbox Code Playgroud)
但是在常规(非快速启动)模式下运行时,我需要能够在 C++(首选)或 Java 中做出相同的决定。
我正在制作引导加载程序,作为学习汇编的一种方式。我已经研究过使用部分来组织和优化我的代码,但是当我调用 printf 函数时,一件事不起作用。当我在 .data 部分中有 HELLO_WORLD 字符串时,它根本不想加载该字符串
; Set Code to run at 0x7c00
org 0x7c00
; Put into real mode
bits 16
; Variables without values
section .bss
; Our constant values
section .data
HELLO_WORLD: db 'Hello World!', 0
; Where our code runs
section .text
_start:
mov si, HELLO_WORLD ; Moves address for string into si register
call printf ; Calls printf function
jmp $ ; Jump forever
printf:
lodsb ; Load the next character
cmp al, 0 …Run Code Online (Sandbox Code Playgroud)