Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Загрузочный сектор

57K
22 марта 2010 года
Lad90
4 / / 22.03.2010
Здравствуйте.

У вашего покорного слуги возникла проблема следующего характера. Имеется дискета с двумя записанными секторами: загрузочный сектор содержит бинарник, который, в свою очередь, должен загружать содержимое следующего сектора в ОЗУ. Также имеется чистая виртуальная машина без какой бы то ни было ОС.
Вопрос такой: какую структуру по адресам имеет оперативка и куда в нее с дискеты можно прочитать сектор, чтобы передать впоследствии управление на загруженный код?

В качестве бинарников используются COM-программы, собираемые TASM+TLINK. Запись бинарников в секторы дискет производится при помощи самодельной программы на С++ с использованием API-процедур.
14K
23 марта 2010 года
shoorick
48 / / 07.06.2006
загрузочный сектор загружается в 0:7С00, а куда он загрузит второй сектор - нужно уже в нём смотреть
399
23 марта 2010 года
KIV
432 / / 20.01.2009
не забудь поставить в коде загрузчика директиву org 0x7C00. а куда загрузит он второй сектор - дело твоё. можно загружать в адресное пространство от 0x600 (если загрузить ниже то повредится таблица прерываний или область данных BIOS) до 0x9FFFF (выше идёт видео-память и BIOS). Оперативка в реальном режим имеет такую структуру:
 
Код:
0x00000 - 0x003FF - таблица прерываний
0x00400 - 0x005FF - Область данных BIOS
0x00600 - 0x9FFFF - доступно для вас
0xA0000 - 0xAFFFF - графический видео-буфер
0xB0000 - 0xBFFFF - текстовый видео-буфер
0xC0000 - 0xEFFFF - видео-BIOS и всякие другие расширения BIOS
0xF0000 - 0xFFFFF - основной BIOS

Адреса 0xC0000 - 0xFFFFF недоступны для записи.
349
23 марта 2010 года
Phantom-84
656 / / 27.10.2005
Уже неоднократно было сказано, что под границей 0xA0000 присутствует область EBDA, данные которой разрушать крайне нежелательно. Да и вообще более профессиональным подходом будет определение вершины доступной базовой памяти с помощью сервиса BIOS, например, int 12h. Базовую память можно использовать, начиная с адреса 0x500, без риска повредить данные BIOS. Кто не согласен, пусть аргументируют свое мнение.
57K
23 марта 2010 года
Lad90
4 / / 22.03.2010
Цитата: KIV
не забудь поставить в коде загрузчика директиву org 0x7C00.


компилятор TASM запрещает транслировать COM-программу со смещением, отличным от 100h. Можно ли еще каким-то образом при помощи tasm + tlink собрать бинарник без заголовков?

Phantom-84, спасибо за рекомендацию, воспользуюсь int 12h.

