Странное поведение ядра 64 бит - PullRequest
0 голосов
/ 28 октября 2018

У меня проблемы с пониманием этой проблемы:

У меня есть этот код, который вызывается загрузчиком, но когда я компилирую и запускаю тест, который должен напечатать HELLO, может произойти одна из этих трех вещей:

Если я объявляю другую переменную типа unsigned, код будет печатать только половину строки (HE).

Если я объявляю другой тип переменной, он вообще ничего не печатает ().

Если я ничего не объявляю, код будет хорошо работать (привет).

main.c

#include "system.h"

int main(void)
{
    init_video();
    move_csr();
    p("HELLO\0");
    while(1){}
    return 1;

}

system.h

#ifndef __SYSTEM_H
#define __SYSTEM_H

/* MAIN.C */

extern void move_csr(void);

extern void init_video();
extern void pc(unsigned char);
extern void p(char*);

#endif

scrn.c

#include "system.h"

unsigned char *textmemptr;
int attrib = 0x0F;
int csr_x = 0, csr_y = 0;

void init_video() {
    textmemptr = (unsigned char*) 0xB8000;
    return;
}

void move_csr(void) {
        unsigned temp = csr_y * 80 + csr_x;
}

void pc(unsigned char c) {
    *textmemptr = c;
    textmemptr += 2;
}

void p(char* string) {
    for (int i = 0; ; i++) {
        if (string[i]=='\0') return;
        pc(string[i]);
    }
}

build.sh

#!/bin/bash

nasm -f bin boot.asm -o boot.bin
nasm -f elf64 loader.asm -o loader.o

#cc -m64  -ffreestanding -fno-builtin -nostdlib -c main.c
#-Wall -O -fstrength-reduce -fomit-frame-pointer -finline-functions -nostdinc -fno-builtin
cc -m64 -masm=intel -fno-builtin -c main.c scrn.c
ld  -Ttext 0x100000 -o kernel.elf loader.o main.o scrn.o
objcopy -R .note -R .comment -S -O binary kernel.elf kernel.bin

dd if=/dev/zero of=image.bin bs=512 count=2880
dd if=boot.bin of=image.bin conv=notrunc
dd if=kernel.bin of=image.bin conv=notrunc bs=512 seek=1

rm ./boot.bin ./kernel.bin ./main.o ./loader.o ./kernel.elf

#qemu-system-x86_64 image.bin format=raw

qemu-system-x86_64 -drive file=image.bin,format=raw,index=0,media=disk -m 512

если я подавлю строку:

unsigned temp = csr_y * 80 + csr_x;

код отлично работает.

Я не слишком разбираюсь в сборке, и, возможно, я упускаю что-то жизненно важное в управлении памятью.

1 Ответ

0 голосов
/ 28 октября 2018

Answer by Michael Petch

Если заглянуть внутрь файла kernel.bin, строка HELLO, кажется, частично находится в первых 512 байтах, а остальная часть - снаружи.Когда вы добавляете или удаляете код, он изменяет, где находится эта строка (находится ли она в первых 512 байтах или нет), и, вероятно, ваш код действует по-другому.Вам определенно придется посмотреть на чтение более 1 сектора, чтобы решить эту проблему.

Проблема заключалась в том, что файл загрузчика считывал только один сектор в файле kernel.bin, поэтому я пытался выполнить строкуПечать была загружена только частично.Решение состоит в том, чтобы изменить загрузчик так, чтобы он загружал достаточное количество секторов для запуска кода.

[EDIT]

Как Майкл Петч предложил добавить -z max-page-size=0x1000 к ld в buildscript, резко сократилосьразмер .bin-файла.

...