Использование портов ВВ для работы с дисководом.

Тема в разделе "WASM.OS.DEVEL", создана пользователем n0name, 31 май 2007.

  1. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    Преамбула: решил разобратся с работай в многопроцессорной среде. Для этого решил написать некоторое подобие ОСи.
    Амбула: подумал что int13 это не интересно, и рещил делать считывание основного ядра напрямую через порты ВВ.
    Собственно не получается :dntknw: Хотя я тестил пока только на эмуляторах, но всё таки хотелось бы чтобы и на них работало.
    Сначала сделал PIO режим, однако бош не поддерживает его(сорцы глядел), vmware вообще хз где падает :\ Сделал работу с DMA, всё чётко как у Фроловых/Несвиждного. А вот проверку на завершение операции сделал по другому. Написав свой обработчик irq6, и отмечаю когда произошло прерывание. Однако после выполнения команды SEEK оно не вызывается(гляжу на ВМ, дисковода у меня нету). Поэтому решил сделать еще проверку на бит готовности к обмену, как делал раньше, и всё работало. А сейчас бош вылетает с ошибкой доступа к памяти. Вот такая вот история ;) Кому не лень прошу помочь.
    Код (Text):
    1. use16
    2.  
    3. org 7C00h
    4.  
    5. STACK_BASE  equ 9000h ; заносим в ss
    6. STACK_PTR   equ 9F00h ; заносим в sp
    7. KERNEL_BASE equ 600h  ; куда будем сохранять ядро
    8. KERNEL_SIZE equ 512   ; размер ядра в байтах
    9.  
    10. include "..\drivers\floppy\floppy.inc"
    11.  
    12. start:
    13.     ; отключаем прерывания
    14.     cli
    15.     ; ds = cs = 0
    16.     push cs
    17.     pop ds
    18.     ; ставим свой обработчик IRQ6
    19.     mov word [0Eh * 4], irq6_handler
    20.     mov word [0Eh * 4 + 2], 0
    21.     ; настраиваем стек
    22.     mov ax, STACK_BASE
    23.     mov ss, ax
    24.     mov sp, STACK_PTR
    25.     ; включаем прерывания
    26.     sti
    27.     ; сохраняем адрес DPT, а в es ее сегмент
    28.     mov ax, [78h]
    29.     mov [DPT_table], ax
    30.     mov ax, [78h + 2]
    31.     mov es, ax
    32.     ; инициализируем DMA
    33.     mov si, KERNEL_BASE
    34.     call DMA_init
    35.     ; врубаем мотор
    36.     call FDD_init
    37.     ; ждём запуска мотора, для этого входим в пустой цикл
    38.     mov cx, 5000
    39. wait_motor:
    40.     loop wait_motor
    41.     ; устанавливаем скорость в 500 кб/с
    42.     mov dx, FLOP_DIR
    43.     xor al, al
    44.     out dx, al
    45.     ; рекалибровка
    46.     call FDD_recalibrate
    47.     jc error
    48.     ; переходим к второму сектору
    49.     call FDD_seek
    50.     jc error
    51.     ; читаем второй сектор и сохраняем его в память
    52.     call FDD_read_sector
    53.     jc error
    54.     call FDD_stop
    55. stop:
    56.     jmp stop
    57. error:
    58.     call print_error
    59.     jmp stop
    60.  
    61. ; обработчик прерываний от дисковода
    62. irq6_handler:
    63.     ; ставим флаг того, что подали сигнал
    64.     mov [int_active], 1
    65.     iret
    66.  
    67. ; Инициализация DMA
    68. DMA_init:
    69.     cli
    70.     ; команда READ DMA
    71.     mov al, 47h
    72.     ; сброс указателя байта
    73.     out 12, al
    74.     ; утсанавливаем режим работы контроллера DMA
    75.     out 11, al
    76.     ; загружаем линейное смещение нашего буфера, тк ds = 0, то модно избежать лишних вычислений с базой сегмента
    77.     mov ax, si
    78.     ; младший байт адреса буфера
    79.     out 4, al
    80.     mov ah, al
    81.     ; старший байт адреса буфера
    82.     out 4, al
    83.     ; номер страницы, у нас он 0, тк ds = 0, а регистры 16-юитные
    84.     xor al, al
    85.     out 81h, al
    86.     ; загружаем размер данных - 1
    87.     mov ax, KERNEL_SIZE
    88.     dec ax
    89.     ; младший байт размера данных
    90.     out 5, al
    91.     mov ah, al
    92.     ; старший байт размера данных
    93.     out 5, al
    94.     ; разрешаем наш проинициализированный канал
    95.     mov al, 2
    96.     out 10, al
    97.     sti
    98.     ret
    99.  
    100. ; Инициализация FDD
    101. FDD_init:
    102.     mov al, 00011100b ; Motor0, Reset, DMA
    103.     mov dx, FLOP_DOR
    104.     out dx, al
    105.     ret
    106.  
    107. ; Остановка FDD
    108. FDD_stop:
    109.     mov al, 00001100b ; DMA, Reset
    110.     mov dx, FLOP_DOR
    111.     ret
    112.  
    113. ; Отсылка байта в порт данных
    114. ;   ah - байт для пересылки
    115. FDD_send_byte:
    116.     clc
    117.     mov dx, FLOP_MSR
    118.     mov cx, 50000
    119. FDD_send_byte_loop:
    120.     dec cx
    121.     jz FDD_send_byte_err
    122.     in al, dx
    123.     and al, 11000000b
    124.     cmp al, 10000000b
    125.     jne FDD_send_byte_loop
    126.     mov dx, FLOP_FIFO
    127.     mov al, ah
    128.     out dx, al
    129.     ret
    130. FDD_send_byte_err:
    131.     stc
    132.     ret
    133.  
    134. ; Чтение байта из порта данных
    135. ;   ah - байт результата
    136. FDD_recv_byte:
    137.     clc
    138.     mov dx, FLOP_MSR
    139.     mov cx, 50000
    140. FDD_recv_byte_loop:
    141.     dec cx
    142.     jz FDD_recv_byte_err
    143.     in al, dx
    144.     and al, 11000000b
    145.     cmp al, 11000000b
    146.     jne FDD_recv_byte_loop
    147.     mov dx, FLOP_FIFO
    148.     in al, dx
    149.     mov ah, al
    150.     ret
    151. FDD_recv_byte_err:
    152.     stc
    153.     ret
    154.  
    155. ; Посылаем команду рекалибровки
    156. FDD_recalibrate:
    157.     mov ah, 00000111b
    158.     call FDD_send_byte
    159.     jc FDD_recalibrate_exit
    160.     mov ah, 00000011b
    161.     call FDD_send_byte
    162.     jc FDD_recalibrate_exit
    163.     call FDD_wait_end
    164. FDD_recalibrate_exit:
    165.     ret
    166.  
    167. FDD_seek:
    168.     mov ah, 00001111b
    169.     call FDD_send_byte
    170.     jc FDD_seek_exit
    171.     mov ah, 00000000b
    172.     call FDD_send_byte
    173.     jc FDD_seek_exit
    174.     mov ah, 00000000b
    175.     call FDD_send_byte
    176.     jc FDD_seek_exit
    177.     call FDD_wait_end
    178. FDD_seek_exit:
    179.     ret
    180.  
    181. ; Читаем сектор
    182. FDD_read_sector:
    183.     ; в bx - адрес DPT
    184.     mov bx, [DPT_table]
    185.     ; READ DATA, Code 1
    186.     mov ah, 01000110b
    187.     call FDD_send_byte
    188.     jc FDD_read_sector_exit
    189.     ; READ DATA, Code 2
    190.     xor ah, ah
    191.     call FDD_send_byte
    192.     jc FDD_read_sector_exit
    193.     ; Cyl
    194.     call FDD_send_byte
    195.     jc FDD_read_sector_exit
    196.     ; Head
    197.     call FDD_send_byte
    198.     jc FDD_read_sector_exit
    199.     ; Sector
    200.     inc ah
    201.     call FDD_send_byte
    202.     jc FDD_read_sector_exit
    203.     ; Sector Size
    204.     mov ah, [es: bx + 3]
    205.     call FDD_send_byte
    206.     jc FDD_read_sector_exit
    207.     ; End of track
    208.         mov ah, [es: bx + 4]
    209.     mov ah, 13h
    210.     call FDD_send_byte
    211.     jc FDD_read_sector_exit
    212.     ; GPL
    213.     mov ah, [es: bx + 5]
    214.     call FDD_send_byte
    215.     jc FDD_read_sector_exit
    216.     ; DTL
    217.     mov ah, 0FFh
    218.     call FDD_send_byte
    219.     jc FDD_read_sector_exit
    220.     ; ждём когда закончится фаза исполнения
    221.     call FDD_wait_end
    222.     ; ST0
    223.         call FDD_recv_byte
    224.         jc FDD_read_sector_exit
    225.  
    226.         mov al, ah
    227.     call print_byte
    228. ;        test ah, 11111100b
    229. ;        jnz FDD_read_sector_error
    230. FDD_read_sector_exit:
    231.     ret
    232. FDD_read_sector_error:
    233.     stc
    234.     ret
    235.  
    236. ; Ждём завершения опреации
    237. FDD_wait_end:
    238.     mov dx, FLOP_MSR
    239. FDD_wait_end_loop:
    240.     in al, dx
    241.     test al, 10000000b
    242.     jnz FDD_wait_end_exit
    243.     cmp [int_active], 0
    244.     jnz FDD_wait_end_exit
    245.     jmp FDD_wait_end_loop
    246. FDD_wait_end_exit:
    247.     mov [int_active], 0
    248.     ret
    249.  
    250. print_byte:
    251.     push ax
    252.     shr al, 4
    253.     call print_byte_
    254.     pop ax
    255.     and al, 0Fh
    256. print_byte_:
    257.     add al, 90h
    258.     daa
    259.     adc al, 40h
    260.     daa
    261.     mov ah, 0Eh
    262.     int 10h
    263.     retn
    264.  
    265. putstr:
    266.     lodsb
    267.     or al,al
    268.     jz  putstrd
    269.     mov ah, 0x0E
    270.     mov bx, 0x0007
    271.     int 0x10
    272.     jmp putstr
    273. putstrd:
    274.     retn
    275.  
    276. print_error:
    277.     mov si, error_msg
    278.     call putstr
    279.     ret
    280.  
    281. int_active  db 0
    282. error_msg   db 'Error.',0
    283. DPT_table   dw 0
    284.  
    285. rb 7C00h + 512 - 2 - $
    286. db 055h,0AAh
     
  2. rei3er

    rei3er maxim

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    917
    Адрес:
    minsk
    цель то у тебя - многопроцессорность
    так что не парься с флопиком :derisive:
     
  3. asmfan

    asmfan New Member

    Публикаций:
    0
    Регистрация:
    10 июл 2006
    Сообщения:
    1.004
    Адрес:
    Abaddon
    сегмент или смещение записываем?
    а я б xchg делал и сохранял бы куда-нить исходн. знач-я. и при нуже восстанавливал. (просто хороший тон;)

    И всё-таки почему 0Eh * 4? 14 прерывание?
     
  4. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    одно другому не мешает :)
    и сегмент, и смещение. база сегмента = 0.
    была такая мысля, однако где мне его восстанавливать? я же не в DOS'e всё таки работаю.
    и irq6 номер вектора 14ый.
     
  5. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    Некоторые продвижения всё таки есть ;)
    Тот код не работал тк "забыл" послать End-Of-Interrupt контроллеру прерываний в обработчике irq6.
    Теперь у меня не работает рекалибровка, точнее работает, но когда я посылаю SENSE INTERRUPT STATUS, в st0 мне на боксе(bochs) возврашается 0x71, на VMWare - 0x61, и только qemu 0x21, что и должно быть. в чём дело? :\

    Код (Text):
    1. use16
    2.  
    3. org 7C00h
    4.  
    5. STACK_BASE  equ 9000h ; заносим в ss
    6. STACK_PTR   equ 9F00h ; заносим в sp
    7. KERNEL_BASE equ 600h  ; куда будем сохранять ядро
    8. KERNEL_SIZE equ 512   ; размер ядра в байтах
    9.  
    10. include "..\drivers\floppy\floppy.inc"
    11.  
    12. start:
    13.     ; отключаем прерывания
    14.     cli
    15.     ; ds = cs = 0
    16.     push cs
    17.     pop ds
    18.     ; настраиваем стек
    19.     mov ax, STACK_BASE
    20.     mov ss, ax
    21.     mov sp, STACK_PTR
    22.     ; ставим свой обработчик IRQ6
    23.     mov word [0Eh * 4], irq6_handler
    24.     mov word [0Eh * 4 + 2], 0
    25.     ; ставим свой обработчик IRQ0
    26.     mov word [08h * 4], irq0_handler
    27.     mov word [08h * 4 + 2], 0
    28.     ; включаем прерывания
    29.     sti
    30.     ; сохраняем адрес DPT, а в es ее сегмент
    31.     mov ax, [78h]
    32.     mov [DPT_table], ax
    33.     mov ax, [78h + 2]
    34.     mov es, ax
    35.     ; инициализируем DMA
    36.     mov si, KERNEL_BASE
    37.     call DMA_init
    38.     ; врубаем мотор
    39.     call FDD_init
    40.     ; ждём запуска мотора, ~1000ms
    41.     mov bh, 18
    42.     call delay
    43.     ; устанавливаем скорость в 500 кб/с
    44.     mov dx, FLOP_DIR
    45.     xor al, al
    46.     out dx, al
    47.     ; 3 попытки рекалибровать
    48.     mov cx, 3
    49. recalibre_retry:
    50.     dec cx
    51.  
    52.     mov dx, FLOP_DOR
    53.     in al, dx
    54.     call print_byte
    55.  
    56.     ; рекалибровка
    57.     call FDD_recalibrate
    58.     jc error
    59.  
    60.     mov al, 30h
    61.     call print_byte
    62.  
    63.     ; проверяем успешность опреации
    64.     call FDD_sense_interrupt_status
    65.     jnc recalibre_success
    66.     ; после трех неудачных попыток рекалибровать, выходим
    67.     test cx, cx
    68.     jz error
    69.     jmp recalibre_retry
    70. recalibre_success:
    71.  
    72.     mov al, 40h
    73.     call print_byte
    74.  
    75. adfad:
    76.     jmp adfad
    77.  
    78.     ; переходим к второму сектору
    79. ;        call FDD_seek
    80. ;        jc error
    81.  
    82. ;        mov al, 50h
    83. ;        call print_byte
    84.  
    85.     ; задержка для установки головки в новое положение
    86. ;        mov bh, 1
    87. ;        call delay
    88.  
    89. ;        mov al, 60h
    90. ;        call print_byte
    91.  
    92.     ; читаем второй сектор и сохраняем его в память
    93. ;        call FDD_read_sector
    94. ;        jc error
    95. ;        call FDD_stop
    96. stop:
    97.     jmp stop
    98. error:
    99.     call print_error
    100.     jmp stop
    101.  
    102. ; Задержка
    103. ;   bh - на сколько в (1/18.2)с отрезках
    104. delay:
    105.     mov [t_count], 0
    106. delay_loop:
    107.     cmp [t_count], bh
    108.     jne delay_loop
    109.     ret
    110.  
    111. send_EOI:
    112.     push ax
    113.     mov  al, 00100000b
    114.     out  20h, al
    115.     out  0A0h, al
    116.     pop ax
    117.     ret
    118.  
    119. ; обработчик прерываний от дисковода
    120. irq6_handler:
    121.     ; ставим флаг того, что подали сигнал
    122.     mov [int_active], 1
    123.     call send_EOI
    124.     iret
    125.  
    126. ; обработчик прерываний таймера
    127. irq0_handler:
    128.     inc [t_count]
    129.     call send_EOI
    130.     iret
    131.  
    132. ; Инициализация DMA
    133. DMA_init:
    134.     cli
    135.     ; команда READ DMA
    136.     mov al, 47h
    137.     ; сброс указателя байта
    138.     out 12, al
    139.     ; утсанавливаем режим работы контроллера DMA
    140.     out 11, al
    141.     ; загружаем линейное смещение нашего буфера, тк ds = 0, то модно избежать лишних вычислений с базой сегмента
    142.     mov ax, si
    143.     ; младший байт адреса буфера
    144.     out 4, al
    145.     mov ah, al
    146.     ; старший байт адреса буфера
    147.     out 4, al
    148.     ; номер страницы, у нас он 0, тк ds = 0, а регистры 16-юитные
    149.     xor al, al
    150.     out 81h, al
    151.     ; загружаем размер данных - 1
    152.     mov ax, KERNEL_SIZE - 1
    153.     ; младший байт размера данных
    154.     out 5, al
    155.     mov ah, al
    156.     ; старший байт размера данных
    157.     out 5, al
    158.     ; разрешаем наш проинициализированный канал
    159.     mov al, 2
    160.     out 10, al
    161.     sti
    162.     ret
    163.  
    164. ; Инициализация FDD
    165. FDD_init:
    166.     mov dx, FLOP_DOR
    167.     xor ax, ax
    168.     out dx, al
    169.     mov al, 00011100b ; Motor0, Reset, DMA
    170.     out dx, al
    171.     ret
    172.  
    173. ; Остановка FDD
    174. FDD_stop:
    175.     mov al, 00001100b ; DMA, Reset
    176.     mov dx, FLOP_DOR
    177.     out dx, al
    178.     xor al, al
    179.     out dx, al
    180.     ret
    181.  
    182. ; Отсылка байта в порт данных
    183. ;   ah - байт для пересылки
    184. FDD_send_byte:
    185.     pusha
    186.     clc
    187.     mov dx, FLOP_MSR
    188.     mov cx, 50000
    189. FDD_send_byte_loop:
    190.     dec cx
    191.     jz FDD_send_byte_err
    192.     in al, dx
    193.     and al, 11000000b
    194.     cmp al, 10000000b
    195.     jne FDD_send_byte_loop
    196.     mov dx, FLOP_FIFO
    197.     mov al, ah
    198.     out dx, al
    199.     popa
    200.     ret
    201. FDD_send_byte_err:
    202.     stc
    203.     popa
    204.     ret
    205.  
    206. ; Чтение байта из порта данных
    207. ;   ah - байт результата
    208. FDD_recv_byte:
    209.     push dx
    210.     push cx
    211.     clc
    212.     mov dx, FLOP_MSR
    213.     mov cx, 50000
    214. FDD_recv_byte_loop:
    215.     dec cx
    216.     jz FDD_recv_byte_err
    217.     in al, dx
    218.     and al, 11000000b
    219.     cmp al, 11000000b
    220.     jne FDD_recv_byte_loop
    221.     mov dx, FLOP_FIFO
    222.     in al, dx
    223.     mov ah, al
    224. FDD_recx_byte_exit:
    225.     pop dx
    226.     pop cx
    227.     ret
    228. FDD_recv_byte_err:
    229.     stc
    230.     jmp FDD_recx_byte_exit
    231.  
    232. ; Посылаем команду SENSE INTERRUPT STATUS
    233. FDD_sense_interrupt_status:
    234.     ; код команды
    235.     mov ah, 00001000b
    236.     call FDD_send_byte
    237.     jc FDD_sense_interrupt_status_exit
    238.     ; читаем st0
    239.     call FDD_recv_byte
    240.     jc FDD_sense_interrupt_status_exit
    241.  
    242.     push ax
    243.     mov al, ah
    244.     call print_byte
    245.     pop ax
    246.  
    247.     push ax
    248.     ; читаем PCN
    249.     call FDD_recv_byte
    250.     jc FDD_sense_interrupt_status_exit
    251.     pop ax
    252.     and ah, 11110000b
    253.     cmp ah, 00100000b
    254.     jne FDD_sense_interrupt_status_error
    255. FDD_sense_interrupt_status_exit:
    256.     ret
    257. FDD_sense_interrupt_status_error:
    258.     stc
    259.     ret
    260.  
    261. ; Посылаем команду рекалибровки
    262. FDD_recalibrate:
    263.     ; код команды
    264.     mov ah, 00000111b
    265.     call FDD_send_byte
    266.     jc FDD_recalibrate_exit
    267.     ; 0 0 0 0 0 0 DS1 DS0
    268.     mov ah, 00000001b
    269.     call FDD_send_byte
    270.     jc FDD_recalibrate_exit
    271.     call FDD_wait_end
    272. FDD_recalibrate_exit:
    273.     ret
    274.  
    275. ; Посылаем команду SEEK
    276. FDD_seek:
    277.     mov ah, 00001111b
    278.     call FDD_send_byte
    279.     jc FDD_seek_exit
    280.     mov ah, 00000000b
    281.     call FDD_send_byte
    282.     jc FDD_seek_exit
    283.     mov ah, 00000000b
    284.     call FDD_send_byte
    285.     jc FDD_seek_exit
    286.     call FDD_wait_end
    287. FDD_seek_exit:
    288.     ret
    289.  
    290. ; Читаем сектор
    291. FDD_read_sector:
    292.     ; в bx - адрес DPT
    293.     mov bx, [DPT_table]
    294.     ; READ DATA, Code 1
    295.     mov ah, 26h
    296.     call FDD_send_byte
    297.     jc FDD_read_sector_exit
    298.     ; READ DATA, Code 2
    299.     xor ah, ah
    300.     call FDD_send_byte
    301.     jc FDD_read_sector_exit
    302.     ; Cyl
    303.     call FDD_send_byte
    304.     jc FDD_read_sector_exit
    305.     ; Head
    306.     call FDD_send_byte
    307.     jc FDD_read_sector_exit
    308.     ; Sector
    309.     inc ah
    310.     call FDD_send_byte
    311.     jc FDD_read_sector_exit
    312.     ; Sector Size
    313.     mov ah, [es: bx + 3]
    314.     call FDD_send_byte
    315.     jc FDD_read_sector_exit
    316.     ; End of track
    317. ;        mov ah, [es: bx + 4]
    318.     mov ah, 13h
    319.     call FDD_send_byte
    320.     jc FDD_read_sector_exit
    321.     ; GPL
    322.     mov ah, [es: bx + 5]
    323.     call FDD_send_byte
    324.     jc FDD_read_sector_exit
    325.     ; DTL
    326.     mov ah, 0FFh
    327.     call FDD_send_byte
    328.     jc FDD_read_sector_exit
    329.     ; ждём когда закончится фаза исполнения
    330.     mov al, 10h
    331.     call print_byte
    332.  
    333.     call FDD_wait_end
    334.     ; ST0
    335. ;        call FDD_recv_byte
    336. ;        jc FDD_read_sector_exit
    337.  
    338. ;        mov al, ah
    339.     mov al, 10h
    340.     call print_byte
    341. ;        test ah, 11111100b
    342. ;        jnz FDD_read_sector_error
    343. FDD_read_sector_exit:
    344.     ret
    345. FDD_read_sector_error:
    346.     stc
    347.     ret
    348.  
    349. ; Ждём завершения опреации
    350. FDD_wait_end:
    351.     mov dx, FLOP_MSR
    352. FDD_wait_end_loop:
    353. ;        in al, dx
    354. ;        test al, 10000000b
    355. ;        jnz FDD_wait_end_exit
    356.     cmp [int_active], 1
    357.     je FDD_wait_end_exit
    358.     jmp FDD_wait_end_loop
    359. FDD_wait_end_exit:
    360.     mov [int_active], 0
    361.     ret
    362.  
    363. print_byte:
    364.     push ax
    365.     shr al, 4
    366.     call print_byte_
    367.     pop ax
    368.     and al, 0Fh
    369. print_byte_:
    370.     add al, 90h
    371.     daa
    372.     adc al, 40h
    373.     daa
    374.     mov ah, 0Eh
    375.     int 10h
    376.     retn
    377.  
    378. putstr:
    379.     lodsb
    380.     or al,al
    381.     jz  putstrd
    382.     mov ah, 0x0E
    383.     mov bx, 0x0007
    384.     int 0x10
    385.     jmp putstr
    386. putstrd:
    387.     retn
    388.  
    389. print_error:
    390.     mov si, error_msg
    391.     call putstr
    392.     ret
    393.  
    394. int_active  db 0
    395. t_count     db 0
    396. error_msg   db 'Error.',0
    397. DPT_table   dw 0
    398.  
    399. rb 7C00h + 512 - 2 - $
    400. db 055h,0AAh
     
  6. rei3er

    rei3er maxim

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    917
    Адрес:
    minsk
    n0name
    а на реальной машине?
     
  7. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    под рукой 4 машины, и ни на одной нет флоппика, прогресс, йопт.
     
  8. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    Вроде всё сделал :)
    По идее должно работать с разными дисководами - EOT, GPL, размер сектора берутся из DPT. Правда дисковод должен быть первым.
    поддержка загрузчика второго уровня произвольного размера(конечно ограниченного одним треком ;) ).
    Код (Text):
    1. use16
    2.  
    3. org 7C00h
    4.  
    5. STACK_BASE  equ 9000h ; заносим в ss
    6. STACK_PTR   equ 9F00h ; заносим в sp
    7. KERNEL_SIZE equ 1024  ; размер ядра в байтах
    8.  
    9. include "..\drivers\floppy\floppy.inc"
    10. include "..\kernel\kernel.inc"
    11.  
    12. start:
    13.     ; отключаем прерывания
    14.     cli
    15.     ; ds = cs = 0
    16.     push cs
    17.     pop ds
    18.     ; настраиваем стек
    19.     mov ax, STACK_BASE
    20.     mov ss, ax
    21.     mov sp, STACK_PTR
    22.     ; ставим свой обработчик IRQ6
    23.     xor cx, cx
    24.     mov word [0Eh * 4], irq6_handler
    25.     mov word [0Eh * 4 + 2], cx
    26.     ; ставим свой обработчик IRQ0
    27.     mov word [08h * 4], irq0_handler
    28.     mov word [08h * 4 + 2], cx
    29.     ; включаем прерывания
    30.     sti
    31.     ; сохраняем адрес DPT, а в es ее сегмент
    32.     mov ax, [78h]
    33.     mov [DPT_table], ax
    34.     mov ax, [78h + 2]
    35.     mov es, ax
    36.     ; врубаем мотор
    37.     call FDD_init
    38.     ; ждём запуска мотора, ~1000ms
    39.     mov bh, 18
    40.     call delay
    41.     ; устанавливаем скорость в 500 кб/с
    42.     mov dx, FLOP_DIR
    43.     xor al, al
    44.     out dx, al
    45.     ; 3 попытки рекалибровать
    46.     mov cl, 3
    47. recalibre_retry:
    48.     ; рекалибровка
    49.     call FDD_recalibrate
    50.     jc error
    51.     ; проверяем успешность опреации
    52.     call FDD_sense_interrupt_status
    53.     jnc recalibre_success
    54.     ; после трех неудачных попыток рекалибровать, выходим
    55.     loop recalibre_retry
    56.     jmp error
    57. recalibre_success:
    58.     ; переходим к первой дорожке
    59.     call FDD_seek
    60.     jc error
    61.     call FDD_sense_interrupt_status
    62.     jc error
    63.     ; задержка для установки головки в новое положение
    64.     mov bh, 1
    65.     call delay
    66.     ; считаем размер сектора в байтах
    67.     mov bx, [DPT_table]
    68.     mov cl, [es: bx + 3]
    69.     mov bx, 128
    70.     shl bx, cl
    71.     ; считаем размер ядра в секторах
    72.     mov ax, KERNEL_SIZE
    73.     xor dx, dx
    74.     div bx
    75.     ; в ch - номер последнего сектора ядра, в cl - первого - 1
    76.     inc al
    77.     mov ch, al
    78.     mov cl, 1
    79.     ; читаем ядро в память
    80.     mov si, KERNEL_BASE
    81. read_kernel:
    82.     call DMA_init
    83.     inc cl
    84.     call FDD_read_sector
    85.     jc error
    86.     add si, bx
    87.     cmp cl, ch
    88.     jne read_kernel
    89.     call FDD_stop
    90.     jmp KERNEL_BASE
    91. error:
    92.     mov si, error_msg
    93.     call putstr
    94. stop:
    95.     jmp stop
    96.  
    97. ; Задержка
    98. ;   bh - на сколько в (1/18.2)с отрезках
    99. delay:
    100.     mov [t_count], 0
    101. delay_loop:
    102.     cmp [t_count], bh
    103.     jne delay_loop
    104.     ret
    105.  
    106. send_EOI:
    107.     push ax
    108.     mov  al, 00100000b
    109.     out  20h, al
    110.     pop ax
    111.     iret
    112.  
    113. ; обработчик прерываний от дисковода
    114. irq6_handler:
    115.     ; ставим флаг того, что подали сигнал
    116.     mov [int_active], 1
    117.     jmp send_EOI
    118.  
    119. ; обработчик прерываний таймера
    120. irq0_handler:
    121.     inc [t_count]
    122.     jmp send_EOI
    123.  
    124. ; Инициализация DMA
    125. DMA_init:
    126.     cli
    127. ;        mov al, 0
    128. ;        out 10, al
    129.     ; команда READ DMA
    130.     mov al, 46h
    131.     ; сброс указателя байта
    132.     out 12, al
    133.     ; утсанавливаем режим работы контроллера DMA
    134.     out 11, al
    135.     ; загружаем линейное смещение нашего буфера, тк ds = 0, то модно избежать лишних вычислений с базой сегмента
    136.     mov ax, si
    137.     ; младший байт адреса буфера
    138.     out 4, al
    139.     mov al, ah
    140.     ; старший байт адреса буфера
    141.     out 4, al
    142.     ; номер страницы, у нас он 0, тк ds = 0, а регистры 16-юитные
    143.     xor al, al
    144.     out 81h, al
    145.     ; загружаем размер данных - 1
    146.     mov ax, bx
    147.     dec ax
    148.     ; младший байт размера данных
    149.     out 5, al
    150.     mov al, ah
    151.     ; старший байт размера данных
    152.     out 5, al
    153.     ; разрешаем наш проинициализированный канал
    154.     mov al, 2
    155.     out 10, al
    156.     sti
    157.     ret
    158.  
    159. ; Инициализация FDD
    160. FDD_init:
    161.     mov dx, FLOP_DOR
    162.     xor ax, ax
    163.     out dx, al
    164.     mov al, 00011100b ; Motor0, Reset, DMA
    165.     out dx, al
    166.     ret
    167.  
    168. ; Остановка FDD
    169. FDD_stop:
    170.     mov al, 00001100b ; DMA, Reset
    171.     mov dx, FLOP_DOR
    172.     out dx, al
    173.     xor al, al
    174.     out dx, al
    175.     ret
    176.  
    177. ; Отсылка байта в порт данных
    178. ;   al - байт для пересылки
    179. FDD_send_byte:
    180.     pusha
    181.     clc
    182.     mov dx, FLOP_MSR
    183.     mov cx, 0FFFFh
    184.     push ax
    185. FDD_send_byte_loop:
    186.     in al, dx
    187.     and al, 11000000b
    188.     cmp al, 10000000b
    189.     je FDD_send_byte_rdy
    190.     loop FDD_send_byte_loop
    191. FDD_send_byte_rdy:
    192.     pop ax
    193.     mov dx, FLOP_FIFO
    194.     out dx, al
    195.     popa
    196.     ret
    197. FDD_send_byte_err:
    198.     stc
    199.     popa
    200.     ret
    201.  
    202. ; Чтение байта из порта данных
    203. ;   al - байт результата
    204. FDD_recv_byte:
    205.     push cx
    206.     clc
    207.     mov dx, FLOP_MSR
    208.     mov cx, 0FFFFh
    209. FDD_recv_byte_loop:
    210.     in al, dx
    211.     and al, 11000000b
    212.     cmp al, 11000000b
    213.     jne FDD_recv_byte_rdy
    214.     loop FDD_recv_byte_loop
    215. FDD_recv_byte_rdy:
    216.     mov dx, FLOP_FIFO
    217.     in al, dx
    218. FDD_recv_byte_exit:
    219.     pop cx
    220.     ret
    221. FDD_recv_byte_err:
    222.     stc
    223.     pop cx
    224.     ret
    225.  
    226. ; Посылаем команду SENSE INTERRUPT STATUS
    227. FDD_sense_interrupt_status:
    228.     ; код команды
    229.     mov al, 00001000b
    230.     call FDD_send_byte
    231.     jc FDD_sense_interrupt_status_exit
    232.     ; читаем st0
    233.     call FDD_recv_byte
    234.     jc FDD_sense_interrupt_status_exit
    235.     and al, 11110000b
    236.     cmp al, 00100000b
    237.     jne FDD_sense_interrupt_status_error
    238.     ; читаем PCN
    239.     call FDD_recv_byte
    240.     jc FDD_sense_interrupt_status_exit
    241.     ; PCN должен быть равен 0
    242.     test al, al
    243.     jnz FDD_sense_interrupt_status_error
    244. FDD_sense_interrupt_status_exit:
    245.     ret
    246. FDD_sense_interrupt_status_error:
    247.     stc
    248.     ret
    249.  
    250. ; Посылаем команду рекалибровки
    251. FDD_recalibrate:
    252.     ; код команды
    253.     mov al, 00000111b
    254.     call FDD_send_byte
    255.     jc FDD_recalibrate_exit
    256.     ; 0 0 0 0 0 0 DS1 DS0
    257.     xor al, al ; 00000000b
    258.     call FDD_send_byte
    259.     jc FDD_recalibrate_exit
    260.     call FDD_wait_end
    261. FDD_recalibrate_exit:
    262.     ret
    263.  
    264. ; Посылаем команду SEEK
    265. FDD_seek:
    266.     mov al, 00001111b
    267.     call FDD_send_byte
    268.     jc FDD_seek_exit
    269.     xor al, al ; 00000000b
    270.     call FDD_send_byte
    271.     jc FDD_seek_exit
    272.     call FDD_send_byte
    273.     jc FDD_seek_exit
    274.     call FDD_wait_end
    275. FDD_seek_exit:
    276.     ret
    277.  
    278. ; Читаем сектор
    279. ;   cl - номер сектора
    280. FDD_read_sector:
    281.     pusha
    282.     ; в bx - адрес DPT
    283.     mov bx, [DPT_table]
    284.     ; READ DATA, Code 1
    285.     mov al, 66h
    286.     call FDD_send_byte
    287.     jc FDD_read_sector_exit
    288.     ; READ DATA, Code 2
    289.     xor al, al
    290.     call FDD_send_byte
    291.     jc FDD_read_sector_exit
    292.     ; Cyl
    293.     call FDD_send_byte
    294.     jc FDD_read_sector_exit
    295.     ; Head
    296.     call FDD_send_byte
    297.     jc FDD_read_sector_exit
    298.     ; Sector
    299.     mov al, cl
    300.     call FDD_send_byte
    301.     jc FDD_read_sector_exit
    302.     ; Sector Size
    303.     mov al, [es: bx + 3]
    304.     call FDD_send_byte
    305.     jc FDD_read_sector_exit
    306.     ; End of track
    307.     mov al, [es: bx + 4]
    308.     call FDD_send_byte
    309.     jc FDD_read_sector_exit
    310.     ; GPL
    311.     mov al, [es: bx + 5]
    312.     call FDD_send_byte
    313.     jc FDD_read_sector_exit
    314.     ; DTL
    315.     mov al, 0FFh
    316.     call FDD_send_byte
    317.     jc FDD_read_sector_exit
    318.     ; ждём когда закончится фаза исполнения
    319.     call FDD_wait_end
    320.     ; ST0
    321.     call FDD_recv_byte
    322.     jc FDD_read_sector_exit
    323.     test al, 11111100b
    324.     jnz FDD_read_sector_error
    325.     ; ST1 & ST2
    326.     xor cx, cx
    327.     mov cl, 2
    328. FDD_read_sector_STX:
    329.     call FDD_recv_byte
    330.     jc FDD_read_sector_exit
    331.     test al, al
    332.     jnz FDD_read_sector_error
    333.     loop FDD_read_sector_STX
    334.     ; C H R N
    335.     mov cl, 4
    336. FDD_read_sector_result:
    337.     call FDD_recv_byte
    338.     loop FDD_read_sector_result
    339. FDD_read_sector_exit:
    340.     popa
    341.     ret
    342. FDD_read_sector_error:
    343.     stc
    344.     popa
    345.     ret
    346.  
    347. ; Ждём завершения опреации
    348. FDD_wait_end:
    349.     mov dx, FLOP_MSR
    350. FDD_wait_end_loop:
    351.     cmp [int_active], 1
    352.     jne FDD_wait_end_loop
    353. FDD_wait_end_exit:
    354.     mov [int_active], 0
    355.     ret
    356.  
    357. putstr:
    358.     lodsb
    359.     or al,al
    360.     jz  putstrd
    361.     mov ah, 0x0E
    362.     mov bx, 0x0007
    363.     int 0x10
    364.     jmp putstr
    365. putstrd:
    366.     retn
    367.  
    368. int_active  db 0
    369. t_count     db 0
    370. DPT_table   dw 0
    371. error_msg   db 'Error',0
    372.  
    373. rb 7C00h + 512 - 2 - $
    374. db 055h,0AAh
    Загрузчик занимает полностью сектор, так что увеличение функционала не планируется ;)
     
  9. rei3er

    rei3er maxim

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    917
    Адрес:
    minsk
    n0name
    прикольно
    осталось только с многопроцессорностью разобраться :))
     
  10. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    я эмулятор нормальный не могу найти/настроить чтобы эмулировал проц с мультиядерностью, хотя там мало чем отличается от MP, но для SMP не могу найти как получить количество процессоров.
     
  11. rei3er

    rei3er maxim

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    917
    Адрес:
    minsk
    n0name
    bochs поддерживает мультипроцессорность (мультиядерность)
    в програмной модели вообще нет разницы между многопроцессорностью/мультиядерностью/Hyper Threading-ом
    SIPI от BTP-процессора +
    Код (Text):
    1. count:
    2.     dd 0
    3. ...
    4. lock inc dword [count]
    не помогает?
     
  12. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    разве?
    я думал что ядро изменяет CoreID, а процессор PackageID в APIC_ID.
    после перекомпиляции с соответствующим флагом он отказывается загружать дискеты, любые.
     
  13. rei3er

    rei3er maxim

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    917
    Адрес:
    minsk
    как так?
    у меня вроде все нормально
    правда под Linux...
     
  14. rei3er

    rei3er maxim

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    917
    Адрес:
    minsk
    APIC_ID в смысле регистр Local APIC?
     
  15. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    ну как я понял этот ID идентифицирует логический процессор в системе и выглядит примерно так:
    |Reserved|PAKAGE_ID|CORE_ID|SMT_ID|

    PAKAGE_ID это как раз номер физического процессора.
    а для посылки IPI не надо указывать ID процов?
     
  16. rei3er

    rei3er maxim

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    917
    Адрес:
    minsk
    есть понятие destination shorthand (2 бита в IPI сообщении)
    комбинация 11 соответствует широковещательному сообщению "all excluding self"
    при этом поле destination field IPI-сообщения игнорируется
     
  17. rei3er

    rei3er maxim

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    917
    Адрес:
    minsk
    откуда информация?
     
  18. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    круто, буду знать.
    только мне нужна информация об этом для того, чтобы решить, UP или MP система.
    Intel, 3A, 7.10
     
  19. rei3er

    rei3er maxim

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    917
    Адрес:
    minsk
    точно, есть такое :)
    я бы так сделал:
    1. Посылаем широковещательный SIPI,
    2. В соответствующем коде (куда передается управление):
    а) Получаем значение APIC ID
    б) Из этого значения получам Package ID
    в) Сравниваем только что найденное значение с последним, если они не совпадают - это MP система, в противном случае пока UP (многоядерная)
     
  20. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    а тогда случайно не стартуют все логические процессы? ;)
    имхо лучше оперировать логическими процессорами, на них же всё и построено, а количество физических процов мне и надо для того чтобы найти количество логических.
    PS: UP != MultiCore, multicore тоже имхо относятся к MP, так же как и HT.