Опять все таже старая проблема с поиском активного диска....

Тема в разделе "WASM.OS.DEVEL", создана пользователем JucED, 14 апр 2011.

  1. JucED

    JucED New Member

    Публикаций:
    0
    Регистрация:
    8 янв 2010
    Сообщения:
    23
    Здравствуйте! Я вот написал такой MBR - он считывает текущую минуту, секунду, час, месяц, день месяца, год из CMOS в память начиная с 7c03h. Затем используя int 13h я обновляю нулевой сектор. Т.е. теперь в памяти и в нулевом секторе у меня хранится считанная дата. И потом читаю с дисков Master\Slave\Primary\Secondary нулевой сектор и сверяю дату в них с датой которая лежит в памяти, если они равны - то этот диск активный, но вот что-то нифига не получается, при опросе дисков через порты я не стал измерять время для того чтобы не повесить прогу в бесконечном ожидании несуществующего диска, я просто взял цикл который повторяется 100 раз. И он у меня постоянно выходит с ошибкой таймаута.
    А задумано было так - код находит активный диск (процедура проверки делает mov dh,0ffh) и на экран выводится адрес порта и номер диска на канале.

    Ткните пожалуйста пальцем где я допустил ошибку.

    Код (Text):
    1. .386
    2.  
    3. code segment para public "code" use16
    4. main proc
    5.     assume cs:code,ss:stk
    6.     org 7c00h
    7.    
    8.     jmp MBR_2_start
    9.    
    10. ;-------------------- Данные --------------------
    11. Stek_Adress    equ 0600h                  ; адрес стэка
    12.  
    13. MBR_2_Data       db 0,0,0,0,0,0,0           ; секунда, минута, час, день месяца, месяц, год, век
    14. MBR_2_Aktiv      db 1                       ; индекс активного тома
    15. MBR_2_Tom1       db 0, 0, 0, 0, 0, 64h      ; адрес (LBA) заголовка тома 1
    16. MBR_2_Tom1_Razm  db 0                       ; размер ядра тома 1
    17. MBR_2_Tom2       db 6 dup(0)                ; адрес (LBA) заголовка тома 2
    18. MBR_2_Tom2_Razm  db 0                       ; размер ядра тома 2
    19. MBR_2_Tom3       db 6 dup(0)                ; адрес (LBA) заголовка тома 3
    20. MBR_2_Tom3_Razm  db 0                       ; размер ядра тома 3
    21. MBR_2_Tom4       db 6 dup(0)                ; адрес (LBA) заголовка тома 4
    22. MBR_2_Tom4_Razm  db 0                       ; размер ядра тома 4
    23. MBR_2_Port       dw 0                       ; порт активного диска              
    24. MBR_2_Disk       db 0                       ; 0 - Primary, 1 - Secondary диск
    25. MBR_2_SecCol     db 1                       ; число секторов для чтения
    26. MBR_2_Cikl       db 0                       ; счетчик цикла
    27. ;------------------------------------------------
    28.    
    29. MBR_2_start:
    30.     mov ax,0              ;----
    31.     mov ds,ax             ;
    32.     mov ss,ax             ;
    33.     mov ax,Stek_Adress    ; Настраиваем сегментные регистры
    34.     mov sp,ax             ;
    35.     xor ax,ax             ;
    36.     mov es,ax             ;----
    37.    
    38.     mov ax,0201h          ;----
    39.     mov cx,0002h          ;
    40.     mov dx,0080h          ; Код MBR не влез в один сектор, подгрузим оставшуюся часть
    41.     mov bx,7e00h          ;
    42.     int 13h               ;----
    43.    
    44. ;-------------- Считываем тукещую дату ----------------
    45.     mov al,00h                     ;-
    46.     out 70h,al                     ; секунда
    47.     in ax,71h                      ;
    48.     mov byte ptr MBR_2_Data,al     ;-
    49.     mov al,02h                     ; минута
    50.     out 70h,al                     ;
    51.     in ax,71h                      ;
    52.     mov byte ptr MBR_2_Data + 1,al ;-
    53.     mov al,04h                     ; час
    54.     out 70h,al                     ;
    55.     in ax,71h                      ;
    56.     mov byte ptr MBR_2_Data + 2,al ;-
    57.     mov al,07h                     ; день месяца
    58.     out 70h,al                     ;
    59.     in ax,71h                      ;
    60.     mov byte ptr MBR_2_Data + 3,al ;-
    61.     mov al,08h                     ; месяц
    62.     out 70h,al                     ;
    63.     in ax,71h                      ;
    64.     mov byte ptr MBR_2_Data + 4,al ;-
    65.     mov al,09h                     ; год
    66.     out 70h,al                     ;
    67.     in ax,71h                      ;
    68.     mov byte ptr MBR_2_Data + 5,al ;-
    69.     mov al,32h                     ; век
    70.     out 70h,al                     ;
    71.     in ax,71h                      ;
    72.     mov byte ptr MBR_2_Data + 6,al ;-
    73. ;------------------------------------------------------
    74.  
    75. ;------------------- Обновляем MBR --------------------
    76.     xor ax,ax
    77.     mov es,ax
    78.     mov ax,0301h
    79.     mov cx,0001h
    80.     mov dx,0080h
    81.     mov bx,7c00h
    82.     int 13h
    83. ;------------------------------------------------------
    84.  
    85.     jmp MBR_2_next1
    86.    
    87. ;------------- Процедура обращения к диску ------------
    88. ; Протокол - PIO, режим - LBA28
    89. ;------------------------------------------------------
    90. ; На входе:
    91. ;     es:di        - буфер
    92. ;     esi[0:27]    - LBA адрес
    93. ;     esi[28]      - Устройство
    94. ;     MBR_2_Port   - базовый адрес порта
    95. ;     MBR_2_SecCol - число секторов для чтения
    96. ;-----------------------------------------------------
    97. MBR_2_Disc_Zapros proc
    98.     mov dx,MBR_2_Port        ;----------------------
    99.     add dx,206h              ;
    100.     mov al,2                 ; Запрещаем прерывания
    101.     out dx,al                ;----------------------
    102.  
    103.     mov dx,MBR_2_Port
    104.     add dx,7
    105. m1:
    106.     cmp MBR_2_Cikl,100       ;--
    107.     jne m1_1                 ; Время истекло, ошибка тайм-аута
    108.     jmp MBR_2_OshibkaTaimAut ;--
    109. m1_1:                        ;
    110.     add MBR_2_Cikl,1         ;
    111.     in   al,dx               ;--
    112.     test al,80h              ; Ждем BSY = 0
    113.     jnz  m1                  ;----------------------
    114.  
    115.     mov ecx,esi              ;----------------------
    116.     shr ecx,24               ; выбираем устройство (в cl)
    117.     or  cl,0e0h              ;----------------------
    118.  
    119.     mov dx,MBR_2_Port        ;----------------------
    120.     add dx,6                 ;
    121.     mov al,cl                ; загружаем устройство и старшие разряды адреса
    122.     out dx,al                ;----------------------
    123.  
    124.     mov dx,MBR_2_Port        ;----------------------
    125.     add dx,7                 ;
    126.     mov MBR_2_Cikl,0         ;
    127. m2:                          ;
    128.     cmp MBR_2_Cikl,100       ;--
    129.     jne m2_1                 ; Время истекло, ошибка тайм-аута
    130.     jmp MBR_2_OshibkaTaimAut ;--
    131. m2_1:                        ;
    132.     add MBR_2_Cikl,1         ;
    133.     in   al,dx               ; Ждем BSY = 0
    134.     test al,80h              ; и   DRDY = 1
    135.     jnz  m2                  ;
    136.     test al,40h              ;
    137.     jz   m2                  ;----------------------
    138.    
    139.     mov dx,MBR_2_Port        ;----------------------
    140.     add dx,2
    141.     mov al,MBR_2_SecCol      ; Число секторов
    142.     out dx,al                ;----------------------
    143.  
    144.     mov eax,esi              ;----------------------
    145.     mov dx,MBR_2_Port        ; Загружаем LBA адрес
    146.     add dx,3                 ;
    147.     out dx,al                ; [0:7]
    148.     mov dx,MBR_2_Port        ;
    149.     add dx,4                 ;--
    150.     shr eax,8                ;
    151.     out dx,al                ; [8:15]
    152.     mov dx,MBR_2_Port        ;
    153.     add dx,5                 ;--
    154.     shr eax,8                ;
    155.     out dx,al                ; [16:23]
    156.                              ;----------------------
    157.    
    158.     mov dx,MBR_2_Port        ;----------------------
    159.     add dx,7                 ;
    160.     mov al,020h              ; Шлем команду - чтение сектора
    161.     out dx,al                ;----------------------
    162.    
    163.     mov dx,MBR_2_Port        ;----------------------
    164.     add dx,206h              ;
    165.     mov MBR_2_Cikl,0         ;
    166. m3:                          ;
    167.     cmp MBR_2_Cikl,100       ;--
    168.     jne m3_1                 ; Время истекло, ошибка тайм-аута
    169.     jmp MBR_2_OshibkaTaimAut ;--
    170. m3_1:                        ;
    171.     add MBR_2_Cikl,1         ;
    172.     in   al,dx               ; Ждем окончания чтения
    173.     test al,80h              ;
    174.     jnz  m3                  ;----------------------
    175.  
    176.     mov  dx,MBR_2_Port       ;----------------------
    177.     add dx,7                 ;
    178.     mov MBR_2_Cikl,0         ;
    179. m4:                          ;
    180.     cmp MBR_2_Cikl,100       ;--
    181.     jne m4_1                 ; Время истекло, ошибка тайм-аута
    182.     jmp MBR_2_OshibkaTaimAut ;--
    183. m4_1:                        ;
    184.     add MBR_2_Cikl,1         ;
    185.     in   al,dx               ; Ждем DRQ = 1
    186.     test al,08h              ;
    187.     jz   m4                  ;----------------------
    188.    
    189.     xor bx,bx
    190.     cld                      ;----------------------
    191.     mov ax,256               ;
    192.     mov bl,MBR_2_SecCol      ;
    193.     mul bx                   ; Принимаем прочитанные данные
    194.     mov dx,MBR_2_Port        ;
    195.     mov cx,ax                ;
    196.     rep insw                 ;----------------------
    197.  
    198.     mov dx,MBR_2_Port        ;----------------------
    199.     add dx,206h              ;
    200.     mov al,0                 ; Разрешаем прерывания
    201.     out dx,al                ;----------------------
    202.    
    203.     ret
    204.    
    205. MBR_2_OshibkaTaimAut:
    206.     mov ax,0e01h
    207.     mov bx,4
    208.     int 10h
    209.  
    210.     ret
    211. MBR_2_Disc_Zapros endp
    212. ;------------------------------------------------------
    213.  
    214. ;--------- Процедура проверки считанных данных --------
    215. ;------------------------------------------------------
    216. ; На входе:
    217. ;     0000:5700h  - считанные данные
    218. ;-----------------------------------------------------
    219. MBR_2_Proveraem proc
    220.     xor ax,ax
    221.     xor dx,dx
    222.     mov si,offset MBR_2_Data
    223.     mov di,5703h
    224.     cld
    225.     mov cx,7
    226.     repe cmpsb
    227.     jne MBR_2_Proveraem_NET
    228.     mov dh,0ffh
    229. MBR_2_Proveraem_NET:
    230.    
    231.     ret
    232. MBR_2_Proveraem endp
    233. ;------------------------------------------------------
    234.    
    235.     org 7dfeh       ;
    236.     db 55h, 0aah    ; сигнатура MBR
    237.    
    238. ;------------ Ищем порты активного диска --------------
    239. MBR_2_next1:
    240.     org 7e00h
    241.     mov MBR_2_Port,01f0h      ;----
    242.     mov MBR_2_Disk,0          ;
    243.     mov esi,0                 ; Primary Master
    244.     mov di,5700h              ;
    245.     call MBR_2_Disc_Zapros    ;
    246.     call MBR_2_Proveraem      ;
    247.     cmp dh,0ffh               ;
    248.     je MBR_2_next2            ;----
    249.     mov MBR_2_Disk,1          ;
    250.     mov di,5700h              ;
    251.     mov esi,1                 ; Primary Slave
    252.     shl esi,28                ;
    253.     call MBR_2_Disc_Zapros    ;
    254.     call MBR_2_Proveraem      ;
    255.     cmp dh,0ffh               ;
    256.     je MBR_2_next2            ;----
    257.     mov MBR_2_Port,0170h      ;
    258.     mov MBR_2_Disk,0          ;
    259.     mov esi,0                 ; Secondary Master
    260.     mov di,5700h              ;
    261.     call MBR_2_Disc_Zapros    ;
    262.     call MBR_2_Proveraem      ;
    263.     cmp dh,0ffh               ;
    264.     je MBR_2_next2            ;----
    265.     mov MBR_2_Disk,1          ;
    266.     mov di,5700h              ;
    267.     mov esi,1                 ; Secondary Slave
    268.     shl esi,28                ;
    269.     call MBR_2_Disc_Zapros    ;
    270.     call MBR_2_Proveraem      ;
    271.     cmp dh,0ffh               ;
    272.     je MBR_2_next2            ;----
    273.    
    274.     jmp MBR_2_next3
    275.    
    276. ;---- Просканили порты, теперь сообщим следующему
    277. ;       загрузчику порт и номер активного диска
    278.  
    279.  
    280. MBR_2_next2:
    281.     mov ax,0003h
    282.     int 10h
    283.    
    284.     mov bp,offset MBR_2_Port
    285.     mov ax,1301h
    286.     mov bx,000fh
    287.     mov cx,3
    288.     xor dx,dx
    289.     int 10h
    290.    
    291. ;------------------------------------------------------
    292. MBR_2_next3:
    293.     xor ax,ax
    294.     int 16h
    295.  
    296. main endp
    297. code ends
    298.  
    299. stk segment stack
    300.     db 256 dup(0)
    301. stk ends
    302.  
    303. end main
     
  2. MisHel64

    MisHel64 Member

    Публикаций:
    0
    Регистрация:
    9 мар 2011
    Сообщения:
    182
    Чисто придирка 1. Посмотри 30ю и 35ю строку. 36ю нужно поднять чуть выше. И как бы прерывание запрещать нужно, когда стек меняешь. И когда работаешь с 0x70/0x71h регистрами, то же нужно запрещать прерывания. 76я строка, ты разве менял сегмент?

    Чисто придирка 2 Эх и не кошерно писать в MBR когда тебя не просят специально. Если пишешь код только для себя, то одно дело, если на "продажу", то не стоит забывать, что в BIOS может стоять запрет на изменение MBR.

    Чисто придирка 3 А кто тебе сказал, что твой винт работает в режиме эмуляции IDE и висит на 0x1F0/0x170h?

    Строка 101. Не трогай +0x206 регистр. Не нужно.
    Строка 105. Цикл по M1 мне лично вообще не понятен.

    В общем совет, с начало напиши простенькую прогу читающую сектора с диска через порты. Стойкое у мню впечатление, что ты не совсем понимаешь, что делаешь, и как вообще это нужно делать на современных компьютерах.

    И посмотри на INT 0x13/0x48, может и не придется изобретать велосипед.
     
  3. Pavia

    Pavia Well-Known Member

    Публикаций:
    0
    Регистрация:
    17 июн 2003
    Сообщения:
    2.409
    Адрес:
    Fryazino
    Не обязательно, достаточно использовать рекомендуемую команду LSS.
    Так никто не делает.

    Странный совет. Наоборот нужно.

    Мне тоже не понятен. надо проверять BSY = 0 и DRQ = 0 И если не так, то можно подождать и перейти к состоянию устройство не исправно.

    test al,80h ; и DRDY = 1
    Можно не проверять.
     
  4. MisHel64

    MisHel64 Member

    Публикаций:
    0
    Регистрация:
    9 мар 2011
    Сообщения:
    182
    Как вариант. Просто LSS автоматически отключает прерывания на время своего исполнения.
    НО! В данном коде использование LSS не оправдано.
    http://compgroups.net/comp.lang.asm.x86/LSS-and-MOV-SS

    Отучаемся говорить за всех.

    В данном коде не нужно.

    Я несколько про другое.
     
  5. Pavia

    Pavia Well-Known Member

    Публикаций:
    0
    Регистрация:
    17 июн 2003
    Сообщения:
    2.409
    Адрес:
    Fryazino
    Три фразы и все бессмысленные, голословные. Я не телепат и ваши мысли читать не могу.

    Почему не оправданно? А запрещений прерываний оправданно так?
     
  6. MisHel64

    MisHel64 Member

    Публикаций:
    0
    Регистрация:
    9 мар 2011
    Сообщения:
    182
    Э.... Если подумать и посмотреть код, и почитать документацию, то все становится очевидным.

    Запрещение оправдано. А LSS нет. Хоть одно преимущество назови.
    А еще лучше дай кусок кода, с LSS. Станет очевидно, по чему.
     
  7. JucED

    JucED New Member

    Публикаций:
    0
    Регистрация:
    8 янв 2010
    Сообщения:
    23
    Чисто отмазка 1 :) код совсем никак не оптимизировал еще, и я ни разу не видел чтобы запрещали прерывания при работе с 70h, 71h регистрами.

    Чисто отмазка 2 :) Буду знать.

    Чисто отмазка 3 :) с sata я пока еще не разобрался, как разберусь - встрою в этот код.


    За основу брал ко из этой статьи http://www.wasm.ru/article.php?article=atazen01

    Ну int 13h/48h у меня на старой версии vmware не фурычил, а на новой не пробовал еще да и пробовать не собираюсь, т.к. мне PM нужен.
    А так если по вашему то данная процедура чтения вообще не работает? Но это совсем не так! Она абсолютно стабильно считала сразу 2 сектора. Вот и странно то что при поиске она вылетает с таймаутом... команды ведь одни и те же, это получается она както неправильно спотыкается об отсутствующие диски.
     
  8. MisHel64

    MisHel64 Member

    Публикаций:
    0
    Регистрация:
    9 мар 2011
    Сообщения:
    182
    Опять же вопрос. Ты это для себя разово делаешь, или собираешься тиражировать свое решение? От этого очень много зависит.

    Про 0x70/0x71 Говорить не буду. Не хочешь не делай. Дело личное, но почитать литературу, настоятельно советую. После этого обнаружишь, что тут у тебя два несоответствия с рекомендациями. Лично мне нравится ISBN 5-256-01263-0.

    Про "хвост загрузчика". Объяснять почему нельзя использовать 1й сектор для своего кода не буду. Пока нет ответа на первый вопрос, смысла распинаться нет, а информации море.

    На счет PM. Ты определись где он нужен, вот там и определяй связку логического номера винта (BIOS) с его физическими координатами (Порты и etc). Про правильное планирование задачи в комплексе то же говорить не буду.

    На счет статьи Посмотри на ее дату. С тех пор много воды утекло. Как там в варе дело обстоит, не знаю, не использую, но вот реальное железо, тебе в легкую сюрприз принесет.

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

    Ну и зря. Порт тебе это прерывание сообщит, без всяких плясок с бубном.
     
  9. JucED

    JucED New Member

    Публикаций:
    0
    Регистрация:
    8 янв 2010
    Сообщения:
    23
    Повторюсь - нормальная или ненормальная логика, но MBR_2_Disc_Zapros proc работает вполне адекватно с присутствующим железом. А про PM вот: по моей задумке код MBR должен находить порты активного диска и передавать их следующему загрузчику, который переключает проц в PM и дальше делает свою работу.

    Этот код чисто для меня, мне нужно реализовать свою ФС + так сказать самодельную простенькую ОС (которая ничего не должна делать кроме как создать\удалить\открыть файл либо каталог). Такчто все вотэти правильности в первичных загрузчиках то и не нужны, главное написать да отточить как следует саму ФС.
     
  10. JucED

    JucED New Member

    Публикаций:
    0
    Регистрация:
    8 янв 2010
    Сообщения:
    23
    И не кусайся только, либо объясни что к чему если не трудно, либо пошли меня на какую нибудь страницу с пояснениями.
     
  11. MisHel64

    MisHel64 Member

    Публикаций:
    0
    Регистрация:
    9 мар 2011
    Сообщения:
    182
    Тут не одна страница с пояснениями нужна, тут их куча. И не только страниц, но и книг, стандартов, и опыта.
    Первая твоя проблема, это в логике. Прежде чем что-то делать, ВСЕГДА задай вопрос, А ЗАЧЕМ.
    Первое, что ты должен определиться насколько твоя ОС будет совместима с другими продуктами.
    Если ОС ставится только на чистый винт, и доступ к данным на этом винте тебе не нужен из других систем, то абсолютно на все стандарты ты можешь наплевать. И делать как тебе нравится. Единственное условие, что код сидящий в первом секторе (LBA=0) должен быть само достаточным. В принципе, ты это уже делаешь.

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

    Типичная схема загрузки:
    1) MBR
    2) BOOT сектор
    3) BOOT менеджер
    4) Загрузчик
    5) Ядро

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

    В задачу загрузчика, входит многое, и опять это зависит от твоей фантазии. И количество этих загрузчиков в том числе. Именно в нем нужно переводить проц в PM, и именно в нем нужно искать порты для устройства. Раньше просто смысла нет.

    И тут же возникает еще один вопрос. Куда ты поместишь этот загрузчик. Так как его размер на этапе будет плавать, и/или ты задумаешь сделать его вообще модульным, то лучше его поместить внутрь раздела.
     
  12. JucED

    JucED New Member

    Публикаций:
    0
    Регистрация:
    8 янв 2010
    Сообщения:
    23
    Эмммм.... я не про ОС говорил а про ФС, и на бумажке у меня все расписано карандашиком, да и не только на бумажке. Да и вопрос вообще не о том был. Ну да ладно хрен с ним, скоро освобожу второй жесткий и буду на реальной машине тестить.

    А вот кстати у кого-нибудь возникала такая вот ошибка:

    Код:
    mov al,11h
    out 20h,al

    Результат:
    Ошибка "Переполнение деления" и ниже еще пишет "Ошибка при выделении памяти Не удается загрузить COMMAND.COM, система остановлена".

    Пробовал этот кусок кода писать в любую часть программы - не помогает. Тестил на винде XP через debug (из TASMа) + в vmware без ОС + в vmware в DOS в том же debug'ере от TASM.
     
  13. JucED

    JucED New Member

    Публикаций:
    0
    Регистрация:
    8 янв 2010
    Сообщения:
    23
    все ошибка решена