Vydělávej až 160.000 Kč měsíčně! Akreditované rekvalifikační kurzy s garancí práce od 0 Kč. Více informací.
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Diskuze: Zápis souborového systému na disk

Aktivity
Avatar
Domiy
Neregistrovaný
Avatar
Odpovídá na Martin Dráb
Domiy:15.6.2013 16:43

Jistý si buď sektorem - ostatním si nejsem jist ani já. Vzal jsem to z logiky - první dráhu to překročit nemohlo. A jak to je v praxi s halvou... :) (Já jen na sebe nalepil všechny soubory tak, jak bylo třeba - netuším, jak je to na disku. Žádný nástroj jsem právě nenašel.)

 
Odpovědět
15.6.2013 16:43
Avatar
Domiy
Neregistrovaný
Avatar
Odpovídá na Martin Dráb
Domiy:15.6.2013 16:47

Disk je přeci tady:

mov [BootDev], dl
mov ah, 8h
int 13h

Později to snad nějak rozvětvím...

 
Nahoru Odpovědět
15.6.2013 16:47
Avatar
Martin Dráb
Tvůrce
Avatar
Martin Dráb:15.6.2013 17:55

Já to s těma CHS adresama také moc neumím. Zkoušel jsem to cca před pěti lety a ani nevím, zda jsem to tehdy naprogramoval dobře, protože pár dní na to díky chybě v synchronizaci zmizela většina souborového systému z disku...

Myslím, že by bylo lepší se problémy s cylindry, hlavami, stopami a sektory vyhnout tím, že pro čtení využiješ funkci 42h (Extended Read) viz http://en.wikipedia.org/wiki/Int_13h#…. Pak se stačí jen zadat číslo sektoru a je hotovo.

U toho tvého kódu ještě nevidím nastavovaní registru ES, který bys mohl třeba vynulovat předtím, než načítáš ty sektory (aby ES:BX ukazovalo na nějaou rozumnou adresu).

Nahoru Odpovědět
15.6.2013 17:55
2 + 2 = 5 for extremely large values of 2
Avatar
Domiy
Neregistrovaný
Avatar
Odpovídá na Martin Dráb
Domiy:15.6.2013 17:59

Nevidím tam registr pro parametr sektoru a počtu sektorů k načtení do paměti... Paměť je mi jedno jaká to bude - prostě do ní pak skočím... (Jak sám jistě vidíš...)

 
Nahoru Odpovědět
15.6.2013 17:59
Avatar
Domiy
Neregistrovaný
Avatar
Odpovídá na Martin Dráb
Domiy:15.6.2013 18:03

Ale já tu adresu nastavil - ne? :)

mov si, 32768
mov bx, si

Nebo alespoň to jsem tam měl před změnou souborového systému a běželo to...

 
Nahoru Odpovědět
15.6.2013 18:03
Avatar
Domiy
Neregistrovaný
Avatar
Odpovídá na Martin Dráb
Domiy:15.6.2013 18:23

Vyčištěno:

BITS 16

jmp short Boot
nop

OEMLabel db "SMA-BOOT"                          ; Disk label
BytesPerSector dw 512                           ; Bytes per sector
SectorsPerCluster db 1                          ; Sectors per Cluster
ReservedForBoot dw 1                            ; Reserved sectors for boot record
LogicalSectors dw 2880                          ; Number of logical sectors
MediumByte db 0F0h                                      ; Medium descriptor byte
SectorsPerTrack dw 18                           ; Sectors per track (36/cylinder)
Sides dw 2                                              ; Number of sides/heads
HiddenSectors dd 0                                      ; Number of hidden sectors
LargeSectors dd 0                                       ; Number of LBA sectors
DriveNo dw 0                                            ; Drive No: 0
Signature db 41                                         ; Drive signature: 41 for disk
VolumeID dd 00000000h
VolumeLabel db "SMA-OP     "
FileSystem db "DSP     "

SMA.Load:

        mov ah, 42h
        mov al, 37
        mov cl, 2
        mov si, 32768
        mov bx, si
        int 13h

        ret

Boot:

        mov ax, 07C0h                                   ; Set up 4K of stack space above Buffer
        add ax, 544                                     ; 8k Buffer = 512 paragraphs + 32 paragraphs (loader)
        cli                                                     ; Disable interrupts while changing stack
        mov ss, ax
        mov sp, 4096
        sti                                                     ; Restore interrupts

        mov ax, 07C0h                                   ; Set data segment to where we're loaded
        mov ds, ax
                                                                ; NOTE: A few early BIOSes are reported to improperly set DL

        cmp dl, 0
        je NoChange

        mov [bootDev], dl                               ; Save boot device number
        mov ah, 8h                                      ; Get drive parameters
        int 13h

        jc FataldiskError

NoChange:

        mov eax, 0

        mov cx, 32768
        call SMA.Load

        jc FataldiskError

        mov ax, 0
        mov bx, 0
        mov cx, 0
        mov dx, 0
        mov di, 0
        mov si, 0

        jmp 32768

PrintString:

        pusha

        mov ah, 0Eh

.write:

        lodsb

        cmp al, 0
        je .done

        int 10h
        jmp short .write

.done:

        popa
        ret

FataldiskError:

        mov si, diskError
        call PrintString

Reboot:

        mov ax, 0
        int 16h                                         ; Wait for keystroke

        mov ax, 0
        int 19h

diskError db "Disk error! Press any key...", 0
bootDev db 0                                            ; Boot device number

times 510-($-$$) db 0                           ; Pad remainder of boot sector with zeros
dw 0AA55h                                               ; Boot signature (DO NOT CHANGE!)

Buffer:                                                 ; Disk Buffer begins (8k after this, stack starts)