Проблема заключается в том, что по какому бы я адресу в оперативку ни копировал кусочек кода (пробовал в том числе и 0000:0600h), VMWare пишет "Operating system not found" :(. Дискета смонтирована правильно, секторы записаны правильно.

399
23 марта 2010 года
KIV
432 / / 20.01.2009
Цитата:
Да и вообще более профессиональным подходом будет определение вершины доступной базовой памяти с помощью сервиса BIOS, например, int 12h


Какой вероятность сегодня, что у компьютера окажется меньше 640 КБ оперативки?

Цитата:
VMWare пишет "Operating system not found"


Может быть вы забыли в конце загрузочного сектора поставить сигнатуру 0x55,0xAA?

57K
24 марта 2010 года
Lad90
4 / / 22.03.2010
Всем спасибо. Решение найдено. Так как тема должна придти к своему логическому завершению, считаю необходимым поделиться решением со всеми.

Проблема была не в последних двух байтах, они-то, как раз, были выставлены правильно.

В качестве компилятора, решившего все вопросы, использовал FASM 1.68. К моей великой радости, он позволяет собирать .asm исходник в бинарник .bin со смещением, отличным от 100h.

Целесообразности в применении сервисов для определения верхней границы памяти я пока не увидел. Всё остальное оказалось совсем просто. Ниже исходники обоих модулей и программы, записывающей их на дискету.

start.asm
Код:
org 7C00h
use16

jmp Main
nop

               db 'bootsect'               ; имя загрузочного сектора
SectSize    dw 0200h        ; количество байт в секторе
ClustSize   db 01h          ; количество секторов в кластере
ResSects    dw 0001h        ; число резервных секторов
FatCnt      db 02h          ; число таблиц FAT
RootSiz                dw 00E0h                
TotSecs     dw 0B40h        ; общее число секторов
Media       db 0F0h         ; media-дескриптор    
FatSize                dw 0009h     ; число секторов в одной FAT
TrkSecs     dw 0012h        ; секторов на дорожку
HeadCnt     dw 0002h        ; число головок чтения/записи
HidnSec     dw 0000h        ; число скрытых секторов

Main:

        cli
        mov ax, cs
        mov ds, ax
        mov es, ax
        mov ss, ax
        mov sp, 0FFFCh
        sti
       
        ; смещение, по которому загрузим в оперативку следующий кусок
        mov bx, 600h

        ; читать с диска A:
        mov dl, 0h
       
        ; головка #0
        mov dh, 0h

        ; цилиндр #0
        mov ch, 0
       
        ; сектор #2
        mov cl, 2
       
        ; количество секторов, которые надо прочитать - 1
        mov al, 1

        mov ah, 2
        int 13h

        jmp 600h


btldr.asm
Код:
org 600h
use16

Btldr:     
        ; получить позицию курсора на экране
        xor ax, ax
        mov ah, 03h
        xor bx, bx
        int 10h

        ; вывести строчку
        mov cx, EndMsg
        sub cx, Msg
        mov bx, 002fh
        mov bp, Msg
        mov ax, 1301h
        int 10h
       
LoopEnd:
        jmp LoopEnd
       
Msg db  'Hello from RAM!'
EndMsg:


bootsector.cpp
Код:
//---------------------------------------------------------------------------
#pragma hdrstop
#include <tchar.h>
#include <stdio.h>
#include <windows.h>
//---------------------------------------------------------------------------
#pragma argsused
int _tmain(int argc, _TCHAR* argv[])
{
    FILE *file;
    const int len = 512;
    char buf[len];
    unsigned long n = 0;

    // открыть дискету на запись
    printf("Trying to open floppy disk... ");

    HANDLE disk = CreateFile("\\\\.\\A:",
                GENERIC_WRITE,
                0,
                NULL,
                OPEN_EXISTING,
                FILE_ATTRIBUTE_NORMAL,
                NULL
                       );

    if (disk == INVALID_HANDLE_VALUE)
    {
        printf("Failed to open floppy disk!");
        return 1;
    }

    printf("Disk is opened successfully!\n");

    // открыть файл стартера на чтение
    printf("Trying to open starter.bin...\n");
    file = fopen("start.bin", "rb");
    if (!file)
    {
        printf("Error reading from starter.bin!\n");
        return 1;
    }

    // прочитать стартер в буфер (510 байт max)
    printf("File is opened successfully! Reading starter.bin...\n");
    fread(buf, sizeof(char), len - 2, file);
    fclose(file);

    // последние два байта сектора
    buf[510] = 0x55;
    buf[511] = 0xaa;

    // записать starter.bin в загрузочный сектор
    if (!WriteFile(disk, buf, len, &n, NULL))
    {
        printf("Error writing starter.com to disk!");
        return 1;
    }

    // прочитать загрузчик в буфер (max 510 байт)
    printf("Trying to open btldr.bin...\n");
    file = fopen("btldr.bin", "rb");
    if (!file)
    {
        printf("Error reading from btldr.bin!\n");
        return 1;
    }

    fread(buf, sizeof(char), len - 2, file);
    fclose(file);

    if (!WriteFile(disk, buf, len, &n, NULL))
    {
        printf("Error writing btldr.bin to disk!");
        return 1;
    }

    CloseHandle(disk);

    printf("All operations completed successfully!");
    return 0;
}
//---------------------------------------------------------------------------

Тему можно считать закрытой.
5.9K
06 мая 2010 года
assign
60 / / 13.12.2005
Цитата: Lad90

...В качестве компилятора, решившего все вопросы, использовал FASM 1.68. К моей великой радости, он позволяет собирать .asm исходник в бинарник .bin со смещением, отличным от 100h...



TASM это тоже может, просто надо присвоить выходному файлу расширение отличное от com.
Например, bin:

 
Код:
tasm myfile.asm
tlink /t myfile.obj,myfile.bin
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог