Welcome, Guest. Please login or register.

Author Topic: Diskless booting of Amiga  (Read 8974 times)

Description:

0 Members and 1 Guest are viewing this topic.

Offline freqmaxTopic starter

  • Hero Member
  • *****
  • Join Date: Mar 2006
  • Posts: 2179
    • Show all replies
Re: Diskless booting of Amiga
« Reply #14 from previous page: June 08, 2013, 10:56:59 PM »
Regarding the thread at abime.net:

The following has to be present in ROM:
 * SANA-II driver (for network hardware)
 * IP + UDP stack
 * NFS client

He says dos.library has to be present. Perhaps one could rather add a hook that will be activated when said library is present? it could then initialize SANA-IP-UDP-NFS in one go.

If there absolutely has to be a "disk" present. One could create a few kB "ROM:" with a bootblock and directory entry. Once dos.library feels to show up one does a switch-and-bait and changes this so that it will access the NFS server instead. Just like one can replace files on a live filesystem under NFS/unix.
 

Offline freqmaxTopic starter

  • Hero Member
  • *****
  • Join Date: Mar 2006
  • Posts: 2179
    • Show all replies
Re: Diskless booting of Amiga
« Reply #15 on: June 09, 2013, 12:11:52 AM »
Found this nice example in comp.os.research in 1993:
User-level Filesystems (was Re: Plan 9)
Quote
Nice example.  For comparison, I'll post an AmigaDOS filesystem.  I'm
writing this off the top of my head, so it probably would need tweaking to
compile.  AmigaDOS, like QNX, converts requests into messages sent to a user-
level process.  I'll try to keep it short and leave out non-relevant parts,
including most of the error-checking.

        Note: this is for a ram disk.  Also, for historical reasons from
Tripos and BCPL, many DOS pointers are BPTR's (longword offsets; i.e. pointers
shifted right by 2.  Ugh.)

Code: [Select]
#include <various header files>

struct DosPacket {
   struct Message *dp_Link;      /* EXEC message              */
   struct MsgPort *dp_Port;      /* Reply port for the packet */
                                 /* Must be filled in each send. */
   LONG dp_Action;               /* See ACTION_... below and
   LONG dp_Res1;                 /* For file system calls this is the result
                                  * that would have been returned by the
                                  * function, e.g. Write returns actual
                                  * length written */
   LONG dp_Res2;                 /* For file system calls this is what would
                                  * have been returned by IoErr() */
   LONG dp_Arg1;                    
   LONG dp_Arg2;
   LONG dp_Arg3;
   ...

};

struct node *root;
struct lock *lock_list;
struct MsgPort *MyPort;
LONG res1,fileerr;

main (struct DosPacket *dp) {
        struct Message    *msg;
        struct DeviceList *devnode,*newnode;
        struct node *node;
        ULONG arg1;

        /* various shared library opens/inits */
        ...

        MyPort = &(FindTask(NULL)->pr_MsgPort);

        root = (struct node *) AllocVec(sizeof(struct node),MEMF_CLEAR);
        root->type = ST_USERDIR;
        strcpy(root->name,&quot;Ram Disk&quot;);
        lock_list  = NULL;
        spaceused  = 1;

        /* add our volume entry to the system */
        newnode = MakeDosEntry(&quot;Ram Disk&quot;,DLT_VOLUME);
        newnode->dl_Task     = MyPort;
        newnode->dl_DiskType = ID_DOS_DISK;
        DateStamp(&(newnode->dl_VolumeDate));
        AddDosEntry(newnode);

        /* our Device node already exists - BPTR */
        devnode = (struct DeviceList *) (dp->dp_Arg3 << 2);
        devnode->dl_Task = MyPort;

        /* init finished successfully, tell system we're ready */
        ReplyPkt(dp,DOS_TRUE,0);

        while (1) {
            sigs = Wait(1L << MyPort->mp_SigBit);

            /* handle dospackets */
            while ((msg = GetMsg(MyPort)) != NULL)
            {
                dp = (struct DosPacket *) msg->mn_Node.ln_Name;

                /* set result to failure, clear secondary result */
                res1 = fileerr = 0;

                /* used by most functions-usually BPTR to filehandle or lock */
                arg1 = dp->dp_Arg1 << 2;       /* save space, do it once */

                switch (dp->dp_Action) {
                case ACTION_WRITE:      /* Write(fh,buffer,len) */
                        res1 = write((struct lock *) arg1,
                                     (CPTR) dp->dp_Arg2, dp->dp_Arg3);
                        break;
                case ACTION_READ:       /* Read(fh,buffer,len */
                        res1 = read((struct lock *) arg1,
                                    (CPTR) dp->dp_Arg2, dp->dp_Arg3);
                        break;
                case MODE_NEWFILE:      /* fh = Open(name,MODE_NEWFILE) */
                        flag = 0;
open:
                        res1 = openmakefile(
                                       (struct FileHandle *) arg1,
                                       (struct lock *) (dp->dp_Arg2 << 2),
                                       BtoC(str1,dp->dp_Arg3),
                                       flag);
                        break;
                case ACTION_END:        /* aka Close(fh) */
                        res1 = closefile((struct lock *) arg1);
                        break;
                etc...

                case ACTION_INHIBIT:
                case ACTION_GET_BLOCK:
                case ACTION_MORE_CACHE:
                default:
                        fileerr = ERROR_ACTION_NOT_KNOWN;
                } /* switch */

                /* we've handled the packet, return it */
                ReplyPkt(dp,res1,fileerr);

            } /* while GetMsg */
        } /* while 1 */
}


