标签: bootloader

D中的我的OS内核:某些嵌入式字符串不起作用

我知道这是一个相当难以回答的问题,主要是因为有很多事情可能是错误的,很难把事情搞得一团糟.但我会尽可能多地提供信息; 希望这会有所帮助.

我开始使用D语言和Digital Mars D编译器编写自己的内核,并且在弄清楚如何生成可以重新定位的平面二进制文件之后遇到了很多麻烦,我终于提出了生成普通PE文件的想法.地址0xC0000000,并用字节0x90(NOP操作码)替换所有标头.这非常好用,我能够在屏幕上编写内容,设置分页,完全进入保护模式等,当然还有16位基于汇编的引导加载程序的帮助.

一切都很顺利,也就是说,我决定将D运行时库移植到我的内核中.我设法提取了库的一个子集并对其进行修改以使其编译到我的应用程序中.然后我运行了我的程序.(注意:我根本没有 使用该库;我的代码是在引导后执行的第一个代码 - 第一件事就是打印"Kernel"到屏幕上,之前没有调用运行时代码.)

AD数组(因此字符串,因为字符串只是一个char[])只不过是一个带有指针和大小成员的结构,因此在32位系统上它将是8字节大.有趣的是,当我运行我的程序时,结构的成员显示为零 - 也就是说,指针和大小都为零.(我通过将指针的值打印到屏幕以及长度成员来验证这一点 - 两者都是零.)一旦我删除了运行时的源代码(从未执行过),它们工作正常.

我把它缩小到两种可能性:

  1. 堆栈在某种程度上没有正确设置:我排除了这一点,因为没有运行时库,一切正常,我确认在我的代码之前没有通过反汇编文件执行其他代码.

  2. PE文件部分很有趣:我检查过,并发现在运行时版本中有两个TLS(线程局部)变量.果然,当我让它们共享(而不是线程本地)时,我的代码工作了!但是,当我调用我在不同文件中编写的代码时,我的代码仍然会出现同样的问题 - 只有kernel.d启动文件才能正确处理字符串; 在其他文件中,数组再次为零.

现在,有没有人猜到为什么会发生这种情况?

如果需要更多信息,我很乐意发布.

谢谢!

boot kernel d portable-executable bootloader

7
推荐指数
2
解决办法
1050
查看次数

如何通过BIOS中断在实模式下处理键盘?

我必须为我可以运行计算器的操作系统编写代码.它就像一个桌面计算器.为此,我正在阅读我已经完成第二阶段bootloaderbreaknthorn操作开发系列引导加载程序处于实模式.在此之后,作者正在解释保护模式.我不想使用保护模式.我没有时间.所以我想通过使用bios中断在实模式下编写计算器.可能吗?我认为它可以写在引导程序的第二阶段(我不确定.)意味着我不必使用内核(我不确定).我不知道如何使用BIOS中断来处理键盘.任何人都可以给我一个链接来帮助我吗?如果我认为上面的任何错误是错误的,请纠正我.谢谢.

x86 assembly operating-system calculator bootloader

6
推荐指数
2
解决办法
6601
查看次数

如何调试启动加载程序?

我使用gdb调试了小程序.

我有GRUB的源代码.GRUB的第二阶段是用C语言编写的.我可以使用gdb进行调试吗?

是否可以调试引导加载程序?如果是,那怎么样?

debugging grub bootloader

6
推荐指数
1
解决办法
3758
查看次数

如何使用_small_代码空间减少十六进制ASCII字符转换的代码空间?

如何使用小代码空间减少十六进制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)

embedded pic bootloader

6
推荐指数
1
解决办法
1035
查看次数

U-boot具有冗余环境,fw_setenv不会更新两个环境

为什么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 输出。

在设置rootfs mtd7之前:

# 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)

embedded linux-kernel bootloader u-boot

6
推荐指数
1
解决办法
5631
查看次数

了解用于在电传模式下输出字符的 nasm 程序集

我正在阅读这篇关于操作系统编程的精彩剧本

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)

如果那是你需要做的?

感谢帮助!

bios nasm osdev bootloader x86-16

6
推荐指数
1
解决办法
1685
查看次数

nasm/ld“重新定位被截断以适应:R_386_16”

集会:

[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 …

assembly nasm ld bootloader x86-16

6
推荐指数
1
解决办法
3967
查看次数

计算机如何知道引导加载程序位于文件系统中的位置?

计算机如何知道引导加载程序位于文件系统中的位置?所有操作系统和所有计算机(也许不是所有计算机,而是所有体系结构)之间是否存在指向引导加载程序的通用文件?我知道Raspberry Pi总是从SD卡的第一个分区加载bootcode.bin。PC 是否共享这样的公共文件?

boot bootloader

6
推荐指数
1
解决办法
628
查看次数

测试Android引导加载程序是否解锁的代码?

有没有办法检查代码是否已解锁设备的引导加载程序?不是设备是否植根,只是引导加载程序状态。

当然有这个命令:

fastboot oem device-info
Run Code Online (Sandbox Code Playgroud)

但是在常规(非快速启动)模式下运行时,我需要能够在 C++(首选)或 Java 中做出相同的决定。

android bootloader

6
推荐指数
0
解决办法
661
查看次数

为什么无法从 .data 节加载我的 HELLO_WORLD 字符串?

我正在制作引导加载程序,作为学习汇编的一种方式。我已经研究过使用部分来组织和优化我的代码,但是当我调用 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)

assembly nasm bootloader x86-16

6
推荐指数
1
解决办法
167
查看次数