Jediné čím si nejsem jist - zda se správně nastaví buffer. To se dozvím později... :)

 
Nahoru Odpovědět
15.6.2013 18:23
Avatar
Martin Dráb
Tvůrce
Avatar
Martin Dráb:15.6.2013 18:50

Ten buffer pro načtená data je určen registry ES:BX. Nevidím tam nikde, že bys nastavoval registr ES. Ale je možné, že tento registr je ve výchozím nastavení nulový, takže není pořádně co nastavovat.

Ta funkce 42h (Extended Read) funguje jinak - parametry operace se ukládají do paměti, ne do registrů AFAIK.

Tohle je část mého MBR, která načítá originální MBR, který je uložen na sektoru 1 (druhý sektor).

        mov ax, 04200h
        push ax
        mov dx, 80h
        mov si, @data
        add si, 6000h
        push si
        int 13h
        pop si
        jmp nekam_dal
data:
        dw 10h       ; structure length
        dw 1         ; sector count
        dw 7c00h     ; buffer address (offset)
        dw 0         ; buffer address (segment)
        dd 1         ; Secntor number (low 32 bits)
        dd 0         ; Sector number (high 32 bits)
nekam_dal:
Editováno 15.6.2013 18:54
Nahoru Odpovědět
15.6.2013 18:50
2 + 2 = 5 for extremely large values of 2
Avatar
Domiy
Neregistrovaný
Avatar
Odpovídá na Martin Dráb
Domiy:15.6.2013 19:02

Nechceš mi poslat kód pro můj případ? (Jsem zničen z toho dorovnání kernelu. Vše je při stavění správně, ale výsledek je větší o 2 sektory - poslední navíc není plný...)

 
Nahoru Odpovědět
15.6.2013 19:02
Avatar
Domiy
Neregistrovaný
Avatar
Odpovídá na Martin Dráb
Domiy:15.6.2013 19:38

Je to tam! :) Ještě to zobecním pro všechny vstupy a juknu se na toto...

 
Nahoru Odpovědět
15.6.2013 19:38
Avatar
Domiy
Neregistrovaný
Avatar
Odpovídá na Martin Dráb
Domiy:16.6.2013 6:46
SMA.Load:

        mov ah, 42h
        mov si, .SMA.Load.Params
        mov dl, bootDev
        int 13h

        ret

.SMA.Load.Params:

        dw 10h                                          ; structure length
        dw 38                                           ; sector count
        dw 7c00h                                                ; buffer address (offset)
        dw 0                                                    ; buffer address (segment)
        dd 1                                                    ; Secntor number (low 32 bits)
        dd 0                                                    ; Sector number (high 32 bits)

Skáči tedy na 7c00h, jenže nic se nenačte... První věc - jedná se o druhý, nebo první sektor? Tedy má myšlenka - když nastavím velikost sektoru na 1024, tak VBR přeci bude pořád 512 - ne? Takže mám VBR zahrnovat? Druhá věc - co znamená údaj "structure length"?
Děkuji.

 
Nahoru Odpovědět
16.6.2013 6:46
Avatar
Martin Dráb
Tvůrce
Avatar
Martin Dráb:16.6.2013 11:16

Skáči tedy na 7c00h

Jakým způsobem to spouštíš a ladíš? Na jaké adrese se nachází tento boot. sektor?

První věc - jedná se o druhý, nebo první sektor?

Druhý sektor. U LBA se sektory číslují od nuly.

co znamená údaj "structure length"?

Velikost struktury s parametry služby 42h, předávané v DS:SI. Viz Wikipedie nebo třeba Ralph Brown's Interrupt List (či jiná dokumentace, kde se popisují přerušení BIOSu).

Nahoru Odpovědět
16.6.2013 11:16
2 + 2 = 5 for extremely large values of 2
Avatar
Domiy
Neregistrovaný
Avatar
Odpovídá na Martin Dráb
Domiy:16.6.2013 11:36

Pokud se čísluje od 0, tak je to 1. sektor - ne? (0 = BootSector, 1 = Kernel - kernel je hned za VBR) Jde mi o to, že když dám velikost sektoru 1024, VBR bude stejně 512 - ne? A jak by mohl číst 512byte sektor s nastaveným sektorem 1024... Nehádám se - jen si potřebuji udělat jasno. VBR se tedy počítá?

Aktuální stav:

BITS 16

SMA.Load.Params:

        dw 10h                                          ; structure length
        dw 38                                           ; sector count
        dw 7c00h                                                ; buffer address (offset)
        dw 0                                                    ; buffer address (segment)
        dd 0                                                    ; Secntor number (low 32 bits)
        dd 2                                                    ; Sector number (high 32 bits)

jmp short Boot
nop

OEMLabel db "SMA-BOOT"                          ; Disk label
BytesPerSector dw 512                           ; Bytes per sector
SectorsPerCluster db 1                          ; Sectors per Cluster
ReservedForBoot dw 1                            ; Reserved sectors for boot record
LogicalSectors dw 2880                          ; Number of logical sectors
MediumByte db 0F0h                                      ; Medium descriptor byte
SectorsPerTrack dw 18                           ; Sectors per track (36/cylinder)
Sides dw 2                                              ; Number of sides/heads
HiddenSectors dd 0                                      ; Number of hidden sectors
LargeSectors dd 0                                       ; Number of LBA sectors
DriveNo dw 0                                            ; Drive No: 0
Signature db 41                                         ; Drive signature: 41 for disk
VolumeID dd 00000000h
VolumeLabel db "SMA-OP     "
FileSystem db "DSP     "

SMA.Load:

        mov ah, 42h
        mov si, SMA.Load.Params
        mov dl, bootDev
        int 13h

        ret

Boot:

        mov ax, 07C0h                                   ; Set up 4K of stack space above Buffer
        add ax, 544                                     ; 8k Buffer = 512 paragraphs + 32 paragraphs (loader)
        cli                                                     ; Disable interrupts while changing stack
        mov ss, ax
        mov sp, 4096
        sti                                                     ; Restore interrupts

        cmp dl, 0                                               ; A few early BIOSes are reported to improperly set DL
        je NoChange

        mov [bootDev], dl                               ; Save boot device number
        mov ah, 8h                                      ; Get drive parameters
        int 13h

        jc FataldiskError

NoChange:

        mov eax, 0

        call SMA.Load

        jc FataldiskError

        mov ax, 0
        mov bx, 0
        mov cx, 0
        mov dx, 0
        mov di, 0
        mov si, 0

        jmp 7c00h

PrintString:

        pusha

        mov ah, 0Eh

.write:

        lodsb

        cmp al, 0
        je .done

        int 10h
        jmp short .write

.done:

        popa
        ret

FataldiskError:

        mov si, diskError
        call PrintString

Reboot:

        mov ax, 0
        int 16h                                         ; Wait for keystroke

        mov ax, 0
        int 19h

diskError db "Disk error! Press any key...", 0xA, 0
bootDev db 0                                            ; Boot device number

times 510-($-$$) db 0                           ; Pad remainder of boot sector with zeros
dw 0AA55h                                               ; Boot signature (DO NOT CHANGE!)

Buffer:                                                 ; Disk Buffer begins (8k after this, stack starts)

Jak jsem psal již někde nahoře - chci jen ušetřit zbytečné hledání a přesně vytyčit co z BootSectoru načíst. (Kernel jen pro začátek.) Kernel si pak již přečte načtené atd.

A aktuálně skládám soubory do systému přeložením do binární podoby, dorovnáním do čísla dělitelného 512 a přilepením do fronty... Jak se mi podaří spustit kernel, přidám své vysněné soubory a systémové funkce... (Stejným způsobem.)

 
Nahoru Odpovědět
16.6.2013 11:36
Avatar
Domiy
Neregistrovaný
Avatar
Odpovídá na Martin Dráb
Domiy:16.6.2013 11:42

A mám na tebe ještě jeden dotaz. Jak si vezme počítač ty parametry nahoře:

OEMLabel db "SMA-BOOT"                         ; Disk label
BytesPerSector dw 512                          ; Bytes per sector
SectorsPerCluster db 1                         ; Sectors per Cluster
ReservedForBoot dw 1                           ; Reserved sectors for boot record
LogicalSectors dw 2880                         ; Number of logical sectors
MediumByte db 0F0h                                     ; Medium descriptor byte
SectorsPerTrack dw 18                          ; Sectors per track (36/cylinder)
Sides dw 2                                             ; Number of sides/heads
HiddenSectors dd 0                                     ; Number of hidden sectors
LargeSectors dd 0                                      ; Number of LBA sectors
DriveNo dw 0                                           ; Drive No: 0
Signature db 41                                                ; Drive signature: 41 for disk
VolumeID dd 00000000h
VolumeLabel db "SMA-OP     "
FileSystem db "DSP     "

Nikde jsem nenašel jak to funguje. Záleží na čem? Na pojmenování? (minimálně case je všude jiné) Myslíš, že mám vše potřebné ke správnému čtení clusterů a hlavně sektorů?

Díky.

 
Nahoru Odpovědět
16.6.2013 11:42
Avatar
Martin Dráb
Tvůrce
Avatar
Martin Dráb:16.6.2013 13:02

A mám na tebe ještě jeden dotaz. Jak si vezme počítač ty parametry nahoře

komponentě zodpovědné za práci se souborovými systémy FAT je srdečně jedno, jak si jednotlivé položky v boot. sektoru pojmenuješ. Klidně si můžeš vzít Erbenova Vodníka a jako názvy jednotlivých položek zvolit jeho úvodní vere. Operační systém názvy nevidí, vidí jen výslednou strukturu boot. sektoru po překladu. Takže pro něj je důležité, aby všechny položky byly na správném místě a aby obsahovaly správná data.

V tom kódu výše jsi předřadil ta data pro 13h Extended Read začátku toho boot. sektoru, takže se v tom FAT driver absolutně nevyzná. Ta data umisti někam do bootovacího kódu. A tak, jak jsi je upravil, tak se bude driver pokoušet načíst sektor s číslem 200000000h (číslováno od nuly), což asi nechceš. x86 je little-endian platforma.

Nechci se tě dotknout, ale doporučoval bych ti si přečíst nějakou knížku o obecných pricnipech, které se v operačních systémech používají (včetně souborových systémů). Docela dobrá knížka je třeba http://www.amazon.com/…p/0131429388. V mojí knize je toho také docela dost platného nejen pro Windows, ale ta cena za to je pro tebe moc vysoká.

Nahoru Odpovědět
16.6.2013 13:02
2 + 2 = 5 for extremely large values of 2
Avatar
Domiy
Neregistrovaný
Avatar
Odpovídá na Martin Dráb
Domiy:16.6.2013 13:13

Já si to myslel... (Že to bere jako celek.)

Pozice struktury parametrů jsem se snažil zařadit tak, aby to nevzalo co nemá... Takže:

BITS 16

jmp short Boot
nop

OEMLabel db "SMA-BOOT"                          ; Disk label
BytesPerSector dw 512                           ; Bytes per sector
SectorsPerCluster db 1                          ; Sectors per Cluster
ReservedForBoot dw 1                            ; Reserved sectors for boot record
NumberOfDSPs db 2                                       ; Number of copies of the DSP
RootDirEntries dw 224                           ; Number of entries in root dir
                                                                ; (224 * 32 = 7168 = 14 sectors to read)