Hint at function replacements over kickstart versions?
abime.net/attachment.php?attachmentid=33641&d=1356876093
Quote
To reduce code size, can use V36+ functions like LockDosList() instead of Forbid()/Permit(), and MakeDosEntry(). Also use RemDosEntry() and FreeDosEntry() to replace most of code in RemoveFreeDosEntry routine at offset $3352.
« Last Edit: June 09, 2013, 12:16:52 AM by freqmax »
 

Offline freqmaxTopic starter

  • Hero Member
  • *****
  • Join Date: Mar 2006
  • Posts: 2179
    • Show all replies
Re: Diskless booting of Amiga
« Reply #16 on: June 09, 2013, 02:17:52 PM »
So RKRM - ROM Kernel Reference Manuals..
"Chapter 27 Graphics Primitives" seems wrong?

Page 702 "ROM Based and Autoboot Drivers" seems interesting however..

Of the three stages DIAG, ROMTAG INIT and BOOT. The last one perhaps is the deal.

Need to figure these out, especially how the first one finds out the name of the volume in the source code:
http://gega.homelinux.net/AmigaDevDocs/dos.html#adddosentry() in nfs_handler.c main()

MakeDosEntry(g->g_VolumeName, DLT_VOLUME) in nfs_handler.c G_Init()

MakeDosEntry(g->g_DeviceName, DLT_DEVICE) in nfs_handler.c G_Init()
« Last Edit: June 09, 2013, 04:02:32 PM by freqmax »
 

Offline freqmaxTopic starter

  • Hero Member
  • *****
  • Join Date: Mar 2006
  • Posts: 2179
    • Show all replies
Re: Diskless booting of Amiga
« Reply #17 on: June 10, 2013, 04:10:29 AM »
I read the discussion at eabime and I think Toni makes some assumptions about implementation that isn't required. Ie one can make SANA-II + UDP/IP driver that manages being in ROM and it can collect any configuration information from DHCP. And TCP isn't even needed.

So it would go something like this:
 * Called via da_DiagPoint
 * Network ROM allocates RAM for variables etc (likely be EEPROM in reality)
 * Hooks Resident structure
 * Quits
 * ....
 * Called via Resident structure
 * Hooks eb_MountList
 * Quits
 * ....
 * Called via eb_MountList
 * Initializes SANA-II driver
 * Initializes IP driver
 * Requests it's own IP+mask+gateway+DNS+fileserver etc by sending DHCP request
 * Initializes UDP driver
 * Initializes NFS driver
 * Creates boot volume assign to BOOT: (or whatever DHCP told it too)
 * DOS can now happily read S:Startup-sequence etc..

The only worry would be this:
Quote from: Toni
- DOS gets initialized (via BootPoint "bootblock")
Because a filesystem (not blocksystem) well.. won't have any blocks. ;)

Amiga ROM Kernel Reference Manual: Libraries, 3rd edition, page 702 mentions DIAG, ROMTAG INIT and BOOT. Which seems to be about:

DIAG:
Quote
will also include the da_DiagPoint ROM/diagnostic routine, a Resident structure (romtag), a device driver (or at least the device initialization tables or structures which need patching), and the da_BootPoint routine.
(p703)

ROMTAG INIT:
Quote
most resident system modules (for example graphics) are initialized. /../ the board’s device driver is initialized.
(p709)
(this is likely the stage at which Picasso96 etc will start generating video etc)

BOOT:
Quote
will examine the eb_MountList; find the highest priority BootNode structure at the head of the List; validate the BootNode; determine which ConfigDev is associated with this BootNode; find its DiagArea; and call its da_BootPoint function in the ROM "image" to bootstrap the appropriate DOS. Generally, the BootPoint code of a ROM driver will perform the same function as the boot code installed on a floppy disk, i.e., it will FindResident() the dos.library, and jump to its RT_INIT vector. The da_BootPoint call, if successful, should not return.
(p709)
I assume this means dos.library is available..

For network this should translate into:
DIAG: Allocate memory
ROMTAG INIT: Tell network hardware to enable itself, hook into eb_MountList.
BOOT: First call to the network driver da_BootPoint routine fires up any missing parts that requires dos.library
« Last Edit: June 10, 2013, 06:51:51 AM by freqmax »
 

Offline freqmaxTopic starter

  • Hero Member
  • *****
  • Join Date: Mar 2006
  • Posts: 2179
    • Show all replies
Re: Diskless booting of Amiga
« Reply #18 on: June 10, 2013, 10:44:30 AM »
NFS only need TCP if you configure it too. It can use any protocoll.

Some common missconceptions:
 * You need IP to communicate. No you can use MAC layer directly just like ARP does
 * TCP/IP stack is required. Infact quite a lot can be done with just IP, like ICMP_ECHO. Which some trojans used to "phone-home".
 * And TCP/IP usually refer to IP + UDP + TCP in that complication order. But IP is the only one required to support UDP or TCP.
 * Most things can be done with UDP which is really simple to implement, it's just that TCP makes things a lot easier.
 * NFS can be configured to use either UDP or TCP. Eliminating TCP saves some codes of programming.

So a minimalistic approach would be to use MAC layer directly with the SANA driver. Very incompatible, but it could do the job.
 

Offline freqmaxTopic starter

  • Hero Member
  • *****
  • Join Date: Mar 2006
  • Posts: 2179
    • Show all replies
Re: Diskless booting of Amiga
« Reply #19 on: June 10, 2013, 01:07:57 PM »
RAD: is essentially a emulated floppy
RAM: behaves very much like a network drive

From what I remember.
 

Offline freqmaxTopic starter

  • Hero Member
  • *****
  • Join Date: Mar 2006
  • Posts: 2179
    • Show all replies
Re: Diskless booting of Amiga
« Reply #20 on: June 10, 2013, 06:34:31 PM »
As I recall the RAD: device only allocate sectors when they are used. Thus it's dynamic to a certain degree.