Nano Hash - криптовалюты, майнинг, программирование

Ядро C - отлично работает на виртуальной машине, но не на реальном компьютере?

Я делаю базовое ядро ​​C. (Загружается ассемблерной программой) Я компилирую его с помощью кросс-компилятора i686-elf для Windows. Мой код C выглядит следующим образом:

void cls();
void drawhappy();
void main(){
    char *vidptr = (char *)0xb8000;
    cls();
    drawhappy();
}

void cls(){
    char *vidptr = (char *)0xb8000;
    unsigned int j = 0;
    while(j < 80*2*25){
        vidptr[j] = ' ';
        vidptr[j+1] = 0x07;
        j = j+2;
    }
}

void drawhappy(){
    char *vidptr = (char *)0xb8000;
    const unsigned int linewidth = 80*2;
    vidptr[3] = 0xa7;
    vidptr[5] = 0xa7;
    vidptr[7] = 0xa7;
    vidptr[9] = 0xa7;
    vidptr[1+linewidth] = 0xa7;
    vidptr[5+linewidth] = 0xa7;
    vidptr[7+linewidth] = 0xa7;
    vidptr[11+linewidth] = 0xa7;
    vidptr[1+linewidth*2] = 0xa7;
    vidptr[3+linewidth*2] = 0xa7;
    vidptr[5+linewidth*2] = 0xa7;
    vidptr[7+linewidth*2] = 0xa7;
    vidptr[9+linewidth*2] = 0xa7;
    vidptr[11+linewidth*2] = 0xa7;
    vidptr[1+linewidth*3] = 0xa7;
    vidptr[5+linewidth*3] = 0xa7;
    vidptr[7+linewidth*3] = 0xa7;
    vidptr[11+linewidth*3] = 0xa7;
    vidptr[1+linewidth*4] = 0xa7;
    vidptr[11+linewidth*4] = 0xa7;
    vidptr[3+linewidth*5] = 0xa7;
    vidptr[5+linewidth*5] = 0xa7;
    vidptr[7+linewidth*5] = 0xa7;
    vidptr[9+linewidth*5] = 0xa7;
}

В bochs это дает мне ожидаемый результат: YayИ если я использую bootice для записи файла bin в загрузочный сектор и запустить его как виртуальную машину на виртуальном боксе, это тоже работает. Но если я на самом деле загружаюсь с USB-накопителя, он просто сходит с ума, а затем помещает странный символ в нижний правый угол моего экрана. (Нет скриншота, потому что я, очевидно, не могу) У меня процессор i7-3770K. Почему это происходит?

РЕДАКТИРОВАТЬ: Вот мой код сборки:

[org 0x7c00]
KERNEL_OFFSET equ 0x1000

    mov [BOOT_DRIVE], dl

    mov bp, 0x9000
    mov sp, bp

    mov bx, MSG_REAL_MODE
    call print_string

    call load_kernel

    call switch_to_pm

jmp $

%include "C:/Users/Aaron/Desktop/CODE_OS/print_string.asm"
; load DH sectors to ES:BX from drive DL
disk_load:
    push dx

    mov ah, 0x02
    mov al, dh
    mov ch, 0x00
    mov dh, 0x00
    mov cl, 0x02

    int 0x13

    jc disk_error

    pop dx
    cmp dh, al
    jne disk_error
    ret

disk_error:
    mov bx, DISK_ERROR_MSG
    call print_string
    jmp $

DISK_ERROR_MSG: db "Disk read error!", 0
%include "C:/Users/Aaron/Desktop/CODE_OS/print_string_pm.asm"
%include "C:/Users/Aaron/Desktop/CODE_OS/switch_to_pm.asm"
; GDT
gdt_start:

gdt_null:   ; the mandatory null descriptor
    dd 0x0
    dd 0x0

gdt_code:   ; the code segment descriptor
    dw 0xffff   ; limit
    dw 0x0      ; base
    db 0x0
    db 10011010b
    db 11001111b
    db 0x0

gdt_data:
    dw 0xffff
    dw 0x0
    db 0x0
    db 10010010b
    db 11001111b
    db 0x0

