标签: osdev

操作系统的Boot-loader不起作用

我正在制作一个自定义操作系统.我有两个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)

x86 kernel nasm osdev bootloader

4
推荐指数
1
解决办法
1062
查看次数

在自制OS中开发GUI环境

我用c中的内核创建了一个桌面操作系统,打印出"hello world".我正在尝试为我的操作系统制作一个GUI(自定义窗口管理器,按钮),但我遇到了麻烦.我看了一个教程:

http://www.osdever.net/tutorials/view/gui-development

是否有适用于C桌面操作系统的GUI教程?

ps没有Linux,没有DOS.只有C标准.

user-interface operating-system kernel osdev

4
推荐指数
2
解决办法
7206
查看次数

简单的C内核字符指针不起作用

我正在尝试使用C创建一个简单的内核.一切都加载并正常工作,我可以访问视频内存并显示字符,但是当我尝试实现一个简单的put函数由于某种原因它不起作用.我已经尝试了自己的代码和其他代码.此外,当我尝试使用在函数外声明的变量时,它似乎不起作用.这是我自己的代码:

#define PUTCH(C, X) pos = putc(C, X, pos)
#define PUTSTR(C, X) pos = puts(C, X, pos)

int putc(char c, char color, int spos) {
    volatile char *vidmem = (volatile char*)(0xB8000);
    if (c == '\n') {
        spos += (160-(spos % 160));
    } else {
        vidmem[spos] = c;
        vidmem[spos+1] = color;
        spos += 2;
    }
    return spos;
}
int puts(char* str, char color, int spos) {
    while (*str != '\0') {
        spos = putc(*str, color, spos);
        str++;
    }
    return spos;
} …
Run Code Online (Sandbox Code Playgroud)

c x86 pointers kernel osdev

4
推荐指数
1
解决办法
1280
查看次数

设置起始地址以执行原始二进制文件

Bootloader分为两个阶段.第一阶段用汇编语言编写,只加载第二阶段,第二阶段在C阶段.阶段1加载C中的代码到地址0x0500:0,并跳转到那里.Stage2必须写"hello message"并停止.

我尝试了不同的方法将起始地址设置为原始二进制文件:(但没有任何效果)

cc -nostartfiles -nostdlib -c stage2.c
ld -s -T scrptfile.ld stage2.o /* I'm using ld just to set starting address of executable */
objcopy -O binary stage2 stage2.bin /* delete all unuseful data  */
Run Code Online (Sandbox Code Playgroud)

链接器脚本

SECTIONS
{
    . = 0x0500;
    .text : { *(.text)}
    .data : { *(.data)}
    .bss : { *(.bss)}
}
Run Code Online (Sandbox Code Playgroud)

也许我删除objcopy somethnig应删除.

那我怎么能执行这个stage2.bin呢?

据我所知,使用32位长度指令编写C代码,当原始二进制只允许16?

PS参数-set-start(objcopy)返回错误:无效的bfd目标.这是因为输出文件是二进制的?


谢谢你的回答.

x86 linker gcc osdev bootloader

4
推荐指数
1
解决办法
1415
查看次数

操作系统开发-在保护模式下执行第一条指令

我指的是Broken Thorn的OS开发教程。我目前处于执行第二阶段引导加载程序以加载GDT并进入保护模式的阶段。

我了解了GDT的工作原理以及如何进入保护模式。但是,我对加载cr0寄存器后执行的第一条指令感到困惑:

jmp 08h:Stage3      ; far jump to fix CS. Remember that the code selector is 0x8!
Run Code Online (Sandbox Code Playgroud)

此时,CS尚未加载指向代码描述符的选择器值,并且我们已经处于保护模式。此CS值可能与用于执行实模式指令的值不同,因此,增加IP的值也将导致地址不同于的地址jmp。那么这是否会导致基于CS的值执行一些垃圾代码?还是我缺少什么?

assembly operating-system protected-mode osdev bootloader

4
推荐指数
1
解决办法
316
查看次数

GCC内联汇编'Nd'约束

我正在用C开发一个小玩具内核.我需要从键盘获取用户输入.到目前为止,我已inb使用以下代码实现:

static inline uint8_t inb(uint16_t port) {
     uint8_t ret;
     asm volatile("inb %1, %0" : "=a"(ret) : "Nd"(port));
     return ret;
}
Run Code Online (Sandbox Code Playgroud)

我知道"=a"约束意味着al/ax/eax将被复制ret为输出,但我仍然对"Nd"约束感到困惑.谁能提供一些有关为什么需要这种约束的见解?或者为什么我不能只使用通用寄存器约束"r""b"?任何帮助,将不胜感激.

x86 gcc kernel inline-assembly osdev

4
推荐指数
1
解决办法
500
查看次数

