Diskuze: SMA-OP

Assembler SMA-OP

Avatar
matesax
Redaktor
Avatar
matesax:

[Esemej oupi:]
SymbolicMatějAndrle-Operative

Je operační systém napsaný v JSA => původní záměr byl nazvat jej JSMA - což mi nepřišlo originální a navíc kamarád navrhl shodou okolností totéž - SMA. OP? => operative - operativní režim jako střed mezi realtime a protected.

Aktuální stav:

Monolitické jednoúhlové jádro pracující v realtime režimu
VFAT => prozatím užívám FAT - přecházím k FAT32 + žurnálování
DOS UI - CLI + minimální grafika
BIOS interupt systém:
mnoho obrazovek => na jedné však může běžet jen jeden program - proto píši jednoúhlové jádro (přeskakování bude fuška :) )...
256 barev => zatím nevyužito - ne v kernelu
klávesnice
myš => zatím nevyužita - nikde
RW (Read-Write) přístup
a další...

Plány:

Monolitické víceúhlové operativní jádro (Práce ve vyšších instrukcích schopných kdykoliv sáhnout hluboko jako realtime - proto operativní. Dosáhnu toho vytvořením objektového JSA Frameworku - ony instrukce budou nadstavbou JSA - nikoliv přepis do vyššího jazyka.)
DSP - vlastní FileSystem - na bázi žurnálovacího - s obrovským objemem přenosu dat
BIOS interupt systém + všechna zařízení
Vlastní pojetí UI - ani okna, ani CLI
a další...

Hlavní cíl - vytvořit něco nového, soběstačného, držícího se jen toho svého. Smysl tohoto postu? Sepsat toto všechno a v průběhu času sledovat jak se to má...

Jak dlouho?
2 roky pracuji absolutně nepravidelně - s velkými přestávkami, již delší dobu však píši plně aktivně a hodlám to dodělat. První verzi - betaverzi plánuji vydat za 2 - 3 roky. Již teď však lze OS používat - jen je to spíš rozbitá verze DOSu... :)

Zdrojové kódy? Rozhodne OpenSource - ale až po vydání licence. Nějak komerčně to přecijen pojmout musím - neboď 5 let práce je dlouhá doba. :) Příklad tvorby - BootSector:

BITS 16

jmp short Boot
nop                                                     ; Pad out before disk description
                                                        ; Disk description table, to make it a valid disk
                                                        ; Note: some of these values are hard-coded in the source!
                                                        ; Values are those used by IBM for 1.44 MB, 3.5" diskette

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                                   ; Set Buffer past what we've already read
        mov es, ax
        mov bx, word [Pointer]

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

        stc
        int 13h

        jnc CalculateNextCluster                        ; If there's no error...

        call ResetDisk                                  ; Otherwise, reset disk and retry
        jmp LoadFileSector
                                                        ; In the FAT, Cluster values are stored in 12 bits, so we have to
                                                        ; do a bit of maths to work out whether we're dealing with a byte
                                                        ; and 4 bits of the next byte -- or the last 4 bits of one byte
                                                        ; and then the subsequent byte!
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:                                            ; Output string in SI to screen

        pusha

        mov ah, 0Eh                                     ; int 10h teletype function

.repeat:

        lodsb                                           ; Get char from string
        cmp al, 0
        je .done                                        ; If char is zero, End of string
        int 10h                                         ; Otherwise, print it
        jmp short .repeat

.done:

        popa
        ret

ResetDisk:                                              ; IN: [BootDev] = boot device; OUT: carry set on error

        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)

JSA a přenositelnost?
Nemohu souhlasit s tím, že JSA je vyloženě nepřenositelný - ovšem multiplatformní také ne. Optimismu se držím už jen proto, že čerpám z Intel Pentium manuálu a nejen, že to běželo na x86 AMD, ale i na x64... :) Ovšem pro jiné názvy instrukcí dělám zrovna konvertor a pro vyloženě odlišné pojetí udělám více verzí - kterých když bude více, stanou se součástí instalačního procesu - uživatel nebude potřebovat cokoliv řešit.

Závěr?
Stačí obyčejný textový editor, trochu logiky, nějaký ten Assembler a světe div se - ono to funguje... :)

Editováno 23.4.2013 13:08
 
Odpovědět 23.4.2013 13:03
Avatar
matesax
Redaktor
Avatar
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na matesax
David Čápka:

Pokud to chceš pojmout komerčně, neměl bys stavět na volně dostupných zdrojových kódech, alespoň ten tvůj zavaděč jsem našel na Googlu. U operačních systémů se naskýtá otázka k čemu je to dobré, když tu již jsou. Větší smysl má upravit existující Linux.

Nahoru Odpovědět  +2 23.4.2013 13:38
Miluji svou práci a zdejší komunitu, baví mě se rozvíjet, děkuji každému členovi za to, že zde působí.
Avatar
matesax
Redaktor
Avatar
Odpovídá na David Čápka
matesax:

Zavaděč samozřejmě najdeš všude - je to zavaděč, jinak napsat nejde... :) musíš definovat stejné proměnné atd. Načítání kernelu a FATu by možná šlo i jinak - ale toto vůbec neřeším - FAT používat nebudu. (Ale chvíli potrvá, než napíši ten svůj FS.) Proč myslíš, že když si vývoj střežím, že jsem vydal tento kód... OpenSource a komerčnost moc dohromady nejde:

Zdrojové kódy? Rozhodne OpenSource - ale až po vydání licence. Nějak komerčně to přecijen pojmout musím

Peníze za to sice chci - ale jinou cestou - například reklamy, sponzorství atd...

Smysl? Pročti si to... Nechci vycházet v ničem z již exitujících řešení - OS je hodně a to i mě odrazovalo, ale přesto věřím, že bude zatraceně inovativní...

Editováno 23.4.2013 13:47
 
Nahoru Odpovědět 23.4.2013 13:44
Avatar
matesax
Redaktor
Avatar
matesax:

Vygoogli mi:

OsPrintString:

        pusha

        mov ah, 0Eh                                     ; int 10h teletype function
        mov byte [line], 0

.loadWord:

        push si
        jmp .chaining

.summary:

        pop si

        cmp [line], cl
        jg .newLine

        jmp .writeWord

.chaining:

        lodsb

        cmp al, 0
        je .summary

        cmp al, 92
        je .chanTestEsc

        cmp al, 32
        je .summary

        inc byte [line]
        jmp .chaining

.chanTestEsc:

        lodsb
        cmp al, 36
        je .pop

        inc byte [line]

        cmp al, 92
        je .chanTestEsc

        inc byte [line]
        jmp .chaining

.pop:

        pop si

.writeWord:

        lodsb                                           ; Get char from string
        cmp al, 0
        je .done                                                ; If char is zero, end of string

        cmp al, 92                                      ; Is escape letter?
        je .testEsc

        int 10h                                         ; Otherwise, print it

        cmp cl, 0
        je .writeWord

        cmp al, 32
        je .loadWord

        jmp .writeWord

.testEsc:

        lodsb
        cmp al, 36
        je .forced

        mov bl, al
        mov al, 92
        int 10h
        mov al, bl

        cmp al, 92
        je .testEsc

        int 10h
        jmp .writeWord

.forced:

        inc dh
        mov byte [line], 0
        call OsMoveCursor

        jmp .loadWord

.newLine:

        inc dh
        mov byte [line], 0
        call OsMoveCursor

        jmp .writeWord

.done:

        popa
        ret

line db 0

Krom serveru http://programujte.com/forum , kde jsem se ptal, proč mi to nejde, nenajdeš jinou shodu... (Když už to bylo zveřejněno, nač to schovávat... :) )

Editováno 23.4.2013 13:58
 
Nahoru Odpovědět 23.4.2013 13:57
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na matesax
David Čápka:

No dobře. Jen stále nevím, v čem to bude inovativní. S trochu štěstí se ti povede vytvořit druhý DOS.

Nahoru Odpovědět 23.4.2013 14:36
Miluji svou práci a zdejší komunitu, baví mě se rozvíjet, děkuji každému členovi za to, že zde působí.
Avatar
matesax
Redaktor
Avatar
Odpovídá na David Čápka
matesax:

Ale ten už dávno mám... (Instalačku pro Windows bez nějakého Windows uživatele dost dobře udělat nemohu, ale hotové ISO by snad přenášet šlo (mezi AMD a některými Intel) - takže klidně mohu poslat.) Jak jsem psal - vlastní jádro, vlastní FS, UI atd... Celé fungování jsem propracoval tak, že by trvalo dloho, než bych to vysvětlil - ale výsledkem bude maximální rychlost a práce s dynamickou pamětí - místo OS založeném na nějakém statickém bodu, SMA-OP je vlastě jakousi nadstavbou BIOSU (tuto přímou vazbu však nikdy neztratí - to je ta myšlenka operativního přístupu) - kdy vlastně nemůže nikdy spadnout - jelikož neexistuje něco jako hlavní proud... (Jako třeba hlavní smyčka.)

Když si to vezmeš, tak nemá smysl dělat cokoliv... Nač se vrtat v Linuxu? Když jsem se navíc dovrtal úplně všude... (A to ne v Linuxu, a už prakticky ani v Unixu - ale snad ve všem co se dalo zprovoznit na mém PC.) Je snad lepší přepisovat cizí práci? Která navíc absolutně neodpovídá mé představě... To už raději vezmu čistý list a mám vše takové, jaké jsem si kdysi vysnil... (Udělal jsem vždy to co pro mne dříve nebylo reálné...) Celý PC svět se neustále mění - OS je mnoho - ale jde přeci o to, co nabízí, kde se dají spustit atd... Podobný dotaz padá ve školách - "A proč se toto máme učit?" Důvod není - a je nesmyslné nějaký hledat - žádný není... Můžu se učit programovat na čemkoliv a v čemkoliv - co z toho ale budu mít? Atd...

Jedno je jisté - nikdy to nebude k ničemu - 80% práce budu moci aplikovat naprosto k čemukoliv... A navíc onen JSA Framework (z části něco jako vyšší programování v JSA) plánuji postavit tak, aby byl schopen zmapovat sadu instrukcí. Což už je jen krůček k vlastnímu jazyku... (Jeden již mám - ale ten chci dotáhnout na virtuální stroj - a ne držet se mého operative modelu.)

 
Nahoru Odpovědět 23.4.2013 15:10
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 7 zpráv z 7.