Переход в PM (тема в BEGINNERS не прижилась)

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

  1. Igor1024

    Igor1024 Васил Троянов Боянов (Azis)

    Публикаций:
    0
    Регистрация:
    15 окт 2010
    Сообщения:
    345
    Адрес:
    Sliven, Bulgaria
    Вот ещё просьба объяснить: почему прыгаем так (bootcode16-gdt). Я не понял смысл этого вычисления.
    Код (Text):
    1. jmp  bootcode16-gdt:...
    2. ...
     
  2. Phantom_84

    Phantom_84 New Member

    Публикаций:
    0
    Регистрация:
    6 июн 2007
    Сообщения:
    820
    Это мелочь. Мне не понравилось, что в боксе оставался гореть индикатор дисковода.

    Правильно, только там было много лишнего.

    Это тоже мелочь. Это такой трюк, чтобы не задумываться о местоположении дескриптора в GDT, когда ты пишешь значение селектора. Как вариант можно было просто сделать так:
    Код (Text):
    1. NULL equ 0
    2. KCODE equ 8
    3. KDATA equ 10h
    4. ...
     
  3. Igor1024

    Igor1024 Васил Троянов Боянов (Azis)

    Публикаций:
    0
    Регистрация:
    15 окт 2010
    Сообщения:
    345
    Адрес:
    Sliven, Bulgaria
    Да, по-хорошему мне надо было переинициализировать сегм. рег. ещё раз. Тогда всё понятно. Спасибо всем.
     
  4. MisHel64

    MisHel64 Member

    Публикаций:
    0
    Регистрация:
    9 мар 2011
    Сообщения:
    182
    А это тонкий намек, что что-то не то с обработчиком таймера. Где-то ты накосячил.
     
  5. Phantom_84

    Phantom_84 New Member

    Публикаций:
    0
    Регистрация:
    6 июн 2007
    Сообщения:
    820
    Я? Это нормальное поведение BIOS. Просто я не стал ждать, пока BIOS вырубит движок, а сделал это сам.
     
  6. Igor1024

    Igor1024 Васил Троянов Боянов (Azis)

    Публикаций:
    0
    Регистрация:
    15 окт 2010
    Сообщения:
    345
    Адрес:
    Sliven, Bulgaria
    Теперь вопросец по прерываниям.
    Я решил пока идти, опираясь на статью Great'a.
    Я постарался разобраться сам, почему не работает, но не получилось...
    Вроде бы IDT правильно построена, прерывания разрешены...
    Код (Text):
    1. format binary
    2.        xor ax,ax
    3.        cli        ;reinitialize segment registers
    4.        mov ss,ax
    5.        xor sp,sp
    6.        sti
    7.  
    8.        jmp 1000h:@f
    9. @@:
    10.  
    11.        mov ax,1000h
    12.        mov ds,ax ; push cs/pop ds
    13.        mov es,ax
    14.  
    15.        cli
    16.  
    17.        mov al,8Fh;disable NMI
    18.        out 70h,al
    19.        in al,71h
    20.  
    21.  
    22.  
    23.        lgdt fword [GDTR]
    24.        lidt fword [IDTR]
    25.  
    26.        mov eax,cr0;enable PM
    27.        or al,1
    28.        mov cr0,eax
    29.  
    30.        jmp fword 08h:Startup32;jump to 32-bit world
    31.  
    32.  
    33.      align 8                  ;align for speed
    34. GDT:
    35.         dq 0                     ;NULL descriptor
    36.         label KCODE at $-GDT
    37.         db 0FFh,0FFh,0,0,0,9Ah,0CFh,0 ; desc 0,0FFFFFh,DF_CODE32
    38.         label KDATA at $-GDT
    39.         db 0FFh,0FFh,0,0,0,92h,0CFh,0 ; desc 0,0FFFFFh,DF_DATA32
    40.         label GDT_SIZE at $-GDT
    41.  
    42. GDTR:
    43.         dw GDT_SIZE-1
    44.         dd GDT+10000h
    45.  
    46.  
    47. IDT:
    48.          dd 0,0 ; 0
    49.          dw int_EOI, 08h, 1000111000000000b, 0   ; 1
    50.          dd 0,0 ; 2
    51.          dd 0,0 ; 3
    52.          dd 0,0 ; 4
    53.          dd 0,0 ; 5
    54.          dd 0,0 ; 6
    55.          dd 0,0 ; 7
    56.          dd 0,0 ; 8
    57.          dd 0,0 ; 9
    58.          dd 0,0 ; 10
    59.          dd 0,0 ; 11
    60.          dd 0,0 ; 12
    61.          dw int_EOI, 08h, 1000111000000000b, 0   ; 13  #GP
    62.          dd 0,0 ; 14
    63.          dd 0,0 ; 15
    64.          dd 0,0 ; 16
    65.          dd 0,0 ; 17
    66.          dd 0,0 ; 18
    67.          dd 0,0 ; 19
    68.          dd 0,0 ; 20
    69.          dd 0,0 ; 21
    70.          dd 0,0 ; 22
    71.          dd 0,0 ; 23
    72.          dd 0,0 ; 24
    73.          dd 0,0 ; 25
    74.          dd 0,0 ; 26
    75.          dd 0,0 ; 27
    76.          dd 0,0 ; 28
    77.          dd 0,0 ; 29
    78.          dd 0,0 ; 30
    79.          dd 0,0 ; 31
    80.          dw timer, 08h, 1000111000000000b, 0   ; IRQ 0 - системный таймер
    81.          dw int_EOI, 08h, 1000111000000000b, 0   ; пока не использую
    82.  
    83.          label IDT_size at $-IDT
    84.  
    85. IDTR dw IDT_size-1
    86.          dd IDT+10000h
    87.  
    88. ;;;;;;;;;;;;;;;;;;;;;;;Interrupt handlers;;;;;;;;;;;;;;;;;;;;;
    89.  
    90. int_EOI:
    91.         push ax
    92.         mov al,20h
    93.         out 20h,al
    94.         out 0a0h,al
    95.         pop ax
    96.         iretd
    97.  
    98. timer:
    99.         push ax
    100.         inc byte [0B8000h]
    101.         pop ax
    102.         iretd
    103.  
    104. keyboard:
    105.         push ax
    106.         push bx
    107.         push si
    108.         push ds
    109.         push cs
    110.         pop ds
    111.  
    112.         xor ax, ax
    113.         in al, 60h
    114.  
    115.         mov bx, ascii
    116.         add bx, ax
    117.         mov di, bx
    118.         mov al,byte [di]
    119.         mov ah, 07h
    120.         mov word [0B8000h],ax
    121.  
    122.         mov al, 20h ;EOI
    123.         out 20h, al
    124.  
    125.         pop ds
    126.         pop es
    127.         pop bx
    128.         pop ax
    129.  
    130.         iretd
    131.  
    132. POWER_OFF:
    133.         mov ax, 0x5301
    134.         xor bx, bx
    135.         int 0x15
    136.         mov ax, 0x5308
    137.         mov bx, 1
    138.         mov cx, bx
    139.         int 0x15
    140.         mov ax, 0x530D
    141.         mov bx, 1
    142.         mov cx, bx
    143.         int 0x15
    144.         mov ax, 0x530F
    145.         mov bx, 1
    146.         mov cx, bx
    147.         int 0x15
    148.         mov ax, 0x530E
    149.         xor bx, bx
    150.         mov cx, 0x102
    151.         int 15h
    152.         mov ax, 0x5307
    153.         mov bx, 1
    154.         mov cx, 3
    155.         int 0x15
    156.         mov bx, 1
    157.         mov cx, 3
    158.         int 0x15
    159.         jmp $
    160.  
    161. ;;;;;;;;;;;;;;;;;;;;;;;;;Data;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    162. ascii    db    0,0,'1234567890-+',0,0,'QWERTYUIOP[]',0,0,'ASDFGHJKL;',"'`",0,0,'ZXCVBNM,./',0,'*',0,' ',0,0,0,0,0,0,0,0,0,0,0,0,0,'789-456+1230.',0,0
    163. index    db    0
    164. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    165.         virtual
    166.         rb 10000h-$
    167.         end virtual
    168. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;PM32 Entry;;;;;;;;;;;;;;;;;;;
    169.         use32
    170.         org $+10000h
    171.  
    172. Startup32:
    173.         mov ax,KDATA;10h
    174.         mov ds,ax
    175.         mov es,ax
    176.         mov fs,ax
    177.         mov gs,ax
    178.         mov ss,ax
    179.         mov esp,10000h
    180.  
    181.         mov al,20h  ;define base address
    182.         out 21h,al
    183.  
    184.         in al,70h          ;enable interrupts
    185.         and al,7Fh
    186.         out 70h,al
    187.         sti
    188.  
    189. check:
    190.         mov al,"!"                ; show that we entered PM
    191.         mov ah,07h
    192.         mov word [0B8000h],ax
    193.         jmp $
     
  7. Phantom_84

    Phantom_84 New Member

    Публикаций:
    0
    Регистрация:
    6 июн 2007
    Сообщения:
    820
    Много ошибок...

    - не инициализирован контроллер прерываний (просто так взять и послать отдельное инициализационное слово в PIC нельзя);
    - пытаешься обрабатывать исключения, также как прерывания (посылаешь EOI, не учитываешь присутствие доп. параметра в стеке);
    - перенеси все обработчики и ascii/index за org $+10000h (POWER_OFF опять не в тему, только создает лишний "шум");
    - не проинициализирован ds:
    Код (Text):
    1. timer:
    2.         push ax
    3.         inc byte [0B8000h]
    4.         pop ax
    5.         iretd
    - в PM такое не прокатит: push cs/pop ds. В сегмент кода нельзя писать. Как вариант: push KDATA/pop ds;
    - прерывания могут происходить 1) случайно, 2) даже те, которые ты не обрабатываешь, поэтому нужно делать шлюзы для всех обработчиков и ставить заглушки;
    - видать, ты не просек фишку:
    Код (Text):
    1.         in al,70h          ;enable interrupts
    2.         and al,7Fh
    3.         out 70h,al
    Правильно так:
    Код (Text):
    1.   mov al,0Fh
    2.   out 70h,al
    3.   in al,71h
     
  8. Igor1024

    Igor1024 Васил Троянов Боянов (Azis)

    Публикаций:
    0
    Регистрация:
    15 окт 2010
    Сообщения:
    345
    Адрес:
    Sliven, Bulgaria
    1)Итак, инициализирую PIC:
    Код (Text):
    1. mov al,00010000b;ICW1
    2. out 20h,al
    3.  
    4. mov al,20h      ;ICW2
    5. out 21h,al
    2)Поставил обработчик #GP => при обращении к несуществующему обработчику возникает #GP, с которым я уже могу сладить.

    3)Я не знаю как их тогда описать в IDT в поле offset. Они в RM получается в другом сегменте уже.

    4)
    Код (Text):
    1. mov ax,KDATA;10h
    2. mov ds,ax       ;кажется здесь всё инициализировано.
    3. mov es,ax
    4. mov fs,ax
    5. mov gs,ax
    6. mov ss,ax
    7. mov esp,10000h
     
  9. Phantom_84

    Phantom_84 New Member

    Публикаций:
    0
    Регистрация:
    6 июн 2007
    Сообщения:
    820
    Мне кажется, и двух инициализационных слов мало. Там вроде бы 3-4 слова плюс маска. Поищи на любом osdev-форуме или osdev-wiki. Только я писал посты с подробными ответами на данный вопрос много раз.

    Это, если ты не возобновляешь управление прерванного кода. Повторяю большинство обработчиков исключений получает от процессора доп. параметр в стеке.

    Не, ну на смещение отводится 4 байта - 2 в начале дескриптора и 2 в конце. Жаль, у меня сейчас с собой нет моего макроса desc - он позволяет описывать в том числе и дескрипторы прерываний. Хотя опять можно поискать на osdev-форумах desc.inc или desc.zip. Можешь пока сделать как-то так:
    Код (Text):
    1. dw handler and 0FFFFh,KCODE,...,handler shr 16
    Это понятно, но когда ты дойдешь до обработки прерываний в рамках прикладных задач, этого уже будет недостаточно. Лучше несложные вещи делать сразу, пусть и на перспективу. Внутри обработчика можешь быть уверен только в корректности ss и cs. Если у тебя стек и данные описываются одним и тем же дескриптором, инициализировать ds можно так: push ss/pop ds. Или обращаться к данным через ss (когда используется в качестве базового регистра ebp или esp, то это также эффективно, как и обращение через ds).
     
  10. Igor1024

    Igor1024 Васил Троянов Боянов (Azis)

    Публикаций:
    0
    Регистрация:
    15 окт 2010
    Сообщения:
    345
    Адрес:
    Sliven, Bulgaria
    Да, всего 4 ICW. Понял, пошлю все, проведу полную инициализацию.
    А вот зачем перемещать обработчики прерываний?
     
  11. Phantom_84

    Phantom_84 New Member

    Публикаций:
    0
    Регистрация:
    6 июн 2007
    Сообщения:
    820
    Это самый простой, но судя по всему не до конца осознанный тобой вопрос. Сегмент 1000h (база 10000h) используется для инициализации в реальном режиме. Обработчики и все остальное уже должны работать в защищенном режиме с Flat-сегментами (база 0 - внутрисегментный адрес совпадает с линейным). Если ты оставишь обработчики до org $+10000h, их адреса будут внутрисегментными для сегмента 1000h, хотя на самом деле их адреса должны быть на 10000h больше.
     
  12. Igor1024

    Igor1024 Васил Троянов Боянов (Azis)

    Публикаций:
    0
    Регистрация:
    15 окт 2010
    Сообщения:
    345
    Адрес:
    Sliven, Bulgaria
    Теперь понятно спасибо. А вот кроме интеловских мануалов, где ещё можно почерпнуть информации (чтоб я Вас вопросами бесконечными не мучил)? На осьдеве всё раскрыто в основном в общих рамках (но судя по-всему на форуме также есть много инфы полезной.)
     
  13. Igor1024

    Igor1024 Васил Троянов Боянов (Azis)

    Публикаций:
    0
    Регистрация:
    15 окт 2010
    Сообщения:
    345
    Адрес:
    Sliven, Bulgaria
    Нашёл на осьдеве такой пример инициализации (что-то я лопухнулся с двумя словами. PIC ведь полность нужно инициализировать).
    Код (Text):
    1. init_PIC:
    2.         mov al,11h;ICW1
    3.         out 20h,al
    4.         out 0A0h,al
    5.  
    6.         mov al,20h;ICW2
    7.         out 21h,al
    8.         mov al,28h
    9.         out 0A1h,al
    10.  
    11.         mov al,04h;ICW3
    12.         out 21h,al
    13.         mov al,02h
    14.         out 0A1h,al
    15.  
    16.         mov al,11h;ICW4
    17.         out 21h,al
    18.         mov al,01h
    19.         out 0A1h,al
    20.  
    21.         xor al,al ;percieve as front signals
    22.         mov dx,04D0h
    23.         out dx,al
    24.         inc dx
    25.         out dx,al
    26.  
    27.         mov al,6bh
    28.         out 20h,al
    29.         out 0A0h,al
    Здесь всё понятно. Но вот макрос я не нашёл, да и временный вариант у меня не заработал (возникает ошибка). Так что посмотрю и поспрашиваю ещё на осьдеве.
     
  14. Igor1024

    Igor1024 Васил Троянов Боянов (Azis)

    Публикаций:
    0
    Регистрация:
    15 окт 2010
    Сообщения:
    345
    Адрес:
    Sliven, Bulgaria
    Phantom_84, объясните как (чисто теретически), можно опиать interrupt gate с обработчиками в другом сегменте. Я сам постараюсь сделать... Я просто не могу понять как записать в оффсет адрес, нахоящийся в другом сегменте.
     
  15. Phantom_84

    Phantom_84 New Member

    Публикаций:
    0
    Регистрация:
    6 июн 2007
    Сообщения:
    820
    Зачем тебе "другой сегмент", если есть Flat-сегменты? Хотя, если чисто теоретически, то по сути точно также и как-то так:
    Код (Text):
    1.   ...
    2.   align 4096 ; align 32
    3. xseg_base:
    4.   org 0
    5. handler:
    6.   iret
    7. xseg_size:
    8.   org xseg_base+xseg_size ; или +$
    9.   ...
    10. GDT:
    11.   ...
    12.   label XSEG_SEL at $-GDT
    13.   desc xseg_base,(xseg_size+4095)/4096-1,DF_CODE32 ; desc xseg_base,xseg_size-1,DF_CODE32 xor DF_PAGED
    14.   ...
    15. IDT:
    16.   ...
    17.   desc XSEG_SEL,handler,DF_INT32
    18.   ...
    Если обработчик в этом "другом сегменте" один единственный и находится в самом начале сегмента, то в качестве смещения можно просто писать 0.
     
  16. Igor1024

    Igor1024 Васил Троянов Боянов (Azis)

    Публикаций:
    0
    Регистрация:
    15 окт 2010
    Сообщения:
    345
    Адрес:
    Sliven, Bulgaria
    Phantom_84, Вы меня не так поняли. Я попросил объяснить
    Код (Text):
    1. dw handler and 0FFFFh,KCODE,...,handler shr 16
    Просто полюбопытствовал, как такие построения проводить.
    А flat-сегменты меня более чем устраивают.
     
  17. Phantom_84

    Phantom_84 New Member

    Публикаций:
    0
    Регистрация:
    6 июн 2007
    Сообщения:
    820
    Так и проводить. В макрос загони для наглядности, чтобы не писать handler and 0FFFFh/handler shr 16 каждый раз.
     
  18. Igor1024

    Igor1024 Васил Троянов Боянов (Azis)

    Публикаций:
    0
    Регистрация:
    15 окт 2010
    Сообщения:
    345
    Адрес:
    Sliven, Bulgaria
    Упс... Я последнию часть оффсет-поля оставил равной нулю... Тогда всё работает... Извиняюсь... Проглядел...
     
  19. Igor1024

    Igor1024 Васил Троянов Боянов (Azis)

    Публикаций:
    0
    Регистрация:
    15 окт 2010
    Сообщения:
    345
    Адрес:
    Sliven, Bulgaria
    Вопрос: а теперь можно как-нибудь удобнее обращаться к переменным (они, в моём случае, строки в большинстве своём). К примеру
    Код (Text):
    1. org $+10000h
    2. ......
    3. ;DATA
    4. cursor db 160
    здесь, чтоб оперировать со значение cursor нужно писать что-то вроде [cursor+10000h], что не удобно (может ошибаюсь). Можно ли как-нибудь иначе обращаться?
     
  20. Phantom_84

    Phantom_84 New Member

    Публикаций:
    0
    Регистрация:
    6 июн 2007
    Сообщения:
    820
    Сначала включаем мозг, потом задаем вопросы.

    А если нужно обращаться к данным в реальном режиме, расположи их в сегменте 1000h (т.е. до org $+10000h).