Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 26.08.2017, 09:57   #21
Nikolay2015
Пользователь
 
Регистрация: 23.08.2017
Сообщений: 59
По умолчанию

А вот так хотелось со своего загрузчика начать.
Или можно вначале использовать GRUB, а потом написать свой, когда опыт будет?
Nikolay2015 вне форума Ответить с цитированием
Старый 26.08.2017, 10:18   #22
Nikolay2015
Пользователь
 
Регистрация: 23.08.2017
Сообщений: 59
По умолчанию

Всё получилось. Вылетело #GP и напечатался текст.

boot.asm
Код:
use16
org 0x7c00                  
                            
 start:

    xor ax, ax
    mov ds, ax

    mov ah, 02h
    mov dh, 0
    mov ch, 2
    mov al, 09h

    int 13h

    jmp Boot_Second
finish:
   times 0x1FE-finish+start db 0
   db 55h,0aah


Boot_Second:
    lgdt [gdtr]            

    lidt [idtr]

    call OpenA20Gate        
    cli

    mov al,8Fh;
    out 70h,al
    in al,71h
    call EnablePMode       




OpenA20Gate:
    in al, 0x92       

    or al, 2            
    out 0x92, al

    ret


EnablePMode:
    mov eax, cr0
    or eax, 1
    mov cr0, eax

    jmp far (CODE_DESC - NULL_DESC) : ProtectedMode


align 8
GDTR_TABLE:
NULL_DESC:
    dd 0            ; null descriptor
    dd 0

CODE_DESC:
    dw 0xFFFF       ; limit low
    dw 0            ; base low
    db 0            ; base middle
    db 10011010b    ; access
    db 11001111b    ; granularity
    db 0            ; base high

DATA_DESC:
    dw 0xFFFF       ; limit low
    dw 0           ; base low
    db 0            ; base middle
    db 10010010b    ; access
    db 11001111b    ; granularity
    db 0            ; base high
VIDEO_SEG:
    dw 0FFFFh
    dw 8000h
    db 0Bh
    db 092h
    db 040h
    db 0

gdtr:
    Limit dw gdtr - NULL_DESC - 1 ; length of GDT
    Base dd NULL_DESC   ; base of GDT


IDT:
        dd 0,0 ;0 äåñêðèïòîð
        dw syscall_int ,08h, 1000111000000000b, 0 ; 1 -Ñèñòåìíûé âûçîâ
        dd 0,0 ; 2
        dd 0,0 ; 3
        dd 0,0 ; 4
        dd 0,0 ; 5
        dd 0,0 ; 6
        dd 0,0 ; 7
        dd 0,0 ; 8
        dd 0,0 ; 9
        dd 0,0 ; 10
        dd 0,0 ; 11
        dd 0,0 ; 12
        dw global_catch_int, 08h, 1000111000000000b, 0   ; 13  #GP
        dd 0,0 ; 14
        dd 0,0 ; 15
        dd 0,0 ; 16
        dd 0,0 ; 17
        dd 0,0 ; 18
        dd 0,0 ; 19
        dd 0,0 ; 20
        dd 0,0 ; 21
        dd 0,0 ; 22
        dd 0,0 ; 23
        dd 0,0 ; 24
        dd 0,0 ; 25
        dd 0,0 ; 26
        dd 0,0 ; 27
        dd 0,0 ; 28
        dd 0,0 ; 29
        dd 0,0 ; 30
        dd 0,0 ; 31
        dw sys_timer_int, 08h, 1000111000000000b, 0   ; IRQ 0 - ñèñòåìíûé òàéìåð
        dw keyboard_int, 08h, 1000111000000000b, 0   ; IRQ 1 - êëàâèàòóðà


IDT_SIZE dw  $-IDT

idtr:
        dw IDT_SIZE-1
        dd IDT


use32
include 'Kernel.ASM'
ProtectedMode:
    mov     ax, DATA_DESC - NULL_DESC
    mov     ds, ax ; update data segment
    mov     ss, ax
    mov     fs, ax
    mov     gs, ax
    mov     ax, VIDEO_SEG - NULL_DESC
    mov     es, ax
    mov     cx, 0
    mov     di, cx
    mov     esi , gp2
    mov ah, 07h
_puts:
    lodsb
    mov  [es:(edi*2)], al
    inc edi
    test al, al
    jnz _puts
    in   al, 70h
    and  al, 7Fh
    out  70h, al
    sti
    jmp $
  gp2 db  'Protected mode',0
kernel.asm
Код:
syscall_int:
        pushad
        xor eax, eax
        mov edi, eax
        mov ah, 07h
_debug:
        lodsb
        mov  [es:(edi*2)], al
        inc  edi
        test al, al
        jnz  _debug
        popad
        iret

int_EOI:
         push ax
         mov  al, 20h
         out  020h, al
         out  0a0h, al
         pop  ax
         iret

global_catch_int:
         pop eax
         mov  esi, gp
         int  1
         iret
gp db 'GENERAL EXCEPTION FAULT',0
cursor dw 160

sys_timer_int:
  
        iret