LogicalSectors dw 2880                          ; Number of logical sectors
MediumByte db 0F0h                                      ; Medium descriptor byte
SectorsPerDSP dw 9                                      ; Sectors per DSP
SectorsPerTrack dw 18                           ; Sectors per track (36/cylinder)
Sides dw 2                                              ; Number of sides/heads
HiddenSectors dd 0                                      ; Number of hidden sectors
LargeSectors dd 0                                       ; Number of LBA sectors
DriveNo dw 0                                            ; Drive No: 0
Signature db 41                                         ; Drive signature: 41 for disk
VolumeID dd 00000000h
VolumeLabel db "SMA-OP     "
FileSystem db "DSP     "

SMA.Load:

        mov ah, 42h
        mov si, .SMA.Load.Params
        mov dl, bootDev
        int 13h

        ret

.SMA.Load.Params:

        dw 10h                                          ; structure length
        dw 38                                           ; sector count
        dw 7c00h                                                ; buffer address (offset)
        dw 0                                                    ; buffer address (segment)
        dd 0                                                    ; Secntor number (low 32 bits)
        dd 2                                                    ; Sector number (high 32 bits)

Boot:

        mov ax, 07C0h                                   ; Set up 4K of stack space above Buffer
        add ax, 544                                     ; 8k Buffer = 512 paragraphs + 32 paragraphs (loader)
        cli                                                     ; Disable interrupts while changing stack
        mov ss, ax
        mov sp, 4096
        sti                                                     ; Restore interrupts

        cmp dl, 0                                               ; A few early BIOSes are reported to improperly set DL
        je NoChange

        mov [bootDev], dl                               ; Save boot device number
        mov ah, 8h                                      ; Get drive parameters
        int 13h

        jc FataldiskError

NoChange:

        mov eax, 0

        call SMA.Load

        jc FataldiskError

        mov ax, 0
        mov bx, 0
        mov cx, 0
        mov dx, 0
        mov di, 0
        mov si, 0

        jmp 7c00h

PrintString:

        pusha

        mov ah, 0Eh

.write:

        lodsb

        cmp al, 0
        je .done

        int 10h
        jmp short .write

.done:

        popa
        ret

FataldiskError:

        mov si, diskError
        call PrintString

Reboot:

        mov ax, 0
        int 16h                                         ; Wait for keystroke

        mov ax, 0
        int 19h

diskError db "Disk error! Press any key...", 0xA, 0
bootDev db 0                                            ; Boot device number

times 510-($-$$) db 0                           ; Pad remainder of boot sector with zeros
dw 0AA55h                                               ; Boot signature (DO NOT CHANGE!)

Buffer:                                                 ; Disk Buffer begins (8k after this, stack starts)

?

 
Nahoru Odpovědět
16.6.2013 13:13
Avatar
Martin Dráb
Tvůrce
Avatar
Martin Dráb:17.6.2013 14:54
dw 10h                                          ; structure length
dw 38                                           ; sector count
dw 7c00h                                                ; buffer address (offset)
dw 0                                                    ; buffer address (segment)
dd 0                                                    ; Secntor number (low 32 bits)
dd 2

bych upravil na

dw 10h                                          ; structure length
dw 38                                           ; sector count
dw 7c00h                                                ; buffer address (offset)
dw 0                                                    ; buffer address (segment)
dd 2                                                    ; Secntor number (low 32 bits)
dd 0

pokud chceš načíst sektor s číslem 2 (který předcházejí sektory s číslem 0 a 1).

Nahoru Odpovědět
17.6.2013 14:54
2 + 2 = 5 for extremely large values of 2
Avatar
Domiy
Neregistrovaný
Avatar
Odpovídá na Martin Dráb
Domiy:17.6.2013 15:28

Už mi pomohl ten kamarád, co mi opravil disk. Sector a Secntor je jako AX a AL.

.SMA.Load.Params:

        dw 10h                                          ; structure length
        dw 38                                           ; sector count
        dw 7c00h                                                ; buffer address (offset)
        dw 0                                                    ; buffer address (segment)
        dd 1                                                    ; Secntor number (low 32 bits)
        dd 0                                                    ; Sector number (high 32 bits)

Nejde. Kernel je hned za VBR a má 38 sektorů. (disk s VBR 39) Chci načíst ten kernel. Tak jak? (zoufale) :)

Díky.

 
Nahoru Odpovědět
17.6.2013 15:28
Avatar
Martin Dráb
Tvůrce
Avatar
Martin Dráb:17.6.2013 16:37

Jakým způsobem to spouštíš? Ono by to asi chtělo si rozchodit nějaké ladící prostředí pro tyto účely (nevím, zda bude stačit zkompilovat Bochs v debug módu).

Nahoru Odpovědět
17.6.2013 16:37
2 + 2 = 5 for extremely large values of 2
Avatar
Domiy
Neregistrovaný
Avatar
Odpovídá na Martin Dráb
Domiy:17.6.2013 16:52

Vždyť tu vše je - načtu to do adresy, na kterou pak skočím... Vše je napsané v Assembly - takže kernel překládám do binárního souboru. Když to bylo ve VFATu, vše jelo. Změnil jsem pouze to, že již nehledám hlavní adresář a kernel.

 
Nahoru Odpovědět
17.6.2013 16:52
Avatar
Martin Dráb
Tvůrce
Avatar
Martin Dráb:17.6.2013 17:30

Vždyť tu vše je

Já se jen snažím naznačit, že je někdy dobré si ten kód odkrokovat, aby člověk věděl, co se opravdu děje. Zvláště v těchto případech. A to zastáncem používání debuggermu nejsem.

