- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我编写了一个简单的引导加载程序,其职责是加载内核,将内核重新定位到写入位置并跳转到内核。但切换到保护模式并跳转到内核后会无限重启。谁能指出我哪里错了,以及如何纠正它?谢谢!
bootsec.asm
[bits 16]
[org 0x7C00]
mov si, hello_string
_print:
mov al, [si] ;ASCII value is in register AL
cmp al, 0x00
jz print_ok
mov ah, 0x0E ;Tell BIOS that we need to print one charater on screen.
mov bh, 0x00 ;Page no.
mov bl, 0x07 ;Text attribute 0x07 is lightgrey font on black background
int 0x10
inc si
jmp _print
print_ok:
enable_a20:
mov ax, 0x2401
int 0x15
load_next_stage:
mov ah, 2
mov al, 4
mov ch, 0
mov cl, 2
mov dh, 0
mov dl, 0
;mov es, 0
mov bx, 0x9000
int 0x13
jc load_next_stage
load_done:
cli ; disable interrupts
lgdt [gdtr32] ; load GDT register with start address of Global Descriptor Table
lidt [idtr32]
;mov eax, cr0
;or al, 1
;mov cr0, eax
mov ax, 0x0001
lmsw ax ; set PE (Protection Enable) bit in CR0 (Control Register 0)
jmp 0x08:gdt32enable ; we need a jump like this to reload the CS.
align 8
gdt32enable:
[bits 32]
mov ax,0x0010 ; set the segment selector for data that we...
mov ds,ax ; ... set to DS
mov es,ax ; ... set to ES
mov fs,ax ; ... set to FS
mov gs,ax ; ... set to GS
mov ss,ax ; ... and set to SS
;mov esp,stack32+STACKSIZE ; and we create a stack
;----------------------------------------------------------------------------------------------
; load GDT ok, end enter protected mode
;----------------------------------------------------------------------------------------------
;mov edi,0xb8000 ; set the screen buffer location
;mov ecx,80*25 ; set the nbr of attr/char pairs to write
;xor eax,eax ; clear eax
;mov ax,0x0f20 ; set the attr/char pair to write
;rep stosw ; clear the screen
mov eax, load_gdt_ok
mov edi,0xb8000 ; go back to the first column
print_gdt:
mov cl, [eax]
cmp cl, 0x00
jz print_gdt_done
or cx, 0x9c<<8
mov [edi], cx
add edi,2 ; move to the next position on the screen
inc eax
jmp print_gdt
print_gdt_done:
;jmp done_move
cld
;mov eax, 0x100000
mov edi, 0x100000
mov esi, 0x9000
mov ecx, 512
move_kernel:
mov eax, [esi]
mov [edi], eax
add edi, 4
add esi, 4
dec ecx
jz done_move
jmp move_kernel
done_move:
mov esp, 0x200000
;sti
;jmp $
;jmp 0x9000
jmp 0x100000
hello_string:
db 'Hello World from bootsec...', 0 ;HelloWorld string ending with 0
load_gdt_ok:
db "Load GDT ok, and enter protected mode..................", 0
align 8
gdt32:
dq 0 ; GDT entry 0x00
dq 0x00cf9a000000ffff ; DGT entry 0x08
dq 0x00cf92000000ffff ; GDT entry 0x10
gdt32End:
gdtr32: ; this is out initial GDTR
dw gdt32End-gdt32-1
dd gdt32
idtr32:
dw 0
dd 0
times 510 - ($ - $$) db 0 ;Fill the rest of sector with 0
dw 0xAA55 ;Add boot signature at the end of bootloader
内核.c
#include <stdint.h>
#define __ISA_IO_base 0x0
#define __VGA_BASE (__ISA_IO_base + 0xb8000)
#define asm __asm__
typedef struct init_gdt32
{
uint64_t dummy;
uint64_t code;
uint64_t data;
}init_gdt32 __attribute__((align(8)));
init_gdt32 init_gdt32_desc = {0,0x00cf9a000000ffff,0x00cf92000000ffff};
void kentry()
{
asm volatile ("lgdt %0;"::"m"(init_gdt32_desc):);
asm (
"mov $0x0010, %ax;"
"mov %ax, %ds;"
"mov %ax, %es;"
"mov %ax, %fs;"
"mov %ax, %gs;"
"mov %ax, %ss;"
// "mov edi, 0xB8000;"
// "movl $500, %ecx;"
// "movl $0x1F201F20, %eax;"
// "rep stosd;"
// "movl $0x00b8000, %edi;"
// "movq 0x1F6C1F6C1F651F48, %eax;"
// "movq %rax, (%edi);"
// "movq $0x1F6F1F571F201F6F, %rax;"
// "movq %rax, 8(%edi);"
// "movq $0x1F211F641F6C1F72, %rax;"
// "movq %rax, 16(%edi);"
);
kmain();
}
void __writew(uint32_t addr, uint16_t val)
{
(*(uint16_t*) addr) = val;
}
int kmain()
{
int i = 0;
char* lint = "----------------------->hello in kernel...";
int offset = 80*10;
int len = 42;
for (i = 0; i < len; ++i)
{
__writew(__VGA_BASE + offset + i*2, (0x2c<<8) | lint[i]);
// __writew(__VGA_BASE + offset + i*2+1, 0x9c);
}
while(1);
return 0;
}
内核.test.ld
OUTPUT_FORMAT(elf64-x86-64)
ENTRY(kentry)
KERNEL_START = 0x100000;
SECTIONS {
. = 0x0 ;
kernel_lma = . ;
. = KERNEL_START;
__kernel_start = . ;
.text ALIGN(0x1000) : AT(kernel_lma) {
*(.text)
}
.data ALIGN(8) : AT(ADDR(.data) - KERNEL_START){
*(.data)
}
.bss ALIGN(8) : AT(ADDR(.bss) - KERNEL_START){
*(.bss)
}
__kernel_end = . ;
}
生成文件
TARGET-BIN=kernel.bin
LINK-SCRIPT=kernel.test.ld
AS=nasm
CC=gcc
LD=ld
CFLAGS=-ffreestanding -O2 -nostdlib -z max-page-size=0x1000
LD-SCRIPT=-T $(LINK-SCRIPT)
OBJCOPY=objcopy
OBJS = kernel.o
.PHONY: build
build: $(TARGET-BIN)
$(TARGET-BIN) : $(OBJS)
echo Linking...
$(LD) $(LD-SCRIPT) -o $@ $(OBJS)
$(OBJCOPY) -O binary $@ kernel.img
%.o : %.c
echo compiling...
$(CC) -c $(CFLAGS) $< -o $@
%.o : %.s
echo assembling...
$(AS) -f elf64 $< -o $@
disk:
cat boot.o kernel.img > OSImage
dd if=./OSImage of=./osdisk.img
boot:
nasm bootsec.asm -o boot.o
.PHONY: clean
clean:
echo Cleaning...
rm -fr *.o *.bin *.img
最佳答案
如果kmain()
运行,请检查WDT并禁用它(如果启用)。
关于c - 如何正确从bootloader跳转到内核(重启无限麻烦),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35122227/
#include using namespace std; class C{ private: int value; public: C(){ value = 0;
这个问题已经有答案了: What is the difference between char a[] = ?string?; and char *p = ?string?;? (8 个回答) 已关闭
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 7 年前。 此帖子已于 8 个月
除了调试之外,是否有任何针对 c、c++ 或 c# 的测试工具,其工作原理类似于将独立函数复制粘贴到某个文本框,然后在其他文本框中输入参数? 最佳答案 也许您会考虑单元测试。我推荐你谷歌测试和谷歌模拟
我想在第二台显示器中移动一个窗口 (HWND)。问题是我尝试了很多方法,例如将分辨率加倍或输入负值,但它永远无法将窗口放在我的第二台显示器上。 关于如何在 C/C++/c# 中执行此操作的任何线索 最
我正在寻找 C/C++/C## 中不同类型 DES 的现有实现。我的运行平台是Windows XP/Vista/7。 我正在尝试编写一个 C# 程序,它将使用 DES 算法进行加密和解密。我需要一些实
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
有没有办法强制将另一个 窗口置于顶部? 不是应用程序的窗口,而是另一个已经在系统上运行的窗口。 (Windows, C/C++/C#) 最佳答案 SetWindowPos(that_window_ha
假设您可以在 C/C++ 或 Csharp 之间做出选择,并且您打算在 Windows 和 Linux 服务器上运行同一服务器的多个实例,那么构建套接字服务器应用程序的最明智选择是什么? 最佳答案 如
你们能告诉我它们之间的区别吗? 顺便问一下,有什么叫C++库或C库的吗? 最佳答案 C++ 标准库 和 C 标准库 是 C++ 和 C 标准定义的库,提供给 C++ 和 C 程序使用。那是那些词的共同
下面的测试代码,我将输出信息放在注释中。我使用的是 gcc 4.8.5 和 Centos 7.2。 #include #include class C { public:
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我的客户将使用名为 annoucement 的结构/类与客户通信。我想我会用 C++ 编写服务器。会有很多不同的类继承annoucement。我的问题是通过网络将这些类发送给客户端 我想也许我应该使用
我在 C# 中有以下函数: public Matrix ConcatDescriptors(IList> descriptors) { int cols = descriptors[0].Co
我有一个项目要编写一个函数来对某些数据执行某些操作。我可以用 C/C++ 编写代码,但我不想与雇主共享该函数的代码。相反,我只想让他有权在他自己的代码中调用该函数。是否可以?我想到了这两种方法 - 在
我使用的是编写糟糕的第 3 方 (C/C++) Api。我从托管代码(C++/CLI)中使用它。有时会出现“访问冲突错误”。这使整个应用程序崩溃。我知道我无法处理这些错误[如果指针访问非法内存位置等,
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,因为
我有一些 C 代码,将使用 P/Invoke 从 C# 调用。我正在尝试为这个 C 函数定义一个 C# 等效项。 SomeData* DoSomething(); struct SomeData {
这个问题已经有答案了: Why are these constructs using pre and post-increment undefined behavior? (14 个回答) 已关闭 6
我是一名优秀的程序员,十分优秀!