Проблема передачи управления на считанный 2ой сектор диска

Тема в разделе "WASM.BEGINNERS", создана пользователем vorobei99, 8 мар 2008.

  1. vorobei99

    vorobei99 New Member

    Публикаций:
    0
    Регистрация:
    16 фев 2008
    Сообщения:
    25
    Адрес:
    Moscow
    Код (Text):
    1. ;---------------------------------------------------------------
    2. ;Сектор 1
    3. ;---------------------------------------------------------------
    4. use16
    5. org 0x7C00
    6. jmp 0x0000:main      
    7. nop
    8.  
    9. main:
    10.   xor ax,ax          ;ds=0
    11.   mov ds,ax
    12.  
    13.   mov si,load_msg    ;вывод сообщения
    14.   call print_str
    15.  
    16.   xor ax,ax
    17.   mov es,ax          ;буфер для считывания es:bx=0x0000:0x7E00
    18.   mov bx,0x7E00
    19.  
    20.   mov dl,0           ; номер устройства   = 0
    21.   mov dh,0           ; головка       = 0
    22.   mov ch,0           ; трек         = 0
    23.   mov cl,2           ; сектор       = 2
    24.   mov al,1           ; считать секторов = 1
    25.   mov ah,2
    26.   int 0x13
    27.  
    28.   jc read_error      ; в случае ошибки процедуре read_error передать управление
    29.   xor ax,ax
    30.   mov ds,ax          ;ds=0
    31.   jmp 0x0000:0x7E00  ; прыжок на считанный сектор
    32. ;---------------------------------------------------------------
    33. ;Процедуры
    34. ;---------------------------------------------------------------
    35. print_str:
    36.   mov ah,0x0E
    37.   mov bh,0x00
    38.   mov bl,0x07
    39.  .nextchar:
    40.   lodsb             ; вывод сообщения
    41.   or al,al
    42.   jz .return
    43.   int 0x10
    44.   jmp .nextchar
    45.  .return:
    46. ret
    47.  
    48. read_error:
    49.  mov si,error_msg  
    50.  call print_str
    51.  jmp $
    52. ret
    53. ;---------------------------------------------------------------
    54. ;Данные
    55. ;---------------------------------------------------------------
    56.  
    57. load_msg  db 'Loading Kernel...',13,10,0
    58. error_msg db 'Error',13,10,0
    59. ;---------------------------------------------------------------
    60. times 510-($-$$) db 0     ; дополняем до 510 байт
    61. dw 0xAA55                 ; последние два байта AA и 55
    62.  
    63. ;---------------------------------------------------------------
    64. ;Сектор 2
    65. ;---------------------------------------------------------------
    66. sector2:
    67.   mov si,kernel_msg
    68.   call print_str          ; вывод сообщения о удачно считанном ядре
    69.   hlt
    70. ;---------------------------------------------------------------
    71. ;Данные
    72. ;---------------------------------------------------------------
    73.  
    74. kernel_msg  db 'Loaded Kernel.',13,10,0
    75. ;---------------------------------------------------------------
    Ребята помогите пожалуйста !Борюсь с этой проблемой не первую неделю ни как не выходит.Прочитал наши и забугорные форумы , посмотрел примеры таких загрузчиков и всеровно не работает.Выводит первое сообщение нормально , а второе о считанном ядре ни в какую.Тестирую всё на Qemu.Отладчик gdb не показывает после считавания наличия CF , значит считалось вроде как нормально .В чем же проблема?
     
  2. diamond

    diamond New Member

    Публикаций:
    0
    Регистрация:
    21 май 2004
    Сообщения:
    507
    Адрес:
    Russia
    Код вроде правильный (единственно, вместо hlt в конце лучше ставить jmp $ либо cli/hlt, потому что при просто hlt после первого же прерывания процессор "проглотит" hlt и управление получит мусор, находящийся в памяти). Каким образом он записывается на дискету?
    P.S. Проверил под Bochs - работает.
     
  3. vorobei99

    vorobei99 New Member

    Публикаций:
    0
    Регистрация:
    16 фев 2008
    Сообщения:
    25
    Адрес:
    Moscow
    По умолчанию фасм делает образ дискеты(вот этот код я так вставляю в фасм и компилирую) , я его монтирую в qemu и делаю бут с него.Я исправил в конце на jmp $ - не помогло.Может я в qemu что то не так делаю((
    qemu.exe -L . -m 128 -hda win.img -soundhw all -localtime -M pc -s -fda boot.bin
     
  4. vorobei99

    vorobei99 New Member

    Публикаций:
    0
    Регистрация:
    16 фев 2008
    Сообщения:
    25
    Адрес:
    Moscow
    Действительно в Bochs все работает!Спасибо за помощь!Товарищи , кто знает от чего возникает такая проблема в Qemu отпишитесь пожалуйста
     
  5. diamond

    diamond New Member

    Публикаций:
    0
    Регистрация:
    21 май 2004
    Сообщения:
    507
    Адрес:
    Russia
    Видимо, qemu очень не нравится, когда образ дискеты обрывается на середине сектора - сектор он не читает, хотя и ошибки не выдаёт. Если в конец исходника добавить "times 0x8000-$ db 0", то и под qemu всё нормально.
     
  6. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    А лучше записать это в качестве бутсектора в корректны
     
  7. vorobei99

    vorobei99 New Member

    Публикаций:
    0
    Регистрация:
    16 фев 2008
    Сообщения:
    25
    Адрес:
    Moscow
    Diamond, еще раз спасибо.Вот поизучал статьи те..Опять проблемка..хотя вроде как говорится всё по инструкции делал.

    Теперь загрузчик выглядит так:
    Код (Text):
    1. ;---------------------------------------------------------------
    2. ;Сектор 1
    3. ;---------------------------------------------------------------
    4. use16
    5. org 0x7C00
    6. jmp 0x0000:main      
    7. nop
    8.  
    9. main:
    10.   xor ax,ax          ;ds=0
    11.   mov ds,ax
    12.  
    13.   mov si,load_msg    ;вывод сообщения
    14.   call print_str
    15.  
    16.   mov ax,0x2000
    17.   mov es,ax          ;буфер для считывания es:bx=0x2000:0x0000
    18.   mov bx,0x0000
    19.  
    20.   mov dl,0           ; номер устройства   = 0
    21.   mov dh,0           ; головка       = 0
    22.   mov ch,0           ; трек         = 0
    23.   mov cl,2           ; сектор       = 2
    24.   mov al,9           ; считать секторов = 9
    25.   mov ah,2
    26.   int 0x13
    27.  
    28.   jc read_error      ; в случае ошибки процедуре read_error передать управление
    29.   xor ax,ax
    30.   mov ds,ax          ;ds=0
    31.   jmp 0x2000:0x0000  ; прыжок на считанный сектор
    32. ;---------------------------------------------------------------
    33. ;Процедуры
    34. ;---------------------------------------------------------------
    35. print_str:
    36.   mov ah,0x0E
    37.   mov bh,0x00
    38.   mov bl,0x07
    39.  .nextchar:
    40.   lodsb             ; вывод сообщения
    41.   or al,al
    42.   jz .return
    43.   int 0x10
    44.   jmp .nextchar
    45.  .return:
    46. ret
    47.  
    48. read_error:
    49.  mov si,error_msg  
    50.  call print_str
    51.  jmp $
    52. ret
    53. ;---------------------------------------------------------------
    54. ;Данные
    55. ;---------------------------------------------------------------
    56.  
    57. load_msg  db 'Loading Kernel...',13,10,0
    58. error_msg db 'Error',13,10,0
    59. ;---------------------------------------------------------------
    60. times 510-($-$$) db 0     ; дополняем до 510 байт
    61. dw 0xAA55                 ; последние два байта AA и 55
    62.  
    63. ;---------------------------------------------------------------
    64. ;Сектор 2
    65. ;---------------------------------------------------------------
    66. file 'kernel.bin'
    kernel.bin - размер 4,01 кб (значит надо считать более 8 секторов)
    kernel.bin собирался из трех файлов startup.c kernel.c procs.c

    Код startup.c:
    Код (Text):
    1. void _start(){
    2. kernel_main();
    3. }
    Код procs.c :
    Код (Text):
    1. #define video_width 80    //øèðèíà ýêðàíà
    2. #define video_height 25   //âûñîòà ýêðàíà
    3. #define video_ram 0xB8000 //àäðåñ âèäåîïàìÿòè
    4.  
    5.  
    6. void clear(){
    7.  int i;
    8.  char *video = video_ram;
    9.  
    10.   for (i = 0; i < (video_width*video_height) ; i++){
    11.    *(video + i*2)=' ';
    12.   }    
    13. }
    Код kernel.c :
    Код (Text):
    1. void kernel_main(){
    2.      
    3.      clear();
    4.      for(;;);
    5. }
    Cобирал gcc kernel.bin так:
    gcc -ffreestanding -c -o procs.o procs.c
    gcc -ffreestanding -c -o startup.o startup.c
    gcc -ffreestanding -c -o kernel.o kernel.c

    ld -Ttext 0x200000 -o kernel.bin startup.o procs.o kernel.o
    objcopy kernel.bin -O binary

    В итоге на этапе загрузки всё встает.В чем проблема.В сегменте(при джампе)?или же в самой сборке образа?
     
  8. diamond

    diamond New Member

    Публикаций:
    0
    Регистрация:
    21 май 2004
    Сообщения:
    507
    Адрес:
    Russia
    gcc генерирует 32-битный код, рассчитанный на плоскую модель памяти. На начальной стадии загрузки, в том числе в момент начала исполнения бутсектора, процессор работает в 16-битном реальном режиме. Так что напрямую загружать gcc'шный код нельзя, а нужно сначала выполнить настройку окружения. Пример кода можно взять, например, тут: http://lowlevel.ru/?namespace=osdev8
     
  9. doctor_Ice

    doctor_Ice New Member

    Публикаций:
    0
    Регистрация:
    21 мар 2005
    Сообщения:
    845
    Адрес:
    Russia
    а стек настраивать разве ненужно?
    мой старый кодес...работает

    Код (Text):
    1. ;!-------------------------------------------------------------------------------------------------------------
    2. ;
    3. ; getting started inject code
    4. ;
    5.  
    6. ;% my incs
    7. ;include 'equals.inc'
    8.  
    9.  
    10. b_p                             equ byte   ; 8
    11. w_p                             equ word   ; 16
    12. d_w_p                           equ dword  ; 32
    13. p_w_p                           equ pword  ; 48
    14. q_w_p                           equ qword  ; 64
    15. t_w_p                           equ tword  ; 80
    16. dq_w_p                          equ dqword ; 128
    17.  
    18.  
    19. BootStart = 7c00h
    20.  
    21. use16
    22.  
    23.            org BootStart
    24.  
    25.            cli
    26.            mov       w_p [cs:BootStart-02h], 0
    27.            mov       w_p [cs:BootStart-04h], ss
    28.            mov       ss, w_p [cs:BootStart-02h]
    29.            mov       w_p [cs:BootStart-02h], sp
    30.            mov       sp, BootStart-04h
    31.  
    32.            push      es
    33.            push      ds
    34.            pushad
    35.  
    36.            push      cs
    37.            pop       ds
    38.  
    39.            dec       w_p [cs:0413h]
    40.            mov       ax, w_p [cs:0413h]
    41.            shl       ax, 6 ; *1024/16
    42.            mov       es, ax
    43.  
    44.            mov       si, CodeStart
    45.            xor       di, di
    46.            mov       cx, 512/4
    47.            cld
    48.        rep movsd
    49.  
    50.            push      es
    51.            push      0
    52.            retf
    53.  
    54. CodeStart:
    55.  
    56.            org 0
    57.  
    58.  
    59. ;% indicator
    60.            mov       ax, 0b800h
    61.            mov       es, ax
    62.            mov       w_p [es:0], 'GG'
    63.  
    64.            xor       ax, ax
    65.            int       16h
    66.  
    67.            mov       ax, 201h
    68.            mov       cx, 1
    69.            mov       dx, 80h
    70.            mov       di, 0
    71.            mov       es, di
    72.            mov       bx, BootStart
    73.            int       13h
    74.  
    75. ;% hook int13 and trap
    76.  
    77.            mov       eax, d_w_p [ds:01h*04h]
    78.            mov       d_w_p [cs:MY_INT_01.Old_01], eax
    79.  
    80.            mov       ax, cs
    81.            shl       eax, 10h
    82.            mov       ax, MY_INT_01
    83.            mov       d_w_p [ds:01h*04h], eax
    84.  
    85.  
    86.  
    87.  
    88.            mov       eax, d_w_p [ds:13h*04h]
    89.            mov       d_w_p [cs:MY_INT_13.Old_13], eax
    90.  
    91.            mov       ax, cs
    92.            shl       eax, 10h
    93.            mov       ax, MY_INT_13
    94.            mov       d_w_p [ds:13h*04h], eax
    95.  
    96. ;% go boot
    97.            popad
    98.            pop       ds
    99.            pop       es
    100.  
    101.            cli
    102.            mov       ss, w_p [cs:BootStart-04h]
    103.            mov       sp, w_p [cs:BootStart-02h]
    104.  
    105.         db 0eah
    106.         dw BootStart
    107.         dw 0
    108.  
    109.  
    110. ;!-------------------------------------------------------------------------------------------------------------
    111. ;
    112. ; Int13h handler
    113. ;
    114. ;
    115. MY_INT_13:
    116.            cmp       ah, 02h          ; sectors read?
    117.            je        .SectorsRead
    118.            cmp       ah, 42h          ; extended read?
    119.            je        .SectorsRead
    120.  
    121.            pushf
    122.            call      d_w_p [cs:.Old_13]
    123.  
    124.  
    125.            pushfd
    126.            push      bp
    127.            mov       bp,sp
    128.            or        w_p [ss:bp+02h], 100h        ; set tf flag
    129.            pop       bp
    130.            popfd
    131.            retf      02h
    132.  
    133. ;% back to mama =)
    134.         db 0eah
    135. .Old_13:
    136.         dd 0
    137.  
    138. .SectorsRead:
    139.  
    140.            pushf
    141.            call      d_w_p [cs:.Old_13]
    142.  
    143.            pushfd
    144.            push      bp
    145.            mov       bp,sp
    146.            or        w_p [ss:bp+02h], 100h        ; set tf flag
    147.            pop       bp
    148.            popfd
    149.            retf      02h
    150.  
    151.  
    152.  
    153.  
    154. ;!-------------------------------------------------------------------------------------------------------------
    155. ;
    156. ; Int01h handler
    157. ;
    158. ;
    159. MY_INT_01:
    160.  
    161.  
    162.            push      si
    163.            push      ds
    164.  
    165.            push      bp
    166.            mov       bp, sp
    167.  
    168.            mov       si, w_p [ss:bp+6h]
    169.            mov       ds, w_p [ss:bp+8h]
    170.  
    171.            pop       bp
    172.  
    173.            cmp       w_p [ds:si], 010fh       ; lgdt?
    174.            jne       .NoLgdt
    175.  
    176.            mov       ax, 0b800h
    177.            mov       es, ax
    178.            mov       di, 0
    179.  
    180.            mov       ah, 4
    181.            mov       cx, 32
    182.  
    183. .PutCodeString:
    184.            lodsb
    185.            mov       dl, al
    186.            mov       bh, 0
    187.            mov       bl, al
    188.            shr       bl, 4
    189.            and       bl, 00001111b
    190.            add       bx, HexTable
    191.            mov       al, [cs:bx]
    192.            stosw
    193.            mov       bh, 0
    194.            mov       bl, dl
    195.            and       bl, 00001111b
    196.            add       bx, HexTable
    197.            mov       al, [cs:bx]
    198.            stosw
    199.  
    200.            mov       al, 20h
    201.            stosw
    202.  
    203.            loop      .PutCodeString
    204.  
    205. .EternalPause:
    206.            nop
    207.            jmp       .EternalPause
    208.  
    209. .NoLgdt:
    210.  
    211.  
    212.            pop       ds
    213.            pop       si
    214.  
    215.  
    216.            push      bp
    217.            mov       bp,sp
    218.            or        w_p [ss:bp+06h], 100h        ; set tf flag
    219.            pop       bp
    220.            iret
    221.  
    222.  
    223. ;% back to mama =)
    224.         db 0eah
    225. .Old_01:
    226.         dd 0
    227.  
    228.  
    229. HexTable:
    230. db '0123456789ABCDEF'
    231.  
    232. align 200h
     
  10. vorobei99

    vorobei99 New Member

    Публикаций:
    0
    Регистрация:
    16 фев 2008
    Сообщения:
    25
    Адрес:
    Moscow
    Спасибо.Значит без защищенного ни как не обайдусь))Буду его грызть))Собирал или линковал значит я правильно?Тоесть если бы я хотел адрес загрузки 0x7E00 , то прописал бы при линковке
    ld -Ttext 0x7E0000 -o kernel.bin startup.o procs.o kernel.o
     
  11. rei3er

    rei3er maxim

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    917
    Адрес:
    minsk
    vorobei99
    советую прочитать про скриптовый язык LD
    Код (Text):
    1. # kernel.ld
    2. ENTRY(start)
    3. SECTIONS {
    4.     .text 0x7E00 : AT(0) {
    5.         start = . ;
    6.         *(.text) ;
    7.     }
    8. }
    Код (Text):
    1. # ld -T kernel.ld --oformat binary startup.o kernel.o -o kernel.bin
     
  12. vorobei99

    vorobei99 New Member

    Публикаций:
    0
    Регистрация:
    16 фев 2008
    Сообщения:
    25
    Адрес:
    Moscow
    Честно сколько не пробывал не вышло.Да и какое там окружение надо.На том сайте они делают под защищенный режим.Я хочу просто под реальный режим ..Попробовал как ты диамонд сказал и райзер.Такое впечатление , что он не может найти точку входа в процедуру _start.Если кому не трудно можете сделать так чтобы это всё грузилось и скинуть ,что по пунктам делали.А то делая ,как в статье что-то не выходит.Я использую Fasm и Dev-Cpp(Gcc и LD)