Napadá mě ještě pár věcí:

  1. na jaké adrese tvůj bootsektor předpokládá, že poběží? Na 0x7C00?
  2. Pe takovým způsobem opravdu kompilován (tzn. absolutní adresy jsou překládány na 7Cxxh? Zvláště u SMA.Load.Params)?
  3. Pokud je tvůj bootsector na adrese 0x7c00 a kernel načítáš také na adresu 0x7c00, nepřepíšeš si tím kód tvého bootsektoru, takže do kernelu nikdy neskočíš (když si třeba disassembluješ MBR, tak ten se hned během prvních několika instrukcí kopíruje (relokuje) z 0x7c00 na 0x600)?
  4. Není chybně nastavován zásobník (registry SS:SP)? Provádíš to kódem:
mov ax, 07C0h                                   ; Set up 4K of stack space above Buffer
add ax, 544                                     ; 8k Buffer = 512 paragraphs + 32 paragraphs (loader)
cli                                                     ; Disable interrupts while changing stack
mov ss, ax
mov sp, 4096
sti

což znamená, že vrchol zásobníku je na 0x9e0:0x1000 = 0xAE00 (pokud dobře počítám). Přijde mi, že pokud má kernel 38 sektorů a jeho začátek je načten na 0x7c00, tak přepíše všechno až do adresy 0xC800, tedy i tvůj zásobník. Navíc případné pokusy o ukládání na zásobník přepisují kód kernelu.

Programování (zvláště v případech, kdy se těžko ladí) je podle mého názoru hodně o pokoře a o tom, že se snažíš nepředpokládat, že nejaká část tvého kódu je dobře, dokud to opravdu neověříš. Emoce sem nepatří.

Nahoru Odpovědět
17.6.2013 17:30
2 + 2 = 5 for extremely large values of 2
Avatar
Domiy
Neregistrovaný
Avatar
Odpovídá na Martin Dráb
Domiy:17.6.2013 17:44

Já jsem sem nepřivedl 7c00h. Ve VFAT verzi mám tu adresu 2000h. Kde píši, že je jaký kus kódu vpořádku? Copak se naopak neustále neptám, zda je to OK? Kde vidíš mé emoce?

 
Nahoru Odpovědět
17.6.2013 17:44
Avatar
Martin Dráb
Tvůrce
Avatar
Martin Dráb:17.6.2013 18:16

I když ti já řeknu, že je to OK, tak to nic neznamená, protože jsem si ten kód nedal do VBR a nespustil. Což dělat nebudu, protože tu nemám připravené ladící prostředí (když jsem psal MBR, tak jsem to zkoušel bez ladění; stálo to více času, ale nakonec se to podařilo).

V poslední verzi tvého kódu jsem objevil ty věci, které jsem psal v minulém příspěvku. Pokud jsi je opravil a stále to nefunguje, je asi čas si to zkusit prokrokovat. Což není legrace, protože nainstalovat nějaké prostředí, ve kterém to půjde, asi nebude snadné.

Nahoru Odpovědět
17.6.2013 18:16
2 + 2 = 5 for extremely large values of 2
Avatar
Domiy
Neregistrovaný
Avatar
Odpovídá na Martin Dráb
Domiy:18.6.2013 7:16

Vzal jsem vše potřebné z VFAT a stejně k ničemu... :)

BITS 16

jmp short Boot
nop

db "SMA-BOOT" ; Disk label
dw 512 ; Bytes per sector
db 1 ; Sectors per Cluster
dw 1 ; Reserved sectors for boot record
db 2 ; Number of copies of the DSP
dw 0 ; Number of root directory entires
dw 39 ; Number of logical sectors
db 0F0h ; Medium descriptor byte
dw 0 ; Sectors per FAT
dw 63 ; Sectors per track
dw 2 ; Number of sides/heads
dd 0 ; Number of hidden sectors
dd 0 ; Number of LBA sectors
dw 0 ; Drive No: 0
db 41 ; Drive signature: 41 for disk
dd 00000000h ; Volume ID
db "SMA-OP     " ; Volume label
db "DSP     " ; File System

Boot:

        mov ax, 07C0h                                   ; Set up 4K of stack space above Buffer
        add ax, 544                                     ; 8k Buffer = 512 paragraphs + 32 paragraphs (loader)
        cli                                                     ; Disable interrupts while changing stack
        mov ss, ax
        mov sp, 4096
        sti                                                     ; Restore interrupts

        cmp dl, 0                                               ; A few early BIOSes are reported to improperly set DL
        je NoChange

        mov ah, 8h                                      ; Get drive parameters
        int 13h

        jc FataldiskError

NoChange:

        mov eax, 0                                              ; Prepare to enter loop

        call SMA.Load

        jc FataldiskError

        jmp 2000h:0000h

PrintString:

        pusha

        mov ah, 0Eh

.write:

        lodsb

        cmp al, 0
        je .done

        int 10h
        jmp short .write

.done:

        popa
        ret

SMA.Load:

        mov ah, 42h
        mov si, .SMA.Load.Params
        int 13h

        ret

.SMA.Load.Params:

        dw 10h                                          ; structure length
        dw 38                                           ; sector count
        dw Buffer                                               ; buffer address (offset)
        dw 2000h                                                ; buffer address (segment)
        dd 1                                                    ; Secntor number (low 32 bits)
        dd 0                                                    ; Sector number (high 32 bits)

FataldiskError:

        mov si, diskError
        call PrintString

Reboot:

        mov ax, 0
        int 16h                                         ; Wait for keystroke

        mov ax, 0
        int 19h

diskError db "Disk error! Press any key...", 0

times 510-($-$$) db 0                           ; Pad remainder of boot sector with zeros
dw 0AA55h                                               ; Boot signature (DO NOT CHANGE!)

