[asm][16 bit] własny os - problem z boot loaderem

0

Witam!

Mam mały problem z boot loaderem, a mianowicie z funkcją 2 przerwania 13h
Obecnie piszę w trybie rzeczywistym, ponieważ chcę potrenować przed napisaniem w pełni własnego graficznego boot loadera i pre loadera dla systemu plików ext2.
Aha i używam nasm-a oraz emulatora qemu pod systemem ubuntu 10.04 PL(polski remix)
mój boot loader:

[ORG 0x7C00]
[BITS 16]
start:

xor ah,ah
mov al, 3
int 10h

mov ah, 2
  mov al, 10 
  xor ch, ch
  mov cl, 2
  mov dh, 0
  mov bx, 0x1000
  mov es, bx
  mov bx, 0
  int 0x13
jc error
mov si, msg_ok
call print_string
xor ah, ah
int 16h

jmp 0x0000:0x1000
error:

mov si, msg_error
call print_string
xor ah, ah

int 16h

mov ax, 5307h
mov cx, 0003h
mov bx, 0001h
int 15h


print_string:
    lodsb           ; załaduj następny znak
    or  al, al      ; sprawdź, czy to już koniec napisu (czy bieżący znak to 0)
    jz  .koniec
    mov ah, 0x0E     
    mov bh, 0x00    ; strona graficzna
    mov bl, 0x07    ; atrybuty tekstu
    int 0x10        
    jmp print_string
    .koniec:
ret


;dane
msg_ok: db "gotowy do załadowania systemu, nacisnij jakis klawisz", 0
msg_error: db "wystapil blad, nacisnij jakis klawisz", 0
times 510 - ($ - start) db 0

;tworzymy znacznik bootsektora
db 0x55
db 0xAA

oraz kernel

[BITS 16]
[ORG 0x0000]

mov al, 0
mov ah, 13h
int 10h

call drawline


hang:
	jmp hang

drawline:

mov ah, 0Ch
mov bh, 0
mov al, 40;
mov cx, [left]
add cx, [len]
mov dx, [top]
int 10h
mov ax, [len]
sub ax, 1
mov [len], ax
cmp ax, 0
jne drawline

ret
;dane
len: db 30
left: db 30
top: db 50

Boot loader jest ładowany poprawnie, ponieważ zanim napisałem ten post prowadziłem eksperymenty z grafiką w kodzie boot loadera.

P.S. Proszę o możliwie szybka odpowiedź.

Pozdrawiam Bartek

1
grabie2 napisał(a)
  mov bx, 0x1000
  mov es, bx
  mov bx, 0
  int 0x13

czyli 0x1000:0x0000?

grabie2 napisał(a)
  jmp 0x0000:0x1000
0

Dzięki za odp ale niestety nie działa

edit:
skompilowałem przykładowy bootloader z kernelem z jakiegoś kursu który kiedyś działał i na qemu nie działa
Na windows'ie używałem bochs ale na ubunty łatwiej mi obsłużyć qemu
aha i uruchamiam qemu tak: "qemu -fda obraz.bin"

1

Jest kilka błędów. Jeden to ten o którym wspomniał Deus czyli po wykonaniu kodu boot loadera skok pod adres 0x1000:0 a nie 0:0x1000.
A teraz kod samego systemu czy raczej prostego programiku.

BITS 16]
[ORG 0x0000]

mov al, 0
mov ah, 13h
int 10h

call drawline


hang:
        jmp hang

drawline:

mov ah, 0Ch
mov bh, 0
mov al, 40;
mov cx, [left]
add cx, [len]
mov dx, [top]
int 10h
mov ax, [len]
sub ax, 1
mov [len], ax
cmp ax, 0
jne drawline

ret
;dane
len: db 30
left: db 30
top: db 50

Po pierwsze boot loader skacze pod adres 0x1000:0 i wykonuje tamtejszy kod. Dane których w nim używasz (len,left,top) znajdują się również w tej pamięci więc musisz ustawić na nie rejestr segmentowy danych czyli dodałem na początku:

mov ax, cs
mov ds, ax

Druga rzecz to pomyłka w rejestrach przy ustawianiu trybu graficznego. Rejestr ah przyjmuje numer funkcji (0 - ustawienie trybu graficznego), a al przyjmuje numer trybu. Więc zmieniłem na:

mov ah, 0
mov al, 13h
int 10h

Trzecia rzecz to dobranie rozmiarów zmiennych. U ciebie jest tak:

mov cx, [left]
...
left: db 30
top: db 50

cx jest rejestrem dwubajtowym, więc wczyta z pod adresu left dwa bajty. U ciebie na zmienne zarezerwowane jest tylko po jednym bajcie to oczywiście jest błędem. Poniżej wklejam poprawny kod.

[BITS 16]
[ORG 0x0000]

mov ax, cs
mov ds, ax

mov ax, 13h
int 10h

call drawline


hang:
        jmp hang

drawline:

mov ah, 0Ch
mov bh, 0
mov al, 40;
mov cx, [left]
add cx, [len]
mov dx, [top]
int 10h
mov ax, [len]
sub ax, 1
mov [len], ax
cmp ax, 0
jne drawline

