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

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

  1. Igor1024

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

    Публикаций:
    0
    Регистрация:
    15 окт 2010
    Сообщения:
    345
    Адрес:
    Sliven, Bulgaria
    Приветствую.
    Эта тема в BEGINNERS не прижилась, потому пишу сюда (http://www.wasm.ru/forum/viewtopic.php?id=40720).
    Вот возник вопрос относительно кода, переводящего процессор в защищённый режим. Phantom_84 рассказал, в чём были мои ошибки (за что ему спасибо), и я постарался сам решить свои вопросы.
    Код (Text):
    1. use16
    2. start:
    3.     jmp continue_loading
    4.  
    5. GDT:
    6.          dd  0,0
    7.          db  0FFh, 0FFh, 00h, 00h, 00h, 10011010b, 11001111b, 00        ; код  
    8.          db  0FFh, 0FFh, 00h, 00h, 00h, 10010010b, 11001111b, 00        ; данные
    9.          db  0FFh, 0FFh, 00h, 80h, 0Bh, 10010010b, 01000000b, 00        ; видеобуфер
    10.          db  0FFh, 0FFh, 00h, 00h, 00h, 10011010b, 00000000b, 00      
    11.  
    12.     GDT_size     equ $-GDT
    13.     GDTR         dw GDT_size-1
    14.                  dd GDT+10000h
    15.  
    16. continue_loading:
    17.     xor eax,eax
    18.  
    19.     ; открываем адресную линию A20
    20.     in   al,92h
    21.     or   al,2
    22.     out  92h,al
    23.  
    24.     cli
    25.     in   al, 70h
    26.     or   al, 80h
    27.     out  70h,al
    28.  
    29.     lgdt fword [GDTR]
    30.  
    31.     mov  eax,cr0
    32.     or al,1
    33.     mov  cr0,eax
    34.  
    35.     jmp  pword 00001000b:PROTECTED_ENTRY;судя по всему не то
    36.  
    37. org $+10000h
    38. use32
    39. PROTECTED_ENTRY:
    40.     mov  ax, 00010000b  ; DATA
    41.     mov  ds, ax
    42.     mov  ss, ax
    43.     mov  ax, 00011000b  ; VIDEO
    44.     mov  es, ax
    45.  
    46.     jmp $
    Поправьте если не прав:
    Выравниваем PROTECTED_ENTRY для far jmp?
    А если так, то как можно прыгнуть на метку входа в PM? Вариант в коде не работает.
     
  2. TermoSINteZ

    TermoSINteZ Синоби даоса Команда форума

    Публикаций:
    2
    Регистрация:
    11 июн 2004
    Сообщения:
    3.546
    Адрес:
    Russia
    Код (Text):
    1. jmp bootcode16-gdt:PM32
    2.  
    3. PM32:
    4.  
    5. <ваш код в защищенном режиме>
    Где
    gdt - Это метка начала таблицы GDT.
    bootcode16 - начало дескриптора код (именно того кода, который сейчас исполнялся (в 16 битном режиме).

    Чтоб было понятно , пример объявления (все что выше и ниже - фасм)
    Код (Text):
    1. align 8
    2. gdt:
    3.     dd 0,0
    4.                        ; [  LIMIT    |      BASE    | PDLSTYPE   GD0ALIMT | BASE ]
    5. bootcode16:
    6.     CODE_descr db 0FFh, 0FFh, 00h, 00h, 00h, 10011000b, 00000000b, 00               ;8h
    7. <другие дескриторы>
    8. gdt_end:
    Суда по всему тут у вас правильно, значит надо проверить дескриптор сегмента кода. Ну и
    я все же не знаю зачем вы делаете это:
    Если это вам нужно то (читайте дальше)

    И еще как то странно псевдодескриптор у вас описан (который вы грузите в GDTR).
    У меня он такой:

    Код (Text):
    1. pGDT32:
    2.   .Limit dw gdtend-gdt  ;GDT limit
    3.   .Base dd gdt             ; 32-bit GDT base
    4.           dd 0
    Тогда вопрос зачем вы прибавляете + 10000h если у вас GDT лежит все равно до директивы org. Выбросьте нафиг эту org . Оно не нужно вам сейчас.
     
  3. Igor1024

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

    Публикаций:
    0
    Регистрация:
    15 окт 2010
    Сообщения:
    345
    Адрес:
    Sliven, Bulgaria
    В BEGINNERS так сделать мне посоветовал Phantom_84.
    мне не подойдёт, поскольку этот код грузит бутлоадер на 01000h:0. Вообще у меня там хранилось значение 0100h+GDT, и никаких выравниваний я не делал.
    Сначала этот мелкий кусок кода выглядел так:
    Код (Text):
    1. use16
    2. start:
    3.     jmp continue_loading
    4.  
    5. GDT:
    6.          dd  0,0
    7.          db  0FFh, 0FFh, 00h, 00h, 00h, 10011010b, 11001111b, 00        ; код  
    8.          db  0FFh, 0FFh, 00h, 00h, 00h, 10010010b, 11001111b, 00        ; данные
    9.          db  0FFh, 0FFh, 00h, 80h, 0Bh, 10010010b, 01000000b, 00        ; видеобуфер
    10.          db  0FFh, 0FFh, 00h, 00h, 00h, 10011010b, 00000000b, 00      
    11.  
    12.     GDT_size     equ $-GDT
    13.     GDTR         dw GDT_size-1
    14.                       dd ?
    15.  
    16. continue_loading:
    17.     mov eax,01000h
    18.     add eax,GDT
    19.     mov dword [GDTR+2],eax
    20.     xor eax,eax
    21.  
    22.     ; открываем адресную линию A20
    23.     in   al,92h
    24.     or   al,2
    25.     out  92h,al
    26.  
    27.  
    28.     cli
    29.     in   al, 70h
    30.     or   al, 80h
    31.     out  70h,al
    32.  
    33.    
    34.     lgdt fword [GDTR]
    35.  
    36.  
    37.     mov  eax,cr0
    38.     or al,1
    39.     mov  cr0,eax
    40.  
    41.     jmp  00001000b:PROTECTED_ENTRY
    42.  
    43. use32
    44. PROTECTED_ENTRY:
    45.     mov  ax, 00010000b
    46.     mov  ds, ax
    47.     mov  ss, ax
    48.     mov  ax, 00011000b  
    49.     mov  es, ax
    50.  
    51.     jmp $
    Но мне сказали, что он неправильный.
    Сейчас попробую Ваш вариант.
     
  4. Igor1024

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

    Публикаций:
    0
    Регистрация:
    15 окт 2010
    Сообщения:
    345
    Адрес:
    Sliven, Bulgaria
    К примеру Great в своей статье по обработке прерываний в PM использовал просто
    Код (Text):
    1.  jmp  00001000b:PM_32
     
  5. Igor1024

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

    Публикаций:
    0
    Регистрация:
    15 окт 2010
    Сообщения:
    345
    Адрес:
    Sliven, Bulgaria
    TermoSINteZ, кстати
    это адрес CODE_descr или я не так понял?
     
  6. TermoSINteZ

    TermoSINteZ Синоби даоса Команда форума

    Публикаций:
    2
    Регистрация:
    11 июн 2004
    Сообщения:
    3.546
    Адрес:
    Russia
    Igor1024
    верно. Тока это офсет. Если быть точнее.
     
  7. Igor1024

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

    Публикаций:
    0
    Регистрация:
    15 окт 2010
    Сообщения:
    345
    Адрес:
    Sliven, Bulgaria
    Да, про оффсет я знаю... Только вот сие никак не работает.
    TermoSINteZ, по Вашему варианту записал так (тоже на FASM'е пишу)
    Код (Text):
    1. jmp pword GDT-code:PM_32
    мне кажется я так неправильно написал...
    Вот объясните мне, почему же нельзя просто сделать jmp pword 08h:PM_32?
     
  8. TermoSINteZ

    TermoSINteZ Синоби даоса Команда форума

    Публикаций:
    2
    Регистрация:
    11 июн 2004
    Сообщения:
    3.546
    Адрес:
    Russia
    Igor1024
    Дело не в джампе у вас. А в адресах и настройке GDT дескриптора видимо.
    А написать можно хоть так хоть так. Разницы никакой, просто в моем случае по коду сразу читается что это, а не видится просто цифра.
     
  9. Igor1024

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

    Публикаций:
    0
    Регистрация:
    15 окт 2010
    Сообщения:
    345
    Адрес:
    Sliven, Bulgaria
    Чего же я в упор не вижу?
    Код (Text):
    1. mov eax,01000h;base address
    2. add eax,GDT      ;linear address
    3. mov dword [GDTR+2],eax
     
  10. Phantom_84

    Phantom_84 New Member

    Публикаций:
    0
    Регистрация:
    6 июн 2007
    Сообщения:
    820
    Код (Text):
    1.     GDT_size     equ $-GDT
    Лучше так не делать! В fasm'е equ делает символьные ссылки. Тебе повезло, что ты это написал там, где написал, иначе бы было совсем плохо. Используй = или label. Плюс можно GDT подровнять на границу 8 байт.

    Код (Text):
    1.     jmp  pword 00001000b:PROTECTED_ENTRY;судя по всему не то
    Самое то. У тебя основные сегменты в GDT описаны, как Flat (база 0). Мы подкорректировали метку PROTECTED_ENTRY, чтобы она совпадала с линейным адресом.

    Код (Text):
    1.     mov eax,01000h
    2.     add eax,GDT
    3.     mov dword [GDTR+2],eax
    4.     xor eax,eax
    Вот это уже фигня. У тебя код загружается по известному адресу, поэтому не нужно вычислять адрес GDT динамически. Я тебе уже написал правильный вариант. Больше повторять не буду:
    Код (Text):
    1.   dd GDT+10000h
    А если все-таки вычисляешь адрес динамически то делай это правильно. База твоего сегмента равна 10000h (1000h*10h).

    Хотелось бы все-таки увидеть код загрузчика, потому что я не уверен, что ты инициализируешь в нем все, что нужно, и делаешь это правильно.
     
  11. TermoSINteZ

    TermoSINteZ Синоби даоса Команда форума

    Публикаций:
    2
    Регистрация:
    11 июн 2004
    Сообщения:
    3.546
    Адрес:
    Russia
    Phantom_84
    У меня тоже была такая мысль. Это было бы лучше, чем кофейная гуща.
     
  12. Igor1024

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

    Публикаций:
    0
    Регистрация:
    15 окт 2010
    Сообщения:
    345
    Адрес:
    Sliven, Bulgaria
    Я разбирал загрузчик от KolibriOS версии 1.0 и для начала решил использовать его код для своих нужд. Инициализация регистров происходит так:
    Код (Text):
    1.         xor     ax,ax
    2.         mov     ss,a
    3.         mov     sp,07c00h
    4.         push    ss
    5.         pop     ds
    Вот, собственно, код загрузчика.
    Код (Text):
    1. lf              equ     0ah
    2. cr              equ     0dh
    3.  
    4. pos_read_tmp    equ     0700h                   ;position for temporary read
    5. boot_program    equ     07c00h                  ;position for boot code
    6. seg_read_kernel equ     01000h                  ;segment to kernel read
    7.  
    8.         jmp     start_program
    9.         nop
    10.  
    11.  
    12. include 'floppy1440.inc'; там BPB
    13.  
    14.  
    15. start_program:
    16.  
    17.         xor     ax,ax
    18.         mov     ss,ax
    19.         mov     sp,boot_program
    20.         push    ss
    21.         pop     ds
    22.  
    23.         ; print loading string
    24.         mov     si,loading+boot_program
    25. loop_loading:
    26.         lodsb
    27.         or      al,al
    28.         jz      read_root_directory
    29.         mov     ah,0eh
    30.         mov     bx,7
    31.         int     10h
    32.         jmp     loop_loading
    33.  
    34. read_root_directory:
    35.         push    ss
    36.         pop     es
    37.  
    38.         ; calculate some disk parameters
    39.         ; - beginning sector of RootDir
    40.         mov     ax,word [BPB_FATSz16+boot_program]
    41.         xor     cx,cx
    42.         mov     cl,byte [BPB_NumFATs+boot_program]
    43.         mul     cx
    44.         add     ax,word [BPB_RsvdSecCnt+boot_program]
    45.         mov     word [FirstRootDirSecNum+boot_program],ax       ; 19
    46.         mov     si,ax
    47.  
    48.         ; - count of sectors in RootDir
    49.         mov     bx,word [BPB_BytsPerSec+boot_program]
    50.         mov     cl,5                            ; divide ax by 32
    51.         shr     bx,cl                           ; bx = directory entries per sector
    52.         mov     ax,word [BPB_RootEntCnt+boot_program]
    53.         xor     dx,dx
    54.         div     bx
    55.         mov     word [RootDirSecs+boot_program],ax              ; 14
    56.  
    57.         ; - data start
    58.         add     si,ax                           ; add beginning sector of RootDir and count sectors in RootDir
    59.         mov     word [data_start+boot_program],si               ; 33
    60.         ; reading root directory
    61.         ; al=count root dir sectrors !!!! TODO: al, max 255 sectors !!!!
    62.         mov     ah,2                            ; read
    63.         push    ax
    64.  
    65.         mov     ax,word [FirstRootDirSecNum+boot_program]
    66.         call    conv_abs_to_THS                 ; convert abs sector (AX) to BIOS T:H:S (track:head:sector)
    67.         pop     ax
    68.         mov     bx,pos_read_tmp                 ; es:bx read buffer
    69.         call    read_sector
    70.  
    71.         mov     si,bx                           ; read buffer address: es:si
    72.         mov     ax,[RootDirSecs+boot_program]
    73.         mul     word [BPB_BytsPerSec+boot_program]
    74.         add     ax,si                           ; AX = end of root dir. in buffer pos_read_tmp
    75.  
    76.         ; find kernel file in root directory
    77. loop_find_dir_entry:
    78.         push    si
    79.         mov     cx,11
    80.         mov     di,kernel_name+boot_program
    81.         rep     cmpsb                          
    82.         pop     si
    83.         je      found_kernel_file
    84.         add     si,32                           ; next dir. entry
    85.         cmp     si,ax                           ; end of directory
    86.         jb      loop_find_dir_entry
    87.  
    88. file_error_message:
    89.         mov     si,error_message+boot_program
    90.  
    91. loop_error_message:
    92.         lodsb
    93.         or      al,al
    94.         jz      freeze_pc
    95.         mov     ah,0eh
    96.         mov     bx,7
    97.         int     10h
    98.         jmp     loop_error_message
    99.  
    100. freeze_pc:
    101.         jmp     $                              
    102.  
    103.         ; === KERNEL FOUND. LOADING... ===
    104.  
    105. found_kernel_file:
    106.         mov     bp,[si+01ah]                    ; first cluster of kernel file
    107.         ; <diamond>
    108.         mov     [cluster1st+boot_program],bp    ; starting cluster of kernel file
    109.         ; <\diamond>
    110.  
    111.         ; reading first FAT table
    112.         mov     ax,word [BPB_RsvdSecCnt+boot_program]   ; begin first FAT abs sector number
    113.         call    conv_abs_to_THS                 ; convert abs sector (AX) to BIOS T:H:S (track:head:sector)
    114.         mov     bx,pos_read_tmp                 ; es:bx read position
    115.         mov     ah,2                            ; ah=2 (read)
    116.         mov     al, byte [BPB_FATSz16+boot_program]     ; FAT size in sectors (TODO: max 255 sectors)
    117.         call    read_sector
    118.         jc      file_error_message              ; read error
    119.  
    120.         mov     ax,seg_read_kernel
    121.         mov     es,ax
    122.         xor     bx,bx                           ; es:bx = 1000h:0000h
    123.  
    124.  
    125.         ; reading kernel file
    126. loop_obtains_kernel_data:
    127.         ; read one cluster of file
    128.         call    obtain_cluster
    129.         jc      file_error_message              ; read error
    130.  
    131.         ; add one cluster length to segment:offset
    132.         push    bx
    133.         mov     bx,es
    134.         mov     ax,word [BPB_BytsPerSec+boot_program]   ;\
    135.         movsx   cx,byte [BPB_SecPerClus+boot_program]   ; | !!! TODO: !!!
    136.         mul     cx                                      ; | out this from loop !!!
    137.         shr     ax,4                                    ;/
    138.         add     bx,ax
    139.         mov     es,bx
    140.         pop     bx
    141.  
    142.         mov     di,bp
    143.         shr     di,1
    144.         pushf
    145.         add     di,bp                           ; di = bp * 1.5
    146.         add     di,pos_read_tmp
    147.         mov     ax,[di]                         ; read next entry from FAT-chain
    148.         popf
    149.         jc      move_4_right
    150.         and     ax,0fffh
    151.         jmp     verify_end_sector
    152. move_4_right:
    153.         mov     cl,4
    154.         shr     ax,cl
    155. verify_end_sector:
    156.         cmp     ax,0ff8h                        ; last cluster
    157.         jae     execute_kernel
    158.         mov     bp,ax
    159.         jmp     loop_obtains_kernel_data
    160.  
    161. execute_kernel:
    162.         ; <diamond>
    163.         mov     ax,'KL'
    164.         push    0
    165.         pop     ds
    166.         mov     si,loader_block+boot_program
    167.         ; </diamond>
    168.         push    word    seg_read_kernel
    169.         push    word    0
    170.         retf                                    ; jmp far 1000:0000
    171.  
    172.  
    173. ;------------------------------------------
    174.         ; loading cluster from file to es:bx
    175. obtain_cluster:
    176.         ; bp - cluster number to read
    177.         ; carry = 0 -> read OK
    178.         ; carry = 1 -> read ERROR
    179.  
    180.         ; print one dot
    181.         push    bx
    182.         mov     ax,0e2eh                        ; ah=0eh (teletype), al='.'
    183.         xor     bh,bh
    184.         int     10h
    185.  
    186.         ; convert cluster number to sector number
    187.         mov     ax,bp                           ; data cluster to read
    188.         sub     ax,2
    189.         xor     bx,bx
    190.         mov     bl,byte [BPB_SecPerClus+boot_program]
    191.         mul     bx
    192.         add     ax,word [data_start+boot_program]
    193.         pop     bx
    194.  
    195. writesec:
    196.         call    conv_abs_to_THS                 ; convert abs sector (AX) to BIOS T:H:S (track:head:sector)
    197. patchhere:
    198.         mov     ah,2                            ; ah=2 (read)
    199.         mov     al,byte [BPB_SecPerClus+boot_program]   ; al=(one cluster)
    200.         call    read_sector
    201.         retn
    202. ;------------------------------------------
    203.  
    204. ;------------------------------------------
    205.         ; read sector from disk
    206. read_sector:
    207.         push    bp
    208.         mov     bp,20                           ; try 20 times
    209. newread:
    210.         dec     bp
    211.         jz      file_error_message
    212.         push    ax bx cx dx
    213.         int     13h
    214.         pop     dx cx bx ax
    215.         jc      newread
    216.         pop     bp
    217.         retn
    218. ;------------------------------------------
    219.         ; convert abs. sector number (AX) to BIOS T:H:S
    220.         ; sector number = (abs.sector%BPB_SecPerTrk)+1
    221.         ; pre.track number = (abs.sector/BPB_SecPerTrk)
    222.         ; head number = pre.track number%BPB_NumHeads
    223.         ; track number = pre.track number/BPB_NumHeads
    224.         ; Return: cl - sector number
    225.         ;         ch - track number
    226.         ;         dl - drive number (0 = a:)
    227.         ;         dh - head number
    228. conv_abs_to_THS:
    229.         push    bx
    230.         mov     bx,word [BPB_SecPerTrk+boot_program]
    231.         xor     dx,dx
    232.         div     bx
    233.         inc     dx
    234.         mov     cl, dl                          ; cl = sector number
    235.         mov     bx,word [BPB_NumHeads+boot_program]
    236.         xor     dx,dx
    237.         div     bx
    238.         ; !!!!!!! ax = track number, dx = head number
    239.         mov     ch,al                           ; ch=track number
    240.         xchg    dh,dl                           ; dh=head number
    241.         mov     dl,0                            ; dl=0 (drive 0 (a:))
    242.         pop     bx
    243.         retn
    244. ;------------------------------------------
    245.  
    246. loading         db      cr,lf,'Starting system ',00h
    247. error_message   db      13,10
    248. kernel_name     db      'KERNEL  BIN ?',cr,lf,00h
    249. FirstRootDirSecNum      dw      ?
    250. RootDirSecs     dw      ?
    251. data_start      dw      ?
    252.  
    253. ; <diamond>
    254. write1st:
    255.         push    cs
    256.         pop     ds
    257.         mov     byte [patchhere+1+boot_program], 3      ; change ah=2 to ah=3
    258.         mov     ax,[cluster1st+boot_program]
    259.         push    1000h
    260.         pop     es
    261.         xor     bx,bx
    262.         call    writesec
    263.         mov     byte [patchhere+1+boot_program], 2      ; change back ah=3 to ah=2
    264.         retf
    265. cluster1st      dw      ?
    266. loader_block:
    267.                 db      1
    268.                 dw      0
    269.                 dw      write1st+boot_program
    270.                 dw      0
    271. ; <\diamond>
    272.  
    273. times   0x1fe-$ db 00h
    274.  
    275.         db      55h,0aah                        ;boot signature
     
  13. Igor1024

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

    Публикаций:
    0
    Регистрация:
    15 окт 2010
    Сообщения:
    345
    Адрес:
    Sliven, Bulgaria
    Мне кажется что с сегментными регистрами всё в порядке, поскольку до этого писал код под RM, который этим же загрузчиком грузился на ура и работал прекрасно.
     
  14. TermoSINteZ

    TermoSINteZ Синоби даоса Команда форума

    Публикаций:
    2
    Регистрация:
    11 июн 2004
    Сообщения:
    3.546
    Адрес:
    Russia
    Igor1024
    В общем подумал я над твоим кодом (перехода в 64 битный режим) немного.
    Первое что бросается в глаза. Корректировка базы псевдодесткриптора. Но на нее Phantom_84 вам указал. Надеюсь вы исправили.
    Надежнее всего сделать так:
    Код (Text):
    1. xor ebx,ebx
    2. mov bx,cs
    3. shl ebx,4    
    4. mov eax,ebx
    5. mov word [CODE_descr+2],bx
    6. rol ebx,16
    7. mov byte [CODE_descr+4],bl
    8.  
    9. add [pGDT32.Base],eax
    Надеюсь понятно.

    Второе, что бросается в глаза.
    Почему ваш код закрытия линии отличается от классического кода закрытия:
    Код (Text):
    1. mov al,0d1h      
    2. out 64h,al      
    3. mov al,0dfh      
    4. out 60h,al
    Ну и прерывания проще всего запретить так (без лишних in):
    Код (Text):
    1. cli
    2. mov      al,80h
    3. out      70h,al
    ну а так вроде все должно работать.
    Третье. Дескриптор данных. Советую его проверить. Нехорошо, если вы его инициализируете в том же где и дескриптор кода. Лучше сделайте ему отдельный регион памяти.

    Проверял тока что свой код, наподобие вашего, но обычный com (org 100h) - работало.

    Прикрепляю код (выход в дос может не сработать (возможно что-то забыл вернуть) - но вы уберете это - вам обратный выход не нужен походу)
     
  15. Igor1024

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

    Публикаций:
    0
    Регистрация:
    15 окт 2010
    Сообщения:
    345
    Адрес:
    Sliven, Bulgaria
    TermoSINteZ, Ваш код прекрасно запустился (ну я потом после перехода в PM hlt вставил, чтоб не возвращаться в RM...). Буду смотреть, менять. Попробую найти где у меня косяк. Спасибо!
     
  16. Phantom_84

    Phantom_84 New Member

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

    Ваши выкладки тоже не безукоризненны. NMI и Gate A20 не так давно обсуждались здесь. Не буду повторяться.

    У вас в этом вопросе сильно устаревшие взгляды. Наоборот нужно, чтобы "сегмент данных" и "сегмент кода" накладывались друг на друга или по крайней мере имели одну и ту же базу. Я бы вообще пока оставил в GDT только первые два дескриптора (не считая обнуленного), а все остальные убрал - к видеобуферу можно обращаться и по смещению 0B8000h.
     
  17. TermoSINteZ

    TermoSINteZ Синоби даоса Команда форума

    Публикаций:
    2
    Регистрация:
    11 июн 2004
    Сообщения:
    3.546
    Адрес:
    Russia
    Phantom_84
    Спасибо. Почитал. Но правда не объясняется почему именно, кроме как аргумента "на старом железе может не работать" и "могут быть проблемы с CMOS". Почему и какие - нету. Ну не будем захламлять тему.
    Устаревшие... Считайте как хотите. Но по крайней мере для ТС было бы хорошо проверить вначале так - как писал я. А потом уже накладывать все. Да и в реальности используют страничную адресацию гораздо чаще (в 64 бите это вообще обязательное условие). Так что - ничего "плохого" я своим советом не сказал.
     
  18. Phantom_84

    Phantom_84 New Member

    Публикаций:
    0
    Регистрация:
    6 июн 2007
    Сообщения:
    820
    Мой вариант:
    Код (Text):
    1.   xor ax,ax
    2.   cli
    3.   mov ss,ax
    4.   xor sp,sp
    5.   sti
    6.  
    7.   jmp 1000h:@f ; при необходимости
    8. @@:
    9.  
    10.   mov ax,1000h
    11.   mov ds,ax ; push cs/pop ds
    12.   mov es,ax ; при необходимости
    13.  
    14.   mov ax,3
    15.   int 10h
    16.  
    17.   mov dx,03F2h
    18.   mov al,0
    19.   out dx,al
    20.  
    21.   cli
    22.  
    23.   mov al,8Fh
    24.   out 70h,al
    25.   in al,71h
    26.  
    27.   lgdt [GDTR]
    28.  
    29.   mov eax,cr0
    30.   or al,1
    31.   mov cr0,eax
    32.  
    33.   jmp fword KCODE:Startup32
    34.  
    35.   align 8
    36. GDT:
    37.   dq 0
    38.  
    39.   label KCODE at $-GDT
    40.   db 0FFh,0FFh,0,0,0,9Ah,0CFh,0 ; desc 0,0FFFFFh,DF_CODE32
    41.  
    42.   label KDATA at $-GDT
    43.   db 0FFh,0FFh,0,0,0,92h,0CFh,0 ; desc 0,0FFFFFh,DF_DATA32
    44.  
    45.   label GDT_SIZE at $-GDT
    46.  
    47. GDTR:
    48.   dw GDT_SIZE-1
    49.   dd GDT+10000h
    50.  
    51.   virtual
    52.   rb 10000h-$
    53.   end virtual
    54.  
    55.   use32
    56.   org $+10000h
    57. Startup32:
    58.   mov ax,KDATA
    59.   mov ds,ax
    60.   mov es,ax
    61.   mov fs,ax
    62.   mov gs,ax
    63.   mov ss,ax
    64.   mov esp,10000h
    65.  
    66.   mov word [0B8000h],700h+"!"
    67.   jmp $
     
  19. Phantom_84

    Phantom_84 New Member

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

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

    Публикаций:
    0
    Регистрация:
    15 окт 2010
    Сообщения:
    345
    Адрес:
    Sliven, Bulgaria
    Phantom_84, Ваш вариант мне больше понравился, но зачем тут общение с контроллером дискеты? Судя по RBIL это именно этот порт.
    А так понял, что до этого неправильно GDT строил.
    Код (Text):
    1. mov dx,03F2h
    2. mov al,0
    3. out dx,al