Buffer:                                                 ; Disk Buffer begins (8k after this, stack starts)
BITS 16

jmp short Boot
nop

OEMLabel db "SMA-BOOT"                          ; Disk label
BytesPerSector dw 512                           ; Bytes per sector
SectorsPerCluster db 1                          ; Sectors per Cluster
ReservedForBoot dw 1                            ; Reserved sectors for boot record
NumberOfFATs db 2                                       ; Number of copies of the FAT
RootDirEntries dw 224                           ; Number of entries in root dir
                                                                ; (224 * 32 = 7168 = 14 sectors to read)
LogicalSectors dw 2880                          ; Number of logical sectors
MediumByte db 0F0h                                      ; Medium descriptor byte
SectorsPerFAT dw 9                                      ; Sectors per FAT
SectorsPerTrack dw 18                           ; Sectors per track (36/cylinder)
Sides dw 2                                              ; Number of sides/heads
HiddenSectors dd 0                                      ; Number of hidden sectors
LargeSectors dd 0                                       ; Number of LBA sectors
DriveNo dw 0                                            ; Drive No: 0
Signature db 41                                         ; Drive signature: 41 for disk
VolumeID dd 00000000h                           ; Volume ID: any number
VolumeLabel db "SMA-OP     "                    ; Volume Label: any 11 chars
FileSystem db "FAT12   "                                ; File system type: don't change!

Boot:

        mov ax, 07C0h                                   ; Set up 4K of stack space above Buffer
        add ax, 544                                     ; 8k Buffer = 512 paragraphs + 32 paragraphs (loader)
        cli                                                     ; Disable interrupts while changing stack
        mov ss, ax
        mov sp, 4096
        sti                                                     ; Restore interrupts

        mov ax, 07C0h                                   ; Set data segment to where we're loaded
        mov ds, ax
                                                                ; NOTE: A few early BIOSes are reported to improperly set DL

        cmp dl, 0
        je NoChange
        mov [BootDev], dl                               ; Save boot device number
        mov ah, 8                                       ; Get drive parameters
        int 13h
        jc FatalDiskError
        and cx, 3Fh                                     ; Maximum sector number
        mov [SectorsPerTrack], cx               ; Sector numbers start at 1
        movzx dx, dh                                    ; Maximum head number
        add dx, 1                                               ; Head numbers start at 0 - add 1 for total
        mov [Sides], dx

NoChange:

        mov eax, 0                                      ; Needed for some older BIOSes

                                                                ; First, we need to load the root directory from the disk. Technical details:
                                                                ; Start of root = ReservedForBoot + NumberOfFATs * SectorsPerFAT = logical 19
                                                                ; Number of root = RootDirEntries * 32 bytes/entry / 512 bytes/sector = 14
                                                                ; Start of user data = (start of root) + (number of root) = logical 33

DiskOK:                                                 ; Ready to read first block of data

        mov ax, 19                                      ; Root dir starts at logical sector 19
        call l2hts

        mov si, Buffer                                  ; Set ES:BX to point to our Buffer (see End of code)
        mov bx, ds
        mov es, bx
        mov bx, si

        mov ah, 2                                       ; Params for int 13h: read disk sectors
        mov al, 14                                      ; And read 14 of them

        pusha                                           ; Prepare to enter loop


ReadRootDir:

        popa                                                    ; In case registers are altered by int 13h
        pusha

        stc                                                     ; A few BIOSes do not set properly on error
        int 13h                                         ; Read sectors using BIOS

        jnc SearchDir                                   ; If read went OK, skip ahead
        call ResetDisk                                  ; Otherwise, reset disk controller and try again
        jnc ReadRootDir                         ; Floppy reset OK?

        jmp Reboot                                      ; If not, Fatal double error

SearchDir:

        popa

        mov ax, ds                                      ; Root dir is now in [Buffer]
        mov es, ax                                      ; Set DI to this info
        mov di, Buffer

        mov cx, word [RootDirEntries]           ; Search all (224) entries
        mov ax, 0                                       ; Searching at offset 0


NextRootEntry:

        xchg cx, dx                                     ; We use CX in the inner loop...

        mov si, KernelFname                     ; Start searching for kernel filename
        mov cx, 11
        rep cmpsb
        je FoundFileToLoad                              ; Pointer DI will be at offset 11

        add ax, 32                                      ; Bump searched entries by 1 (32 bytes per entry)

        mov di, Buffer                                  ; Point to next entry
        add di, ax

        xchg dx, cx                                     ; Get the original CX back
        loop NextRootEntry

        mov si, KernelMiss                              ; If kernel is not found, bail out
        call PrintString
        jmp Reboot

FoundFileToLoad:                                        ; Fetch Cluster and load FAT into RAM

        mov ax, word [es:di+0Fh]                ; Offset 11 + 15 = 26, contains 1st Cluster
        mov word [Cluster], ax

        mov ax, 1                                       ; Sector 1 = first sector of first FAT
        call l2hts

        mov di, Buffer                                  ; ES:BX points to our Buffer
        mov bx, di

        mov ah, 2                                       ; int 13h params: read (FAT) sectors
        mov al, 9                                               ; All 9 sectors of 1st FAT

        pusha                                           ; Prepare to enter loop


ReadFAT:

        popa                                                    ; In case registers are altered by int 13h
        pusha

        stc
        int 13h                                         ; Read sectors using the BIOS

        jnc ReadFAT_OK                          ; If read went OK, skip ahead
        call ResetDisk                                  ; Otherwise, reset disk controller and try again
        jnc ReadFAT                                     ; Floppy reset OK?

FatalDiskError:

        mov si, DiskError                               ; If not, print error message and Reboot
        call PrintString
        jmp Reboot                                      ; Fatal double error