keyboard_int:
        jmp int_EOI
Nikolay2015 вне форума Ответить с цитированием
Старый 26.08.2017, 10:43   #23
R71MT
Участник клуба
 
Аватар для R71MT
 
Регистрация: 16.06.2011
Сообщений: 1,428
По умолчанию

что-то перемудрил ты..
Куда ты скопировал второй сектор? Там-же нужно указывать в BX, и по окончании передать на ВХ управление. Где-то глюк притаился. ИМХО.

Цитата:
Сообщение от Nikolay2015 Посмотреть сообщение
Придётся сейчас браться и читать про int 13h.
Когда-то я сюда выкладывал свои эксперементы с загрузчиком, но что-то не нашёл тему поиском. Грузился флопом, в нулевой сектор которого кидал загрузчик, а в первый сектор - саму ось. Загрузчик подгружал ось по адресу 0:600h, куда и передавал управление. Записывал на дискету через винду кекс-редактором HxD. Сохранился исходник на FASM'e:

Код:
; Код загрузчика
;-----------------
use16
org 7C00h
jmp  start

mess0   db  ' READ BOOT-SECTOR: OK!',13,10
        db  '  L - load OS',13,10
        db  '  R - reboot'
mess1   db  ' Loading "DEMO-OS v0.1"....'
error   db  ' ERROR!'

start:
; сегментные регистры в нуль, и устанавливаем стек
   cli
     xor   ax,ax
     mov   ds,ax
     mov   es,ax
     mov   ss,ax
     mov   sp,7C00h         ; стек (растёт вниз) нужен для CALL/RET
   sti

; ставим режим 80х25 и убираем курсор
     mov   ax,3
     int   10h
     mov   ah,1
     mov   ch,20h
     int   10h

; выводим мессагу, что мы по-адресу 0:7C00h
     mov   bp,mess0
     xor   dx,dx
     mov   cx,51            ; длина строки
     call  printStr

; ждём дальнейших указаний..
@@:  xor   ax,ax
     int   16h
     cmp   al,'L'
     je    @loading
     cmp   al,'R'
     je    @reboot
     jmp   @b

; переходим к загрузки ОС из сектора(2) флопа..
@loading:
     mov   bp,mess1         ; мессага
     mov   dx,1419h         ; позиция текста в окне
     mov   cx,27            ; длина строки
     call  printStr

     mov   bp,3             ; счётчик попыток чтения сектора
     mov   al,1             ; кол-во секторов для чтения,
     mov   bx,600h          ;    ..на адрес 600h
     mov   cx,2             ; номер сектора
     xor   dx,dx            ; головка/диск = нуль
@@:  mov   ah,2             ; считать сектор!
     int   13h
     jnc   @ok              ; ОК, если нет ошибки

     dec   bp               ; иначе: уменьшаем счётчик попыток
     jz    @error           ; 3 попытки - ERROR!
     xor   ah,ah            ; иначе: сброс контролёра флопа
     int   13h
     jmp   @b               ; сл.попытка..

; считали ОС! передаём ей управление!
@ok: jmp   600h

; мессага обработчика ошибки и ребут
@error:
     mov   bp,error
     mov   dx,1623h
     mov   cx,7
     call  printStr
     xor   ax,ax            ; ждём клаву..
     int   16h
@reboot:
     xor   dx,dx
     int   18h

;=========== функция вывода сообщений ======================
printStr:
     mov   bx,0Fh
     mov   ax,1301h
     int   10h
ret
Флоп - существо не надёжное, и может не считать сектор с первой попытки. Поэтому даём ему несколько шансов и ставим BP=3. У жёсткого диска сектора считаются с нуля, а у флопа с единицы. Значит нужно выставить у INT-13h значение СХ=2 (номер сектора), в который кидаем загружаемую ОС. Я выводил просто надпись, что являлось флагом передачи управления. Ты вставляй свой код, посчитай размер модуля, в зависимости от которого установишь кол-во секторов для чтения:

Код:
; Код загружаемого модуля (т.н. ОС)
;----------------------------------
use16
org 600h
jmp start

mess0   db  '*********] DEMO-OS v0.1 [*********'

start:
; сегментные регистры в нуль, и устанавливаем стэк
   cli
     xor   ax,ax
     mov   ds,ax
     mov   es,ax
     mov   ss,ax
     mov   sp,600h
   sti

; выводим мигающую мессагу
     mov   si,10            ; кол-во повторов мигания..
@@:  call  Delay
     mov   bp,mess0
     mov   dh,11
     mov   dl,23
     mov   cx,34
     call  PrintStr
     call  Delay

     dec   si
     jz    @exit
     jmp   @b

@exit:
     xor   ax,ax
     int   16h
@reboot:
     int   19h

;=========== функция вывода сообщений ======================
PrintStr:
     mov   bx,0Ch
     mov   ax,1301h
     int   10h
ret

; таймер. читаем секунду в цикле ===========================
Delay:
     mov   ax,0200h
     int   1Ah
     add   dh,1
     cmp   dh,59h
     jnbe  correct
     mov   bl,dh
     jmp   timer