ret
;dane
len: dw 30
left: dw 30
top: dw 50

Nie da się nauczyć asemblera nie używając debugera.

0

Dzięki zaraz sprawdzę i napiszę czy działa.

edit:
niestety nie działa aha i jak mówiłem

skompilowałem przykładowy bootloader z kernelem z jakiegoś kursu który kiedyś działał i na qemu nie działa

może to wina samego qemu??
PS. wcześniej używałem bochs

0

ale co nie dziala, jakies logi musi miec ten emulator.

0
grabie2 napisał(a)

może to wina samego qemu??
PS. wcześniej używałem bochs

Jak wspomniano wcześniej nie działa to nie jest odpowiedź wystarczająca żeby rozwiązać ten problem. Opisz co się dzieje po uruchomieniu qemu. Czy odpala ci się emulator, czy ładuje się w nim BIOS, jaki jest ostatni komunikat itp.

0

Przecież bochs ma wbudowany debugger...

0

Poskłdam wszystko w kupę:

  • zanim przesiadłem się na ubuntu miałem windows i używałem bochs
  • po przesiadce przerzuciłem się na qemu ponieważ nie mogę ustalić nazwy rom-u dla karty VGA
  • qemu ładuje boot-loader i on działa funkcje rusujące testowałem właśnie w boot-loaderze ale boot-loader nie może załadować kernel-a
  • funkcja 2 przerwania 13h nie zwraca błędu
  • przetestowałem czy w/w funkcja zwraca błąd w systuacji podania 0 sektorów do przeczytania
  • wynik pozytywny
  • miałem błędy w boot-loaderze oraz w kernelu
  • wcześniej skompilowałem inny przykładowy boot-loader i kernel który kiedyś działał na bochs
  • os w pascalu(z $4prog) z wykorzystaniem GRUB-a działa

to chyba wszystko

edit:
błędy poprawione

0

http://en.wikibooks.org/wiki/QEMU/Monitor sekcja log, co masz w tym pliku?

0

Co dokładnie mam wysłać do log'u mam takie opcje:

out_asm show generated host assembly code for each compiled TB
in_asm show target assembly code for each compiled TB
op show micro ops for each compiled TB
op_opt show micro ops before eflags optimization and after liveness analysis
int show interrupts/exceptions in short format
exec show trace before each executed TB (lots of logs)
cpu show CPU state before block translation
pcall show protected mode far calls/returns/exceptions
cpu_reset show CPU state before CPU resets
Pozdrawiam i dziękuję za zainteresowanie

0

dobierz takie żeby pokazywało stan rejestrów procesora z momentu kiedy program się wywalił/zamknął. Później możesz dawać w różnych miejscach "jmp $" i sprawdzać czy rejestry maja oczekiwany stan, głównie tuż przed i po przełączeniu na protected mode. jeżeli coś będzie nie tak to podaj co i w którym miejscu, najlepiej wklej wtedy loga z tego miejsca. btw. na pewno podaj log zaraz po wejściu do "kernela"

0

sorki, zapomniałem że ty nie przełączasz na protected mode, chodzi mi w takim razie po jmp do kernela

0

Witam!

Zlokalizowałem już problem jest nim qemu.
Uruchomiłem system na windzie z bochs-em i ruszył.

Niestety nie wiem czemu tak się dzieje ale nie przejmuję się tym zbytnio.
Na realnych kompach śmiga jak złoto.

Pozdrawiam Bartek

0
grabie2 napisał(a)

Zlokalizowałem już problem jest nim qemu.
Rzadko problemem jest emulator. Pewnie twój kod nie jest do końca poprawny.

0

Wiem ale jak pisałem nie ma to większego znaczenia i tak nie piszę nic poważnego a na 5 kompach z różnymi prockami od 286 do pentium 4 i śmigało bez kłopotów

0

Emulator bywa często elementem wadliwym, ale wiadomo nie zawsze można sprawdzać na prawdziwym sprzęcie. Jednak w przypadku twojego programu to zawiera on takie podstawowe mechanizmy które powinien dobrze realizować qemu. Linuksa to nie posiadam, ale na moim windowsie mam qemu i bochs i jakoś twój system nie sprawił im żadnego problemu.

0

Może np. na ta wersja ma dobyślnie jakiś bios który czegoś tam nie obsługuje albo konfiguracja ja jadę na domyślnej jakt faktem grub działał na qemu

0

Przepraszam, że wznawiam wątek, ale wypaliłem obraz systemu na pednrive u uruchomiłem na moim lapku i:
-bootloader się uruchomił nie wczytał systemu, ale to nie kłopot(bynajmniej na razie)
zgrałem obraz pendrive na dysk lokalny(nie w całości) i uruchomiłem pod qemu(ciekawość) i... DZIAŁA!
wcześniej uruchomiłem go pod bochs(plik po kompilacji) i działał, a skompilowana wersja systemu(nie zgrana z pendrive) nie działa pod qemu
No i pytanie co wywołuje takie zachowanie qemu?
PS. obraz zgrany z pendriva miał około 2,4GB i zamontowałem go pod fda

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.