ReadFAT_OK:

        popa

        mov ax, 2000h                                   ; Segment where we'll load the kernel
        mov es, ax
        mov bx, 0

        mov ah, 2                                       ; int 13h disk read params
        mov al, 1

        push ax                                         ; Save in case we (or int calls) lose it

                                                                ; Now we must load the FAT from the disk. Here's how we find out where it starts:
                                                                ; FAT Cluster 0 = media descriptor = 0F0h
                                                                ; FAT Cluster 1 = filler Cluster = 0FFh
                                                                ; Cluster start = ((Cluster number) - 2) * SectorsPerCluster + (start of user)
                                                                        ; = (Cluster number) + 31
LoadFileSector:

        mov ax, word [Cluster]                  ; Convert sector to logical
        add ax, 31

        call l2hts                                              ; Make appropriate params for int 13h

        mov ax, 2000h
        mov es, ax
        mov bx, word [Pointer]

        pop ax
        push ax

        stc
        int 13h

        jnc CalculateNextCluster

        call ResetDisk
        jmp LoadFileSector

CalculateNextCluster:

        mov ax, [Cluster]
        mov dx, 0
        mov bx, 3
        mul bx
        mov bx, 2
        div bx                                          ; DX = [Cluster] mod 2
        mov si, Buffer
        add si, ax                                      ; AX = word in FAT for the 12 bit entry
        mov ax, word [ds:si]

        or dx, dx                                               ; If DX = 0 [Cluster] is Even; if DX = 1 then it's Odd

        jz Even                                         ; If [Cluster] is Even, drop last 4 bits of word
                                                                ; with next Cluster; if Odd, drop first 4 bits
Odd:

        shr ax, 4                                               ; Shift out first 4 bits (they belong to another entry)
        jmp short NextClusterCont

Even:

        and ax, 0FFFh                                   ; Mask out final 4 bits

NextClusterCont:

        mov word [Cluster], ax                  ; Store Cluster

        cmp ax, 0FF8h                                   ; FF8h = End of file marker in FAT12
        jae End

        add word [Pointer], 512                 ; Increase Buffer Pointer 1 sector length
        jmp LoadFileSector

End:                                                            ; We've got the file to load!

        pop ax                                          ; Clean up the stack (AX was pushed earlier)
        mov dl, byte [BootDev]                  ; Provide kernel with boot device info

        jmp 2000h:0000h                         ; Jump to entry point of loaded kernel!

Reboot:

        mov ax, 0
        int 16h                                         ; Wait for keystroke
        mov ax, 0
        int 19h                                         ; Reboot the system

PrintString:

        pusha

        mov ah, 0Eh

.write:

        lodsb
        cmp al, 0
        je .done
        int 10h
        jmp short .write

.done:

        popa
        ret

ResetDisk:

        push ax
        push dx
        mov ax, 0
        mov dl, byte [BootDev]
        stc
        int 13h

        pop dx
        pop ax
        ret

l2hts:                                                  ; Calculate head, track and sector settings for int 13h
                                                                ; IN: logical sector in AX, OUT: correct registers for int 13h
        push bx
        push ax

        mov bx, ax                                      ; Save logical sector

        mov dx, 0                                       ; First the sector
        div word [SectorsPerTrack]
        add dl, 01h                                     ; Physical sectors start at 1
        mov cl, dl                                      ; Sectors belong in CL for int 13h
        mov ax, bx

        mov dx, 0                                       ; Now calculate the head
        div word [SectorsPerTrack]
        mov dx, 0
        div word [Sides]
        mov dh, dl                                      ; Head/side
        mov ch, al                                      ; Track

        pop ax
        pop bx

        mov dl, byte [BootDev]                  ; Set correct device

        ret

KernelFname db "SMA     BIN"

DiskError db "HDD error! Press any key.", 0
KernelMiss db "Kernel file SMA.BIN missing.", 0

BootDev db 0                                            ; Boot device number
Cluster dw 0                                            ; Cluster of the file we want to load
Pointer dw 0                                            ; Pointer into Buffer, for loading kernel

times 510-($-$$) db 0                           ; Pad remainder of boot sector with zeros
dw 0AA55h                                               ; Boot signature (DO NOT CHANGE!)

Buffer:                                                 ; Disk Buffer begins (8k after this, stack starts)

První nejde, druhé ano - kde je rozdíl? :)

 
Nahoru Odpovědět
18.6.2013 7:16
Avatar
Martin Dráb
Tvůrce
Avatar
Martin Dráb:18.6.2013 14:39

Podle mě načítáš data kernelu na 0x2000:0x0200, ne na 0x2000:0x0000, kam skáčeš.

Nahoru Odpovědět
18.6.2013 14:39
2 + 2 = 5 for extremely large values of 2
Avatar
Domiy
Neregistrovaný
Avatar
Odpovídá na Martin Dráb
Domiy:18.6.2013 15:23

Nic. Tedy obě verze způsobí vypsání písmene S do TTY, ale netuším, co si o tom mám myslet... :)

 
Nahoru Odpovědět
18.6.2013 15:23
Avatar
Domiy
Neregistrovaný
Avatar
Odpovídá na Martin Dráb
Domiy:18.6.2013 15:31

Kernel:

BITS 16

%define InterpreterBAS.Version '6.0'
%define APIVersion 16
                                                        ; This is the location in RAM for kernel disk operations, 24K
                                                        ; after the point where the kernel has loaded; it's 8K in size,
                                                        ; because external programs load after it at the 32K point:
DiskBuffer      equ     24576
                                                        ; The comments show exact locations of instructions in this section,
                                                        ; and are used in programs/smadev.inc so that an external program can
                                                        ; use a SMA-OP system call without having to know its exact position
                                                        ; in the kernel source code...