correct:
     sub   dh,59h
     mov   bl,dh
timer:
     mov   ax,0200h
     int   1Ah
     cmp   dh,bl
     jge   endTimer
     jmp   timer
endTimer:
ret
Нашедшего выход - затаптывают первым..

Последний раз редактировалось R71MT; 26.08.2017 в 10:46.
R71MT вне форума Ответить с цитированием
Старый 26.08.2017, 10:58   #24
R71MT
Участник клуба
 
Аватар для R71MT
 
Регистрация: 16.06.2011
Сообщений: 1,428
По умолчанию

..э-э забыл. Нужно вставить в хвост загрузчика сигнатуру 55ААh
Нашедшего выход - затаптывают первым..
R71MT вне форума Ответить с цитированием
Старый 26.08.2017, 11:08   #25
Nikolay2015
Пользователь
 
Регистрация: 23.08.2017
Сообщений: 59
По умолчанию

А есть отличия SSD и HDD в прерывании int 13h
Nikolay2015 вне форума Ответить с цитированием
Старый 26.08.2017, 11:17   #26
R71MT
Участник клуба
 
Аватар для R71MT
 
Регистрация: 16.06.2011
Сообщений: 1,428
По умолчанию

Если разметка диска CHS (под досом), то обычный сервис с fn. AH=0..18h
Если разметка LBA, то расширенный сервис с номерами AH=41..52h
Все современные диски эмулируют CHS, поэтому для загрузчиков хватает и обычного сервиса
Нашедшего выход - затаптывают первым..

Последний раз редактировалось R71MT; 26.08.2017 в 11:19.
R71MT вне форума Ответить с цитированием
Старый 26.08.2017, 11:31   #27
7in
(aka Jin X) !RTFM!
Форумчанин
 
Аватар для 7in
 
Регистрация: 14.12.2014
Сообщений: 295
По умолчанию

Цитата:
Сообщение от Nikolay2015 Посмотреть сообщение
А есть отличия SSD и HDD в прерывании int 13h
Разницы нет между FDD, HDD, SSD. Разве что номер Floppy < 80h, а HDD/SSD >= 80h.
При загрузке MBS (MBR-сектора) DL уже содержит номер диска, с которого грузится.
Делаю лабы на Asm/Delphi/C++/Python/VBA(Excel): asmlabs.ru
7in вне форума Ответить с цитированием
Старый 26.08.2017, 12:15   #28
Nikolay2015
Пользователь
 
Регистрация: 23.08.2017
Сообщений: 59
По умолчанию

R71MT, Ваш код не работает. Не грузит сектор))
И почему вы грузитесь на адрес 600h
Если загрузились до этого на адрес 07C00h?

Последний раз редактировалось Nikolay2015; 26.08.2017 в 12:17.
Nikolay2015 вне форума Ответить с цитированием
Старый 26.08.2017, 12:54   #29
R71MT
Участник клуба
 
Аватар для R71MT
 
Регистрация: 16.06.2011
Сообщений: 1,428
По умолчанию

Алгоритм загрузки компа такой..
После процедуры POST, BIOS передаёт управление по адресу 0:7C00h.
Чтобы загрузить ОС, должен быть загрузчик в задачи которого входит поиск активного\загрузочного раздела на носителях по сигнатуре 55ААh. Если таковая сигнатура имеется в хвосте сектора, то код этого сектора выполняется.

Всё, что нужно от программиста - это расположить свой код по адресу 0:7С00h и ждать, пока BIOS не обратится к нему. Получив управление от BIOS, можно подгружать остальной код ОС, в любой из следующих адресов:

Код:
  Память в реальном режиме [первый 1М] =======================
  ============================================================
  0000:0000 - 0000:05FF    используется BIOS (1.536)
  0000:0600 - 0000:7BFF    свободно (30.208)
  0000:7C00 - 0000:7DFF    программа начальной загрузки (512)
  0000:7E00 - 9FFF:FFFF    свободно (623.104)
  A000:0000 - FFFF:FFFF    используется BIOS (393.216)
Поэтому и задают в коде загрузчика адрес 'ORG 7C00h', а дальше разницы нет, куда ты загрузишь остальную часть. Люшь-бы она была не занята.. А код рабочий 100%. Значит что-то ты сделал не так.
Нашедшего выход - затаптывают первым..
R71MT вне форума Ответить с цитированием
Старый 26.08.2017, 12:58   #30
Nikolay2015
Пользователь
 
Регистрация: 23.08.2017
Сообщений: 59
По умолчанию

Я скомпилил весь код, только номер сектора поменял на 1. Через ульта ISO создал самозагружаемый образ. И запустил на виртуалке. Пишу большую L. На экране высвечивается ERROR

PS. в конце загрузочного сектора поставил 0x55aa
Nikolay2015 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Прерывания kolyan147 Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM 0 13.06.2012 23:55
прерывания lilek Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM 2 14.12.2010 20:44
Прерывания alexdrew Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM 1 16.05.2010 00:38
Прерывания Kn793 Общие вопросы Delphi 3 10.01.2009 18:43