将16位实模式代码链接到符合Multiboot的ELF可执行文件时出现LD错误

我正在编写一个包含我的32位内核的Multiboot兼容的ELF可执行文件.我的主要问题是我在生成可执行文件时收到一系列链接器错误:

重定位被截断以适合:R_386_16对``.text'

链接器脚本,代码和构建脚本如下

我决定尝试在我的操作系统中实现VESA VBE图形.我在OSDev论坛中发现了一个现有的VESA驱动程序,我试图将它集成到我自己的操作系统中.我尝试将它添加到我的源目录,用NASM组装并将其链接到LD的最终可执行文件中.我收到的具体错误是:

vesa.asm:(.text+0x64): relocation truncated to fit: R_386_16 against `.text'
obj/vesa.o: In function `svga_mode':
vesa.asm:(.text+0x9d): relocation truncated to fit: R_386_16 against `.text'
vesa.asm:(.text+0xb5): relocation truncated to fit: R_386_16 against `.text'
obj/vesa.o: In function `done':
vesa.asm:(.text+0xc7): relocation truncated to fit: R_386_16 against `.text'
Run Code Online (Sandbox Code Playgroud)

导致错误的行(按顺序)如下:

mov ax,[vid_mode]
mov cx,[vid_mode]
mov bx,[vid_mode]
jmp 0x8:pm1
Run Code Online (Sandbox Code Playgroud)

我还评论了"链接器错误"的行

这是文件(vesa.asm):

BITS    32

global do_vbe

save_idt: dd 0
          dw 0
save_esp: dd 0
vid_mode: dw 0

do_vbe: …
Run Code Online (Sandbox Code Playgroud)

x86 assembly nasm ld osdev

4
推荐指数
1
解决办法
946
查看次数

VirtualBox-找不到可启动媒体

关于标题类似的stackoverflow有很多问题。我读了所有这些文章,但没有一个回答我的问题。这就是为什么我打开这个问题。

我正在用汇编器和C创建一个操作系统。我发现必须将C代码编译为二进制格式,提取文本部分并将其保存为文件,然后将其转换为ISO,然后将其安装到diskete的虚拟光驱中,然后在VirtualBox中加载我的操作系统。因此,这是我要避免的许多工作。我不想每次都将二进制文件转换为ISO。

因此,我决定将操作系统的二进制计算机代码放入虚拟硬盘驱动器(VDI文件),然后将其设置为引导顺序的顶部并加载,而不是从虚拟光盘驱动器加载ISO

我正在研究VDI工作原理,发现它通常是按名称分配的,并且只存储数据的开头。因此,的开头VDI代表标题,其余的代表存储在虚拟驱动器上的实际数据。因此,我发现数据从某个地址开始(就我而言,它是0x00200000VDI文件的开头开始)。

然后,我基本上VDI使用pattern 从该地址填充到文件末尾55 AA。因此,我想它现在意味着磁盘是可引导的(因为第一个扇区的末尾仍是签名55 AA)。

我启动了虚拟机,它说:

找不到可启动媒体!系统停止

有什么办法解决这个问题?为什么我的虚拟磁盘仍然无法启动?

编辑

这是实际的VDI文件:1.vdi

x86 virtualbox virtual-machine osdev bootloader

4
推荐指数
1
解决办法
1592
查看次数

如何将节从ELF输出文件映射到段?

好吧,我已经在程序集中编写了一个引导加载程序,并尝试从中加载C内核。

这是引导程序:

bits 16
xor ax,ax
jmp 0x0000:boot

extern kernel_main

global boot
boot:
    mov ah, 0x02             ; load second stage to memory
    mov al, 1                ; numbers of sectors to read into memory
    mov dl, 0x80             ; sector read from fixed/usb disk ;0 for floppy; 0x80 for hd
    mov ch, 0                ; cylinder number
    mov dh, 0                ; head number
    mov cl, 2                ; sector number
    mov bx, 0x8000           ; load into es:bx segment :offset of buffer
    int 0x13                 ; …
Run Code Online (Sandbox Code Playgroud)

x86 assembly gcc elf osdev

4
推荐指数
1
解决办法
401
查看次数

ASM:“ mov”的内存引用过多

还是我,我的idt.S文件(使用gcc编译的Intel语法)出现了新问题。当我尝试编译以下代码时:

load_idt:
        mov edx, (esp + 4) ; On this line
        lidt (edx)
        sti
        ret
Run Code Online (Sandbox Code Playgroud)

我收到一个我真的不知道如何解决的错误:

Error: too many memory references for `mov'
Run Code Online (Sandbox Code Playgroud)

x86 assembly gcc osdev intel-syntax

4
推荐指数
1
解决办法
492
查看次数