OsCallVectors:

        jmp Main

        jmp InterpreterBAS.Run                            ; 0003h
        jmp InterpreterBAS.Pause                                ; 0006h
        jmp InterpreterBAS.FatalError                      ; 0009h
        jmp System.ApiVersion                      ; 000Ch

        jmp Console.WaitForKey                    ; 000Fh
        jmp Console.WriteHline                    ; 0012h
        jmp Console.PrintRegs                      ; 0015h
        jmp Console.NewLine                          ; 0018h
        jmp Console.ReadLine                        ; 001Bh
        jmp Console.NibbleAL                        ; 001Eh
        jmp Console.ReadKey                          ; 0021h
        jmp Console.DigitAX                          ; 0024h
        jmp Console.PrintAL                          ; 0027h
        jmp Console.PrintAX                          ; 002Ah
        jmp Console.Space                              ; 002Dh
        jmp Console.Write                              ; 0030h
        jmp Console.Clear                              ; 0033h

        jmp Cursor.Location                          ; 0036h
        jmp Cursor.Move                          ; 0039h
        jmp Cursor.Show                          ; 003Ch
        jmp Cursor.Hide                          ; 003Fh

        jmp String.Join                          ; 0042h
        jmp String.Strip                                ; 0045h
        jmp String.Time                          ; 0048h
        jmp String.Date                          ; 004Bh
        jmp String.Parse                                ; 004Eh
        jmp String.Copy                          ; 0051h
        jmp String.Dump                          ; 0054h
        jmp String.Upper                                ; 0057h
        jmp String.Lower                                ; 005Ah
        jmp String.Length                              ; 005Dh
        jmp String.Chomp                                ; 0060h
        jmp String.Reverse                            ; 0063h
        jmp String.IndexOf                            ; 0066h
        jmp String.TimeFmt                            ; 0069h
        jmp String.DateFmt                            ; 006Ch
        jmp String.Truncate                          ; 006Fh
        jmp String.Tokenize                          ; 0072h
        jmp String.Compare                            ; 0075h
        jmp String.ReplaceChar                    ; 0078h
        jmp String.SubCompare                      ; 007Bh

        jmp Int.Parse                              ; 007Eh
        jmp Int.ToString                                ; 0081h
        jmp SInt.ToString                              ; 0084h
        jmp LInt.ToString                              ; 0087h

        jmp DialogBox.File                            ; 008Ah
        jmp DialogBox.List                            ; 008Dh
        jmp DialogBox.Plain                          ; 0090h
        jmp DialogBox.Input                          ; 0093h
        jmp DialogBox.DrawBlock                  ; 0096h

        jmp Math.Random                          ; 0099h
        jmp Math.BcdToInt                              ; 009Ch
        jmp Math.LIntNegate                          ; 009Fh

        jmp File.Size                              ; 00A2h
        jmp File.Load                              ; 00A5h
        jmp File.Save                              ; 00A8h
        jmp File.Exists                          ; 00ABh
        jmp File.Create                          ; 00AEh
        jmp File.Remove                          ; 00B1h
        jmp File.Rename                          ; 00B4h

        jmp Disk.FileList                              ; 00B7h

        jmp Port.SendByte                              ; 00BAh
        jmp Port.SpeakerOn                            ; 00BDh
        jmp Port.SpeakerOff                          ; 00C0h
        jmp Port.ReceiveByte                        ; 00C3h
        jmp Port.GetViaSerial                      ; 00C6h
        jmp Port.SendViaSerial                    ; 00C9h
        jmp Port.SerialPort.Enable                    ; 00CCh

        jmp Gshell.DrawBack                          ; 00CFh

Main:

        cli                                             ; Clear interrupts
        mov ax, 0
        mov ss, ax                              ; Set stack segment and pointer
        mov sp, 0FFFFh
        sti                                             ; Restore interrupts

        cld                                             ; The default direction for string operations will be 'up' - incrementing address in RAM

        mov ax, 2000h                           ; Set all segments to match where kernel is loaded
        mov ds, ax                              ; After this, we don't need to bother with
        mov es, ax                              ; segments ever again, as SMA-OP and its programs
        mov fs, ax                              ; live entirely in 64K
        mov gs, ax

        cmp dl, 0
        je .NoChange

        mov [bootdev], dl                       ; Save boot device number
        push es
        mov ah, 8                               ; Get drive parameters
        int 13h

        pop es
        and cx, 3Fh                             ; Maximum sector number
        mov [SecsPerTrack], cx          ; Sector numbers start at 1
        movzx dx, dh                            ; Maximum head number
        add dx, 1                                       ; Head numbers start at 0 - add 1 for total
        mov [Sides], dx

.NoChange:

        mov ax, 1003h                           ; Set text output with certain attributes
        mov bx, 0                               ; to be bright, and not blinking
        int 10h


        call Console.Clear
        call Iterp

Fmt1224 db 0                                    ; Non-zero = 24-hr format

FmtDate db 0, '/'                               ; 0, 1, 2 = M/D/Y, D/M/Y or Y/M/D
                                                        ; Bit 7 = use name for months
                                                        ; If bit 7 = 0, second byte = separator character
%include "features/Iterp.asm"
%include "features/System.asm"
%include "features/InterpreterBAS.asm"
%include "features/Gshell.asm"
%include "features/Console.asm"
%include "features/Cursor.asm"
%include "features/DialogBox.asm"
%include "features/Disk.asm"
%include "features/File.asm"
%include "features/Int.asm"
%include "features/Math.asm"
%include "features/Port.asm"
%include "features/String.asm"
 
Nahoru Odpovědět
18.6.2013 15:31
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 26 zpráv z 76.