mcp@ziebmef.uucp (Marc Plumb) (12/28/88)
I'm trying to reverse-engineer the disk validator, and encoutering a few snags. Could someone help me out? What I'd really like to do is put breakpoints in the ROMs and work through things that way, but I haven't yet found the magic flag that write-enables the WCS. The only likely sounding thing, the "memory overlay bit" on PA0 of 8250 A, crashes the machine. Obviously not what I want. Against the day whan I find out (I could use help there, too), does SDB mind encountering breakpoints in a foreign process? I suspect it would get upset if it hit one while the program it was debugging was stopped, but if I put my test program into an infinite Wait(), would things work, or does it mess around with the task structure? The features to debug device drivers suggest that something's possible, but the docs don't go into any detail. Also, in the interim, my attempts involving patching the rn_RestartSeg vector to go through a jump to the real code I set up in RAM cause machine crashes. Can someone tell me what I'm doing wrong? Current procedure: OpenLibrary("dos.library", 0L) and find the root node. Look at the rn_RestartSeg vector. It holds 0x3ffc6c, a BPTR to 0xfff1b0, a reasonable place in the ROMS. Disassembling this location reveals: 00fff1b0: 0000 0000 ori.b #0,d0 00fff1b4: 0000 038d ori.b #-73,d0 00fff1b8: 2401 move.l d1,d2 (more reasonable-looking code) The first word looks like the NULL pointer to the next segment in the SegList, the second, I don't know (by the docs I've seen, it should get executed, but although it's harmless, it sure looks like a count or something), and the rest is code involving a lot of shifts and (a0,dn) addressing modes. BCPL compiler, anyone? (1.3 kickstart, BTW.) So I try to patch in my own code. I declare a static array (char code[20]), round up to the nearest longword, stuff the current contents of rn_RestartSeg into the first word, two nops after that (since I'm not sure where the executable code starts in a segment), and then an absolute jump to 0xfff1b4 (I've also tried with 0xfff1b8). I patch rn_RestartSeg to hold a bptr to my fake segment, and, while I can unpatch it again safely, if I insert a floppy (removal is okay) while this patch is in place, boom! Guru time. For the technically oriented, I patched rn->RestartSeg to hold 0x7f2d, 0x1fcb4 in the APTR world, and at that address is found: 0001fcb4: 003f fc6c ori.b $6c,usp 0001fcb8: 4e71 nop 0001fcba: 4e71 nop 0001fcbc: 4ef9 00ff f1b4 fmp fff1b4 I can't see what's wrong with this. I haven't tried inserting a breakpoint yet; I wanted to get this obviously trivial thing working first. So... suggestions? My eventual aim is to have my format of floppy auto- recognised when a floppy is stuck in the drive, which I decided was best achieved by patching in my rn_RestartSeg disk validator, which would read the boot block, check the DOS type, and possibly punt to the old one, but might do what the current disk vallidator does (whatever that is), but using a different handler. In furtherance of this, I'm trying to reverse-engineer the disk validator. Any help at any stage of this descent to detail would be appreciated. -- -Colin (utai.toronto.edu!ncrcan!ziebmef!mcp for now)
steveb@cbmvax.UUCP (Steve Beats) (12/30/88)
In article <1988Dec27.223345.29513@ziebmef.uucp> mcp@ziebmef.UUCP (Colin Plumb) writes: >I'm trying to reverse-engineer the disk validator, and encoutering a few >snags. Could someone help me out? >[stuff deleted] >Also, in the interim, my attempts involving patching the rn_RestartSeg >vector to go through a jump to the real code I set up in RAM cause >machine crashes. Can someone tell me what I'm doing wrong? > Yes, you're playing around in system structures and using private fields that are not guaranteed to remain the same for all Kickstart releases. You can consider this a polite slap on the wrist if you like :-) Really though, what you are attempting to do is completely unsupported, the only way to take over a small part of the filing system is to write the big part too and mount that on the appropriate device. >So... suggestions? My eventual aim is to have my format of floppy auto- >recognised when a floppy is stuck in the drive, which I decided was >best achieved by patching in my rn_RestartSeg disk validator, which >would read the boot block, check the DOS type, and possibly punt to >the old one, but might do what the current disk vallidator does >(whatever that is), but using a different handler. > 'fraid you have hit a pretty glaring hole in the current AmigaDOS filing system environment. Right now, the filing system is mounted on a device and remains there for all time. The mounted filing system decides if it can grok the inserted disk, if it can't, it just says "not a DOS disk" and gives up. There is no facility for "passing-on" a disk to an alternate filing system. Unfortunately, this is what you need. Once again, the solution is to mount your own filing system on the trackdisk unit and do everything yourself. To handle the case of the ROM filing system you could send an inhibit packet to it when your task starts up; this will prevent it from snooping the disk before you do. If a disk is inserted that you don't recognise, simply send an uninhibit to the ROM filing system and it will then log and check the disk instead. Of course, you mustn't touch the disk once this has been done. There will also be complications when the oldfs disk is removed and one of your disks is inserted. Really, this kind of trickery just ain't supported. >In furtherance of this, I'm trying to reverse-engineer the disk validator. >Any help at any stage of this descent to detail would be appreciated. > OK, that bit is easy, the disk-validator/restart code does the following when a disk is inserted or the volume is uninhibited (by format for example). 1. Read the boot block, if !DOS0 then "not a DOS disk" 2. Read the root block and make sure the checksum is OK. Check various fields in the root block for consistency. These include the hashtable size and the size of the volume name. Parent key and a couple of others are checked to make sure they are 0. If any of these tests fail then "not a DOS disk" 3. Check the bitmap-valid flag in the root block. If it's 0 then the validator will be called. Under the old filing system, this involves loading it off *SOME* disk and creating a separate process. Under FFS the validator runs on the same task as the main filing system code but as a separate co-routine (or thread or lightweight process, whatever :-) The validator code is an integral part of FFS, not loaded separately. The main task of the validator is to check the files on the disk and report any corrupted headers or duplicate keys etc. If no uncorrectable problems are found, then the bitmap is rebuilt and written to the disk (if there is room). If there's no room on the disk (which can be the case with floppies) then just the memory copy of the bitmap will be used and the disk will get validated every time it is inserted. I won't go into the details of how the bitmap is built since this isn't really pertinent to what you were asking about. Hope this helps though. Steve
page@swan.ulowell.edu (Bob Page) (12/30/88)
mcp@ziebmef.UUCP (Colin Plumb) wrote: >I'm trying to reverse-engineer the disk validator, and encoutering a few >What I'd really like to do is put breakpoints in the ROMs and work through How about using the validator in L: ? >I haven't yet found the magic flag that write-enables the WCS. My dim view of Amiga hardware says you won't find such a magic flag. Here's something Kim posted around September 86. Might be useful. ..Bob vvvvvvvvvvvvvvvvvvvvvvvvvv from Steve Schoettler vvvvvvvvvvvvvvvvvvvvvvvvvvvvv Making Kickstart RAM writable. If you've ever wanted to modify kickstart routines, here's the information you've been waiting for. If you use metascope and would like to trace your program as it calls some kernel routine or set breakpoints in the libraries, the following information should be very useful. How many times have you called OpenWindow() and bombed but didn't quite know why? Even with this modification, when you're not interested in writing to kickstart, you can switch the capability off and it's write protected just like a normal Amiga! Of course, this leaves the ram open to crazy programs, but that simply means that if a program goes wild and happens to write to a critical area you have to turn off the machine to reboot kickstart, rather than just inserting workbench. To me, the ability to debug is worth it. Besides I can easily return to write protection. First, a few words about how the kickstart sequence works: When you turn on your Amiga the bootup ROM reads the Kickstart disk into the Kickstart RAM at $fc0000. Then the 68000 does a read to the location $f80000. (Actually, anything with Address bits 19-23 high and A18 low would do). This condition is detected by a PAL called DAUGCAS, which write protects the kickstart ram. There are three methods you could use to disable the write protect: (1) Install a switch to force the write protect signal (WPRO*) inactive. This is the method I used, and is really simple because C-A graciously left two holes in the circuit board for the wires to my switch. It could probably be removed (in case you had to take it in for servicing at a later time) without leaving any traces. Well, actually you would have to drill a hole in the back panel to mount the switch. (2) Replace the PAL with one that had a different equation for the WPRO*. This has the glamor of not needing any solder. The equation could be set up to never write protect the RAM, but that's probably not such a good idea. A better method would be to make the RAM toggle the WPRO* signal with every read to $f80000. A simple C or Basic program could be written to read this location. Just so you know what state it's in (WPRO* or not), you could read location $ffffff, write something else to it, and read it back again. If it's the same, it's write protected, otherwise it's not so put the old value back. (By the way, the location you choose should not be any code another task might be executing. Maybe you could overwrite the copyright notice. To be safe, a forbid() and permit() would probably be a good idea.) (3) Remove the instruction that reads location $f80000 in the first place. This is in the Boot Rom, so you'd have to change that. I don't like that solution because it's permanent. If you like the PAL method (2), you're on your own for now. I have figured out how to make the new PAL, but I can't post the equations and I can't distribute the chips without violating C-A's copyrights. I have gotten a preliminary OK from Commodore to distribute the PALs, and as soon as I get a written OK, I'll let you know about it. They should cost less than $10. Following is a description of how to install a WPRO* switch (method (1), above): ********** But first, a disclaimer ******************************* **** **** 1. I can't be responsible for anything you do to your Amiga. **** I believe I've explained this thoroughly enough so someone **** with soldering experience and a reasonable mechanical **** intuition can do it without much difficulty, but you **** are taking your computer into your own hands. **** **** 2. Commodore may have or may in the future change the layout **** of the circuit board or change the PAL's, making these **** instructions obsolete. If your board doesn't look like **** what I'm describing, DON'T DO ANYTHING. **** **** 3. This will void your warranty. **** **** 4. I represent no company or organization in any way whatsoever. **** ******************************************************************** UNPLUG YOUR AMIGA!!!! It will be very easy to strike a metal object (soldering iron, solder, resistor, wire, watch, etc) across two consecutive traces and who knows what might happen. First, you need to take off the cover of your Amiga and take off the metal shield that covers the circuit boards (yes, all 19 screws and 2 twist tabs). So we agree on orientation, the front of the Amiga is towards you, the power supply is on the left, and the parallel port is on the upper right side. I will refer to the rear of the Amiga as the "top." There is a main mother board, and an L-shaped "daughter board" which is upside down, above the main board. The PAL is located on the daughter board at location J-6. It's on one of the inside corners, next to the letter "J" and it says "DAUGCAS" alongside it. This is a 20 pin chip. There should be a white outline of the chip between the pins with a notch at one end. From the notch, count pins clockwise until you get to pin #13, which is the third one from the upper right corner of the chip. Pin 13 is the WPRO* signal. Originally, the WPRO* signal went through a resistor and LED to +5V. Since WPRO* is active low, the LED would go on during bootup while the ram was being written, and then go off at about the time it told you to insert the Workbench, and remain off until you turned the machine off. Well, it's silly to have an LED inside a closed box, so C-A decided to save costs and not insert the resistor and LED, but the circuit board should still be the same. I don't know on how many boards the LED was inserted, or on how many boards the LED socket will still be around, so inserting the wire to the switch may be a slightly different procedure for some of you. If you follow the trace from pin 13 of DAUGCAS it will go to one of the resistor terminals. Insert the stripped end of a wire into this hole at the left end of the resistor. (Just heat the hole with your soldering iron and push the wire through). As a precaution, before working on the board, put a piece of paper under where you'll be soldering so solder splats don't hit the board below. I didn't get anything on my paper, but it's good prevention. Above the resistor space is a white box marked "1" with 2 solder holes. Insert the stripped end of another wire in the left-most of these two holes inside the box. You now have the two wires necessary to run to your switch: one is connected to WPRO* and the other to +5V. With the switch "on" you will pull WPRO* hi (inactive) and make the ram writable. A note about mounting of the switch. I suppose you will want to mount this in the back panel. This panel is removable, so it's easy to put it flat on a table and drill a new hole. Before you remove the back panel and drill the hole, however, put the metal shield back on (screws not necessary) and hold your switch in the location you wanted. If it's like most switches, it probably won't fit next to the metal shield UNLESS it's as far right as possible (over the keyboard jack). Now, go drill the hole. When cutting the wires, leave a few inches of slack so they can fit through the crack in the metal shield in the upper right corner. (convenient, huh?) Now put it back together and you have switchably writable kickstart! A note about operation: ======================= For normal operation, leave the switch "off" when you power up. This will look and act exactly like a normal Amiga. To enable writing the ram, turn the switch "on". If, after you have been writing the ram, you decide to write protect it, the switch alone won't do it - TURNING THE SWITCH BACK OFF STILL LEAVES THE RAM WRITABLE. You need to either do a read to location $f80000 or turn the machine off and on again. If you want the facility to turn off WPRO* with a switch, you can use a 3 pole switch with WPRO* in the middle terminal and +5V on one side and GND on the other, but there isn't a convenient hole for GND so you'd have to find one on the board. This would have an immediate reaction with any direction of the switch. Technicalities: =============== All of the above works, but if you want to know a little more about how, read on. The WPRO* signal is actually both an output and input of the DAUGCAS PAL. The logic used to generate it has what we call a "set" term and a "reset" term. It acts like a S/R flip-flop. The "set" term makes WPRO* active when the processor does a read cycle from an address whose bits 19-23 are high and bit 18 is low. The "reset" term comes from the hardware reset line that is active when the machine powers on. Once WPRO* is set, it won't be reset until power on again, and once it's reset it won't be set until that read instruction. WPRO* is both an output and an input of the PAL. The output is generated from the above equation, and the input is used to disable a write signal from ever getting to the RAM. The very astute of you might criticize the forcing high of a low output. Well, the only time the output is forced is during the read cycle (a couple hundred nanoseconds), because after that WPRO* is tricked into thinking it was reset and the output agrees with what is being forced so no more contention. The PAL used, according to the manufacturer, is able to handle voltage applied to outputs up to Vcc, which is +5V, so we're within specs. ******************************************************************** Happy hacking! Steve Schoettler ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -- Bob Page, U of Lowell CS Dept. page@swan.ulowell.edu ulowell!page Have five nice days.
sean@ms.uky.edu (Sean Casey) (12/30/88)
In article <5595@cbmvax.UUCP> steveb@cbmvax.UUCP (Steve Beats) writes: |>So... suggestions? My eventual aim is to have my format of floppy auto- |>recognised when a floppy is stuck in the drive, which I decided was |'fraid you have hit a pretty glaring hole in the current AmigaDOS filing |system environment. Right now, the filing system is mounted on a device |and remains there for all time. The mounted filing system decides if it |can grok the inserted disk, if it can't, it just says "not a DOS disk" and |gives up. There is no facility for "passing-on" a disk to an alternate |filing system. Unfortunately, this is what you need. I thought that this was exactly what FFS on floppies combined with autodiskchange does. Have I got it wrong? Sean -- *** Sean Casey sean@ms.uky.edu, sean@ukma.bitnet *** Who sometimes never learns. {backbone site|rutgers|uunet}!ukma!sean *** U of K, Lexington Kentucky, USA ..where Christian movies are banned. *** ``My name is father. You killed my die. Prepare to Inigo Montoya.''
sean@ms.uky.edu (Sean Casey) (12/30/88)
In article <10967@swan.ulowell.edu> page@swan.ulowell.edu (Bob Page) writes: >mcp@ziebmef.UUCP (Colin Plumb) wrote: >>I haven't yet found the magic flag that write-enables the WCS. > >My dim view of Amiga hardware says you won't find such a magic flag. Apparently the people who wrote Dragon's Lair did. It's there somewhere. How about it, CA? How is it done? Sean -- *** Sean Casey sean@ms.uky.edu, sean@ukma.bitnet *** Who sometimes never learns. {backbone site|rutgers|uunet}!ukma!sean *** U of K, Lexington Kentucky, USA ..where Christian movies are banned. *** ``My name is father. You killed my die. Prepare to Inigo Montoya.''
kodiak@amiga.UUCP (Robert R. Burns) (12/31/88)
In article (Colin Plumb) writes: )00fff1b0: 0000 0000 ori.b #0,d0 )00fff1b4: 0000 038d ori.b #-73,d0 )00fff1b8: 2401 move.l d1,d2 )(more reasonable-looking code) )... )BCPL compiler, anyone? (1.3 kickstart, BTW.) )... )For the technically oriented, I patched rn->RestartSeg to hold 0x7f2d, )0x1fcb4 in the APTR world, and at that address is found: ) )0001fcb4: 003f fc6c ori.b $6c,usp )0001fcb8: 4e71 4e71 nop nop )0001fcbc: 4ef9 00ff f1b4 fmp fff1b4 Well, that *fmp* instruction will get you every time! :-) Seriously: 1. You're looking at a BCPL segment global table. The 0000 0000 is indeed a NULL next pointer, and the 0000 038d is the size of the segment. You have now entered the twilight zone. The reason you're crashing is because BCPL segments are different than any other kind of segment, and the lie about either the next segment pointer, or (more likely) the size of this one caused the crash. Moreover, execution does not start at the first code in the first segment. I honestly don't want to go into more detail lest folks start using the mechanisms involved, because they are structurally flawed and will break if too many people use them. Hope you're not the "knowledge for knowledge's sake" type :-). 2. This mechanism (if you get it to work) will not be supported for 1.4, but I see Steve has already said that. -- Bob Burns, amiga!kodiak _ | /_ _|. _ | Commodore __ |_) _ |_ _ )' |<(_)(_)|(_\|< /\ | ||| _` /\ |_)(_\| )(_\ | | \ Software ___/..\|\/|||__|/..\___ Faith
grr@cbmvax.UUCP (George Robbins) (01/01/89)
In article <1988Dec27.223345.29513@ziebmef.uucp> mcp@ziebmef.UUCP (Colin Plumb) writes: > I'm trying to reverse-engineer the disk validator, and encoutering a few > snags. Could someone help me out? > > What I'd really like to do is put breakpoints in the ROMs and work through > things that way, but I haven't yet found the magic flag that write-enables > the WCS. The only likely sounding thing, the "memory overlay bit" on > PA0 of 8250 A, crashes the machine. Obviously not what I want. There is no magic flag. What you must do to reenable writing to the control store is issue a 68000 reset instruction, then get things started up again. This is, in general, non-trivial task, though I suspose for a stand-alone game it isn't that hard. The "memory overlay bit" or "OVR" bit simply controls whether ROM or "chip" memory is mapped at location 0. This is neccessary so that the processor can find it's way to the normal "ROM" area. It is of course fairly simple to modify the RAM/ROM tower board to disable the ROM write protect feature... -- George Robbins - now working for, uucp: {uunet|pyramid|rutgers}!cbmvax!grr but no way officially representing arpa: cbmvax!grr@uunet.uu.net Commodore, Engineering Department fone: 215-431-9255 (only by moonlite)
scott@applix.UUCP (Scott Evernden) (01/07/89)
>>>I haven't yet found the magic flag that write-enables the WCS. Based on a note by Martin Brenner, I quickly tried this in Manx C and it sure seems to work main() { * (long *) 0x80 = 0xFC00D0; /* a RESET */ #asm trap #0 #endasm } Compile and run. The machine'll reboot, but the WCS will be unprotected and the BootRom will be visible at 0xF80000. Please don't anyone use this for amything. -scott