gpt4 book ai didi

c - 如何正确从bootloader跳转到内核(重启无限麻烦)

转载 作者:行者123 更新时间:2023-11-30 17:05:44 27 4
gpt4 key购买 nike

我编写了一个简单的引导加载程序,其职责是加载内核,将内核重新定位到写入位置并跳转到内核。但切换到保护模式并跳转到内核后会无限重启。谁能指出我哪里错了,以及如何纠正它?谢谢!

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/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com