gdt_end:

gdt_descriptor:
    dw gdt_end - gdt_start - 1
    dd gdt_start

CODE_SEG equ gdt_code - gdt_start
DATA_SEG equ gdt_data - gdt_start

[bits 16]

load_kernel:
    mov bx, MSG_LOAD_KERNEL
    call print_string

    mov bx, KERNEL_OFFSET
    mov dh, 15
    mov dl, [BOOT_DRIVE]
    call disk_load

    ret

[bits 32]

BEGIN_PM:
    mov ebx, MSG_PROT_MODE
    call print_string_pm

    call KERNEL_OFFSET

    jmp $

BOOT_DRIVE db 0
MSG_REAL_MODE  db 'Started in 16-bit Real Mode',0
MSG_PROT_MODE db 'Successfully booted to 32-bit Protected Mode',0
MSG_LOAD_KERNEL db "Loading Kernel...",0

times 510-($-$$) db 0 ; Pad the boot sector out with zeros
dw 0xaa55 ; Last two bytes form the magic number

(Print-string.asm просто печатает строки, switch_to_pm.asm переключается в защищенный режим, а print_string_pm.asm печатает строки в защищенном режиме.)


  • Вы явно установили видеорежим на предыдущих этапах? У вас на самом деле есть BIOS на вашем компьютере или только эмулированный? 30.05.2015
  • Непонятно, как вы хотите загрузить это, так как это ELF-образ защищенного режима, а классический загрузочный сектор работает в 16-битном реальном режиме. Вам нужен загрузчик (например, grub) или, может быть, прошивка, которая его понимает. 30.05.2015
  • У меня UEFI, значит ли это, что он эмулирован? @user35443 30.05.2015
  • Значит, вы не написали код загрузчика или что-то в этом роде? 30.05.2015
  • @Jester Но тогда почему я могу загрузить его как виртуальную машину в виртуальном боксе? 30.05.2015
  • @ user35443 Я написал программу сборки для загрузки ядра. 30.05.2015
  • Я предполагаю, что это было 32-битное, поэтому вы не смогли установить видеорежим, верно? 30.05.2015
  • Ну, вы не показали ту программу сборки. Предположительно, он предполагает что-то, что не соответствует действительности на вашей реальной машине. Часто это касается адреса загрузки 0:7c00 или 7c0:0. 30.05.2015
  • @user35443 user35443 Да, это 32-битная версия. 30.05.2015
  • @Jester Я добавил свой ассемблерный код в свой пост. 30.05.2015
  • Ну вот, он жестко привязан к 0:7c00, но код может быть загружен по 7c0:0 (конечно, это тот же физический адрес). Вы также вообще не инициализируете DS. Вы должны добавить код для настройки CS и DS. 30.05.2015
  • @Jester Могу я спросить, что означают CS и DS? 30.05.2015
  • @Jester, как вы думаете, можно ли установить режим видео, отличный от режима по умолчанию? 30.05.2015
  • @Jester Или ты просто думаешь, что мне следует использовать grub? 30.05.2015
  • CS=сегмент кода, DS=сегмент данных. Это два из четырех сегментных регистров, остальные SS = сегмент стека, а ES = дополнительный сегмент. 30.05.2015
  • @ user3386109 Хорошо, спасибо. Как вы думаете, я должен просто использовать grub? 30.05.2015
  • Извините, я не знаком с grub, поэтому Jester должен вам помочь :) 30.05.2015
  • @ user3386109 Хорошо, спасибо. 30.05.2015

Ответы:


1

Вы не инициализируете регистры сегментов. Попробуйте изменить начало загрузочного сектора примерно так:

xor ax, ax
mov bp, 0x9000
mov ds, ax
mov es, ax
mov ss, ax ; disables interrupts until the end of the next instruction
mov sp, bp
mov [BOOT_DRIVE], dl
30.05.2015
  • Минимальные примеры с точными шагами компиляции на: github.com/cirosantilli/x86-bare-metal- примеры Я столкнулся с похожей проблемой по адресу: stackoverflow.com/questions/32508919/ 15.09.2015
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..