相关疑难解决方法(0)

bootloader - 将处理器切换到保护模式

我很难理解简单的引导装载程序是如何工作的.我正在谈论的引导加载程序是麻省理工学院"操作系统工程"课程中的一个.

首先,让我向您展示BIOS执行的一段汇编代码:

[f000:fec3]    0xffec3: lidtw  %cs:0x7908
[f000:fec9]    0xffec9: lgdtw  %cs:0x7948
[f000:fecf]    0xffecf: mov    %cr0,%eax
[f000:fed2]    0xffed2: or     $0x1,%eax
[f000:fed6]    0xffed6: mov    %eax,%cr0
[f000:fed9]    0xffed9: ljmpl  $0x8,$0xffee1
Run Code Online (Sandbox Code Playgroud)

从它的外观来看,此代码设置中断表和描述符表,然后打开保护模式.

  1. 为什么我们在BIOS中进入保护模式?引导程序不应该以实模式运行(顺便说一下 - 为什么它需要在实模式下运行?)
  2. 我搜索但没有找到ljmpl指令的确切工作方式,并且它与ljmp和常规jmp之间的区别 - 如果有人指向正确的方向,我将不胜感激.
  3. 我们为什么要跳跃?这条指令的目的是什么?

转到启动加载程序代码 -

# Switch from real to protected mode, using a bootstrap GDT
# and segment translation that makes virtual addresses
# identical to their physical addresses, so that the
# effective memory map does not change during the switch.
lgdt    gdtdesc
movl    %cr0, %eax
orl …
Run Code Online (Sandbox Code Playgroud)

x86 assembly operating-system protected-mode bootloader

27
推荐指数
1
解决办法
9784
查看次数

如何编写hello world内核?

我正在编写一个内核,所以我开始在内核中使用hello world程序.

我用c ++编写了一个hello world内核,并且编译成功.

但是,当我启动它时,它不会在屏幕上显示任何内容.

这段代码出了什么问题?

link.ld

OUTPUT_FORMAT("binary")
ENTRY(start)
SECTIONS{
. = 0x00100000;

.text :{
    *(.text)
}

.rodata ALIGN (0x1000) : {
    *(.rodata)
}

.data ALIGN (0x1000) : {
    *(.data)
}

.bss : {
    sbss = .;
    *(COMMON)
    *(.bss)
    ebss = .;
}
}
Run Code Online (Sandbox Code Playgroud)

loader.asm

[BITS 32]

global start
extern _main

start:
    call _main
    cli 
    hlt
Run Code Online (Sandbox Code Playgroud)

video.h

#ifndef VIDEO_H
#define VIDEO_H

class Video{
    public:
        Video();
        ~Video();
        void clear();
        void write(char *cp);
        void put(char c);
    private:
        unsigned short *videomem;
        unsigned …
Run Code Online (Sandbox Code Playgroud)

c c++ assembly operating-system kernel

16
推荐指数
3
解决办法
4629
查看次数

汇编程序使用GDT跳转到保护模式

我目前正在玩x86 Assember,以提高我的低级编程技能.目前,我在32位保护模式下的寻址方案面临一些问题.

情况如下:

我有一个程序加载在0x7e0,它将CPU切换到保护模式并跳转到代码中的相应标签:

[...]
code to switch CPU in Protected Mode
[...]

jmp ProtectedMode


[...]

bits 32

ProtectedMode:
    .halt:
        hlt
        jmp .halt
Run Code Online (Sandbox Code Playgroud)

到目前为止这个工作绝对正常."jmp ProtectedMode"在没有显式远跳的情况下工作以清除预取队列 - 因为该程序加载了偏移量0(开头的org 0) - 导致代码段指向正确的位置.

我现在的问题是,在"ProtectedMode"标签中我想跳转到另一个加载到0x8000的程序(我用内存转储检查了这个,加载函数确实正常工作,程序正确加载到0x8000) .

由于CPU现在处于ProtectedMode而不再是RealMode,因此寻址模式不同.ProtectedMode使用描述符选择器查找基址和描述符表中的限制,以添加给定的偏移量并检索物理地址(据我所知).因此,在进入ProtectedMode之前必须安装GDT.

我看起来如下:

%ifndef __GDT_INC_INCLUDED__
%define __GDT_INC_INCLUDED__

;*********************************
;* Global Descriptor Table (GDT) *
;*********************************
NULL_DESC:
    dd 0            ; null descriptor
    dd 0

CODE_DESC:
    dw 0xFFFF       ; limit low
    dw 0            ; base low
    db 0            ; base middle
    db 10011010b    ; access
    db 11001111b    ; granularity
    db 0 …
Run Code Online (Sandbox Code Playgroud)

x86 assembly protected-mode addressing-mode

12
推荐指数
1
解决办法
8392
查看次数