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

Ваш аккаунт

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

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

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

Создаем загрузочный диск.

Данные в секторе 1 дорожки 0 головки 0 дисковода 0 для первого откликнувшегося диска (дискеты или твердого диска) загружаются по абсолютному адресу 0000:7c00, и управление передается по этому адресу. Если опрос всех дисков неудачен, управление передается на прерывание INT 18H .

На твердом диске, этот код в "корневом секторе" в действительности определяет активный раздел диска, а затем загружает и выполняет корневой сектор для этого раздела. Это передает управление активной операционной системе диска.

Наша задача - написать процедуру, работающую с адреса CS:07C00h и производящую загрузку OS.

Для простоты предположим, что ядро ОС - первый файл (не фрагментированный) не дискете, с размером 64kb (или меньше). (Первый файл на дискете(1.44) находится в сектре 33.)

Все-бы бало ни чего, если-бы была процедура чтения сектора (типа int 25h), ну вроде и все, больше ни каких проблем загрузка из boot'а вызвать не должна.

                IDEAL
                MODEL   tiny
                DATASEG
KernelSeg       EQU 01000h

                CODESEG
                ORG     100h  
Start:          jmp     Start1
                ORG     07C00h

Данные из boot сектора грузятся по адрессу 0000:7C00, следовательно мы должны писать под этот адрес.

Start1:         jmp     Begin
                ; EB 3C 90
                ;       Таблица для совместимости с DOS
                nop
OEMName         DB      29h,63h,7Eh,26h,49h,49h,48h,43h
SectSize        DW      00200h
ClustSize       DB      001h
ResSecs         DW      00001h
FatCnt          DB      002h
RootSiz         DW      000E0h
TotSecs         DW      00B40h
Media           DB      0F0h
FatSize         DW      00009h
TrkSecs         DW      00012h
HeadCnt         DW      00002h
HidnSec         DW      00000h

Данные о дискете, для совместимости с DOS

; Мои переменные
AbsSectNum      DW      0
AbsHeadNum      DW      0

Begin:          ; Рамка
                ; Читаем ядро
                mov     ax,KernelSEG
                mov     es,ax
                mov     di,100h          ; Entry Point - KernelSEG:100h
                mov     dx,33            ; Первый сектор с данными 
                                         ; (128 секторов ядра)
nextsect:       push    dx es di
                call    ReadSect
                pop     di es dx
                add     di,512
                inc     dx
                cmp     dx,160
                jne     nextsect
                call     far KernelSEG:0100h
                ; ReadKey
                int     20h
; Чтение сектора (DX=номер сектора) ##########################################

Чтение сектора без DOS довольно запаристо: Зная абсолютный номер сектора, нам надо его преобразовать в номер головки, дорожки и сектора.

; ES:DI - куда читать
PROC            ReadSect
                push di es
                 ; Начало расчета сектора/дорожки/головки
                 push    cs
                 pop     ds
                 mov     cx,[TrkSecs]
                 mov     si,dx
                 ; tmp=(Sect/Sectors);
                 mov     ax,si
                 xor     dx,dx
                 div     cx
                 mov     di,ax
                 ; Sec=Sect-(tmp*Sectors)+1;
                 mov     ax,di
                 imul    cx
                 mov     dx,si
                 sub     dx,ax
                 inc     dx
                 mov     [AbsSectNum],dx
                 ; Hea=tmp & 1;
                 mov     ax,di
                 and     ax,1
                 mov     [AbsHeadNum],ax
                 ; Trk=(Sect-(Hea*Sectors)-(Sec-1))/(Sectors*2);
                 imul    cx
                 push    ax
                 mov     ax,si
                 pop     dx
                 sub     ax,dx
                 mov     dx,[AbsSectNum]
                 dec     dx
                 sub     ax,dx
                 mov     dx,cx
                 shl     dx,1
                 push    ax
                 push    dx
                 xor     dx,dx
                 pop     bx
                 pop     ax
                 div     bx           ; AX = AbsTrackNum
                 ; Конец расчетов
                 mov     cx,ax
                 mov     al,cl
                 shr     cx,2
                 and     cl,0C0h
                 mov     ch,al
                 and     cx,0FFC0h
                 mov     ax,[AbsSectNum]  ;      -5-4-3-2-1-0-9-8-7-6-5-4-3-2-1-0-
                 or      cl,al            ; CX = |c|c|c|c|c|c|c|c|C|c|S|s|s|s|s|s|
                pop     es bx             ; ES:BX = Куда считывать
                mov     dx,[AbsHeadNum]
                mov     dh,dl             ; Номер головки
                mov     dl,0              ; Номер диска 0 = A
                mov     al,1              ; Количество считываемых секторов
                mov     ah,2              ; Номер функции
                int     13h
                ret
ENDP            ReadSect
                END     Start

Оставить комментарий

Комментарий:
можно использовать BB-коды
Максимальная длина комментария - 4000 символов.
 
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог