Aktív témák
-
''Most egy TSS-t szeretnék létrehozni, ami nem a 0-ás privilégium szinten futna.''
Ezt nem értem...:)
A TSS ahhoz kell, hogy mindenféle járulékos információt a taszkkal kapcsolatban tárolni tudjon a proci (Task State Segment). Itt tárolódik például az összes stack címe, vagy taszkváltáskor a regiszterek tartalma, de az I/O permission bitmap is (a V86 módnak). Tehát, ha akarsz 0-ás priv. szinten kívül más szintet, akkor kell egy TSS. A szükséges priv. szint stack mutatóit be kell állítani benne, majd a deszkriptor táblában létre kell hozni egy TSS bejegyzést, és ezt a címet (mint akár egy szegmens címét) be kell tölteni, csak nem egy szegmens regiszterbe, hanem a Task Register-be (pl. mov ax,TSS_SEG ltr ax). Ha nincs szükség az I/O permission bitmap-re, akkor állítsd a kezdetét a TSS határán túlra.
A C-s dologhoz sajnos nem tudok semmit tanácsolni, én csak full assemblyben csináltam mindent. Ezt a GRUB-os dolgot említették sokan, biztos jó. :DD -
''Létezik egyáltalán olyan debugger, amit lehetne használni?''
A probléma ott van, hogy védett módba csak valós módból lehet átkapcsolni, így csak olyan debuggert használhatsz, ami valós módú. De mivel átkapcsolsz, a szegmens regiszterek új értelmet nyernek, azokhoz kellene a megfelelő GDT stb. Ráadásul az interruptokat is engedélyezi (hiába volt cli, az csak virtuálisan, a programod szempontjából érvényes). A turbo debugger meg amúgy is elég béna (kicsi, valós módú programokhoz jó).
Én úgy csináltam, hogy stack-re mentettem az engem érdeklő regiszetereket, majd vissza valós módba, ott pedig szépen, kényelmesen kibányásztam a védett módú stack helyéről a számokat.
Az IDT az egy nagy tömb, felépítését tekintve olyan, mint a GDT. Ugyanúgy kell beállítani, mint a GDT-t (lidt). A bejegyzések szintén 8 byte-osak. Egy bejegyzés így néz ki:
dw offszet also 16 bitje
dw szelektor
db 0 ; ez igazabol csak 5 bites, ez azt mondja meg, hogy call gate eseten hany dwordot (wordot) kell a ket kulonbozo szint verme kozott masolni (mert minden szintnek sajat verme van)
db 0 ; a tipust es a priv. szintet adja meg, ugyanugy mint egy deszkriptornal. A tipus ertekei a kovetkezok lehetnek:
; 4 286 call gate
; 5 386 task gate
; 6 286 interrupt gate
; 7 286 trap gate
; 12 386 call gate
; 14 386 int gate
; 15 386 trap gate
dw 0 ; offszet felso 16 bitje
Szóval, baromira hasonló, de itt nem bázis és határ van, hanem szelektor és offszet. Ez a címe a kiszolgáló rutinnak, ide ugrik, a valós módban csak szelektor és offszet van pl. A típust állítsd interrupt gate-re (14)!
A kivételek listája:
0 osztás hiba
1 debug trap
2 NMI
3 int3 utasítás
4 into utasítás
5 bound hiba
6 érvénytelen utasítás
7 device not available (taszkváltásnál kell, vagy koprocesszor emulációnál)
8 double fault (hiba amikor éppen hibát szolgálsz ki)
10 érvénytelen TSS
11 szegmens nem aktív (a P bitje 0)
12 stack hiba
13 általános hiba (ez kell nagyon :DD)
14 lapozási hiba
16 FPU hiba
Meg még van egy pár, de ezek a legfontosabbak. A 9-es és 15-ös nem maradt ki, az nincs. A legegyszerűbb, ha csinálsz egy 32 elemű IDT-t, az lefedi az összes (akár jövőbeni) kivételt. Ahogy ajánlottam feljebb, az összes rutin csak annyi, hogy beteszed a számát a kivételnek a verembe, majd ugrasz a közös rutinra. Érdemes a verembe piszmogni, mert amikor a kiszolgálóra jut a vezérlés, akkor csak az ''áll készen'', hiszen a szegmens regiszterek ismeretlen értéket tartalmaznak (és a CS nem írható). Vagy benyomatod a verembe a DS-t, majd szabad a pálya. Mindenképpen 0-ás priv. szint kell a kiszolgáláshoz (természetesen a cél CS-nek is 0-ás szintűnek kell lennie)! Persze az int3, into lehet alacsonyabb szinten, ott azt jelenti, hogy melyik a legalacsonyabb szint, ahol végrehajtható az utasítás.
Van még egy lényeges dolog. Lehet, hogy tudsz róla, lehet, hogy nem. Amikor átváltasz másik módba, akkor a szegmensek megőrzik a régi tartalmukat. De itt ne csak a számra gondolj, amit betöltöttél, hanem azokra az értékekre, amit a deszkriptorban állítani tudsz (valós módban is ugyanúgy működik a határ ellenőrzés pl.). Hogy ez ne okozzon gondot, átváltás után szükség van egy szegmensközi ugrásra (far jmp pl.). Ha vissza is akarsz váltani, akkor szükséged lesz egy olyan deszkriptorra, ami egy valós módú szegmenst ír le. 64k-s határral, 16 bites móddal, 0-ás priv. szinttel. Lehet, hogy a fajtáját is be kell állítani, már nem emlékszem, hogy én hogyan csináltam.
Kiváncsian várom a fejleményeket! -
''Na a nasm-ban a ''jmp dword cs:ip'' 32bit-es és ''jmp word cs:ip'' 16bit-es far ugrás.
Megnéztem az exe-t hexa editorral és úgy néz ki, hogy a nasm jól fordítja le ezeket az utasításokat. Te próbáltad már a nasm-ot? Mert ha mégsem fordítja jól, akkor az álltalad írt gépikód formát fogom használni. Meg gondolom bizonyos esetekben kell a 66h prefix, amikor a szegmens 16bit-es az utasítás meg 32bit-es.''
Még nem nasm-oztam, mert mindent meg tudtam oldani tasm alatt, és át kellett volna szoknom. Egyszer olvastam végig a doksiját, és nem sokra emlékszem...
Na, megnéztem amit küldtél, de szerintem semmi probléma. Hogyan futtatod? Ugye nem debuggerben? Mivel nem használod a GDT-t (mert nincs szegmens betöltés), ezért azzal még nem kell foglalkozni. Van valami memory manager (qemm, emm386 stb.) bent a memóriában? És honnan tudod, hogy pontosan hol szállt el? Valami emulátorból próbálkozol?
[Szerkesztve] -
OddMan
őstag
Huh most esett le a hogyan kell fizikai címet csinálni kérdésem.
mov eax, ds
shl eax, 4 ;ezt nem értem, hogyha 4-el balra léptetem a biteket, akkor mitől lesz az a fizikai címe a DS-nek?
Tehát azért, mert a DS csak 16bit-es és mindig utána kell képzelni még 4db 0-ás bitet. Így ha balra léptetem 4-el, akkor az eax-be már a 20 bites fizikai cím lesz. Aztán azt meg csak hozzá kell adni a GDT_addr relatív címéhez és így már tényleg a GDT_addr változóban az igazi fizikai cím szerepel, ugye? :DD -
OddMan
őstag
Még van egy-két kérdésem, ezeket ti már biztosan tudjátok.
Elkezdtem tanulmányozni a védett módot. Sajnos a megszakítások és kivételek kezelése rész eléggé homályos számomra. Kivételkezelés valós módban nem volt. Nos akkor amit nem tudok, hogy mi az a minimum 16 kivétel amit az IDT-be fell kell vennem? Tudtok valami doksit, ahol van erről leírás? A köv. kérdésem, hogy, védett módban az int xxh parancsot már nem lehet használni ugye? Tehát a bios-t el lehet felejteni?
A GDT-vel kapcsolatban még annyit szeretnék kérdezni, hogy idézet:
''szóval ezek a táblák nyugodtan lehetnek data sorokban, csak a bázisukat kell számítani, kivéve, ha mindig ugyanoda rakod).''
Hogyan kell a bázist számolni és miért kell? Ez még valós módban történik ugye?
Érdekelne a sorrend is, hogyan kezdjek egy védett modú asm progit:
-Na először is én ellenőrzöm a proc típusát.
-Utána a GDT fizikai címmé alakítása aztán a GDT beállítása az lgdt src paranccsal. A GDT struktúráját is elkészítettem.
-A CR0 PE bitjének 1-be állításával védett módba kapcsolok.
-A szegmens regiszterekbe betöltöm a kívánt szelektorokat.
Ha egyenlőre nem akarok taszkokat és egyéb nyalánkságot, akkor érdemes egy 4GB-os code és egy data szegmens deszkriptor-t használni?
Talán egyelőre ennyi. :DD
Előre is nagyon köszi a segítséget! :U
Ha valaki tud olyan helyet, ahol még lehet kapni a Dr. Kovács Magda 80386 I. és 80386/80486 II. című könyvét, az legyen szíves írja ide a bolt címét. :F -
-
Floppynál nincs MBR, az csak HDD-n van. Az MBR-ben a partíciók leírásai, és a boot szektor betöltője van. Igazából mindegy, mert fogja, betölti az első szektort, majd futtatja. Semmi másra nincs szükség, a FAT az a DOS része. Oda rakod a kerneled, ahová jólesik, neked kell betöltened a boot szektorbeli kóddal.
Azért nem látja a lemez tartalmát, mert számára ismeretlen a formátum.
Megszokásból csak a második sávon kezdik az adatokat, az első sávon csak a boot szektor van (HDD esetén MBR). -
OddMan
őstag
Közben rájöttem, hogy miért nem látom a floppy tartalmát.
000h 446 Machine Code and Associated Data.
1BEh 16 Partition 1 Information. //ezek a byte-ok nálam végig nullák. Ez volt a baj szerintem.
1CEh 16 Partition 2 Information.
1DEh 16 Partition 3 Information.
1EEh 16 Partition 4 Information.
1FEh 2 Boot Signature AA55h.
Szal az első 446 byte a boot code és a következő 4x16 byte pedig a particíós táblák elhelyezkedése mérete és a boot flag állapota van itt tárolva.
Aztán jön a lezáró AA55h .
Láttam egy kódot a nasm-hoz a neten, de valamit nem értek benne.
iderakom:
; 3.ASM
; Load a program off the disk and jump to it
; Tell the compiler that this is offset 0.
; It isn't offset 0, but it will be after the jump.
[ORG 0]
jmp 07C0h:start ; Goto segment 07C0 ;Ezt az első ugrást nem értem. ha elugrik a 07C00h:start címre, akkor ott nincsen semmi. A következő code sorok már nem tudnak lefutni, mivel azok a 00000:0000 címre lettek betöltve vagy nem? Szal szerintem ez így nem múködik. Valki segítsen!
start:
.|. the segment registers
mov ax, cs
mov ds, ax
mov es, ax
reset: ; Reset the floppy drive
mov ax, 0 ;
mov dl, 0 ; Drive=0 (=A)
int 16h ;
jc reset ; ERROR => reset again
read:
mov ax, 1000h ; ES:BX = 1000:0000
mov es, ax ;
mov bx, 0 ;
mov ah, 2 ; Load disk data to ES:BX
mov al, 5 ; Load 5 sectors
mov ch, 0 ; Cylinder=0
mov cl, 2 ; Sector=2
mov dh, 0 ; Head=0
mov dl, 0 ; Drive=0
int 13h ; Read!
jc read ; ERROR => Try again
jmp 1000h:0000 ; Jump to the program
times 510-($-$$) db 0
dw 0AA55h
Aktív témák
- Apple iPhone 13 Pro Max /128GB / Kártyafüggetlen / 12Hó Garancia / Akku:83%
- 5G Lenovo ThinkPad P14s Gen 3 Intel Core i7-1280P Nvidia T550 32GB 1000GB 1 év teljeskörű garancia
- Lenovo L14 Ryzen 5 4500U Refurbished - Garancia!
- LENOVO GAMER BAZÁR - új lista (2026.03.14) - Legion Pro 7 (16IAX10H) RTX 5080
- Apple iPad Pro 13 M4 256GB Wi-Fi használt, szép állapot 98% akku (113 ciklus)
Állásajánlatok
Cég: Laptopműhely Bt.
Város: Budapest
