revert between 56095 -> 55830 in arch
[AROS.git] / arch / .unmaintained / m68k-pp-native / dos / dosboot.c
blob00a2ebaa0359107e95ae599bb381220be71ba784
1 /*
2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
3 Id: dosboot.c,v 1.16 2001/08/26 02:27:00 falemagn Exp $
5 Desc: Start up the ol' Dos boot process.
6 Lang: english
7 */
10 # define DEBUG 1
11 # include <aros/debug.h>
13 #include <aros/macros.h>
15 #include <exec/types.h>
16 #include <exec/nodes.h>
17 #include <exec/lists.h>
18 #include <exec/execbase.h>
19 #include <exec/alerts.h>
20 #include <exec/memory.h>
21 #include <dos/dosextens.h>
22 #include <dos/dostags.h>
23 #include <libraries/expansionbase.h>
24 #include <aros/asmcall.h>
25 #include <string.h>
26 #include <dos/filehandler.h>
27 #include <dos/filesystem.h>
28 #include <devices/trackdisk.h>
30 #include <proto/exec.h>
31 #include <proto/dos.h>
33 #include <string.h>
35 extern void boot();
37 BOOL init_hidds( struct ExecBase *, struct DosLibrary * );
38 BOOL mount( struct DeviceNode *dn, struct DosLibrary * );
39 BOOL isBootable( CONST_STRPTR deviceNam, struct DosLibrary * );
41 AROS_UFH3(void, intBoot,
42 AROS_UFHA(APTR, argString, A0),
43 AROS_UFHA(ULONG, argSize, D0),
44 AROS_UFHA(struct ExecBase *,SysBase, A6)
47 AROS_USERFUNC_INIT
49 struct ExpansionBase *ExpansionBase = NULL;
50 struct DosLibrary *DOSBase = NULL;
51 struct BootNode *bootNode = NULL;
52 STRPTR bootName;
53 LONG bootNameLength;
54 BPTR lock;
55 LONG second;
57 # define deviceName (((struct DosList *) bootNode->bn_DeviceNode)->dol_DevName)
59 /**** Open all required libraries **********************************************/
60 DOSBase = (struct DosLibrary *) OpenLibrary( "dos.library", 0 );
61 ExpansionBase = (struct ExpansionBase *) OpenLibrary( "expansion.library", 0 );
63 if( DOSBase == NULL )
65 D(bug( "Could not open dos.library, something's wrong!\n" ));
66 Alert(AT_DeadEnd| AG_OpenLib | AN_DOSLib | AO_DOSLib);
69 if( ExpansionBase == NULL )
71 D(bug( "Could not open expansion.library, something's wrong!\n"));
72 Alert(AT_DeadEnd | AG_OpenLib | AN_DOSLib | AO_ExpansionLib);
75 /**** Try to mount all filesystems in the MountList ****************************/
76 D(bug( "Examining MountList:\n" ));
78 ForeachNode( &ExpansionBase->MountList, bootNode )
80 D(bug
82 "Node: %p, DevNode: %p, Name = %s\n",
83 bootNode, bootNode->bn_DeviceNode,
84 deviceName ? deviceName : "(null)"
85 ));
86 //#if (AROS_FLAVOUR & AROS_FLAVOUR_EMULATION)
87 #if 0
88 #warning !!! Cannot have this part activated. I do define AROS_FLAVOUR_EMULATION
89 #warning in order no to have to deal with things in boot/strap.c like
90 #warning partition.library.
91 AddDosEntry( (struct DosList *) bootNode->bn_DeviceNode );
92 #else
93 /*
94 Try to mount the filesystem. If it fails, remove the BootNode
95 from the list so DOS doesn't try to boot from it later.
96 */
98 if( !mount( (struct DeviceNode *) bootNode->bn_DeviceNode ,
99 (struct DosLibrary *) DOSBase))
101 REMOVE( bootNode );
103 #endif
106 /**** Try to find a bootable filesystem ****************************************/
107 while( TRUE )
109 ForeachNode( &ExpansionBase->MountList, bootNode )
112 Check if the mounted filesystem is bootable. If it's not,
113 it's probably some kind of transient error (ie. no disk
114 in drive or wrong disk) so we only move it to the end of
115 the list.
118 if( isBootable( deviceName, (struct DosLibrary *)DOSBase ) )
120 goto boot;
124 kprintf( "No bootable disk was found.\n" );
125 kprintf( "Please insert a bootable disk in any drive.\n" );
127 for( second = 5; second > 0; second-- ) {
128 kprintf( "Retrying in %d seconds...\n", second );
129 Delay( 50 );
132 /* FIXME: Should there be a prompt instead of a automatic retry? */
135 boot:
137 /* Construct the complete device name of the boot device */
138 bootNameLength = strlen( deviceName ) + 2;
139 bootName = AllocMem( bootNameLength, MEMF_ANY);
141 if( bootName == NULL )
143 Alert(AT_DeadEnd | AG_NoMemory | AO_DOSLib | AN_StartMem);
146 strcpy( bootName, deviceName );
147 strcat( bootName, ":" );
149 /* We don't need expansion.library any more */
150 CloseLibrary( (struct Library *) ExpansionBase );
152 /* Lock the boot device and add some default assigns */
154 lock = DOSBase->dl_SYSLock = Lock(bootName, SHARED_LOCK);
156 if (lock != NULL)
158 AssignLock("SYS", lock);
160 else
162 Alert(AT_DeadEnd | AG_BadParm | AN_DOSLib);
165 FreeMem( bootName, bootNameLength );
166 lock = Lock("SYS:", SHARED_LOCK);
168 if (lock != NULL)
170 CurrentDir(lock);
172 else
174 Alert(AT_DeadEnd | AG_BadParm | AN_DOSLib);
177 lock = Lock("SYS:C", SHARED_LOCK);
179 if (lock != NULL)
181 AssignLock("C", lock);
184 lock = Lock("SYS:S", SHARED_LOCK);
186 if (lock != NULL)
188 AssignLock("S", lock);
191 lock = Lock("SYS:Libs", SHARED_LOCK);
193 if (lock != NULL)
195 AssignLock("LIBS", lock);
198 lock = Lock("SYS:Devs", SHARED_LOCK);
200 if (lock != NULL)
202 AssignLock("DEVS", lock);
205 /* Late binding ENVARC: assign, only if used */
206 AssignLate("ENVARC", "SYS:Prefs/env-archive");
208 /* Initialize HIDDs */
209 init_hidds(SysBase, (struct DosLibrary *)DOSBase);
211 /* We now call the system dependant boot - should never return. */
212 AROS_UFC3(void, boot,
213 AROS_UFCA(STRPTR, argString, A0),
214 AROS_UFCA(ULONG, argSize, D0),
215 AROS_UFCA(struct ExecBase *, SysBase, A6));
217 # undef deviceName
219 AROS_USERFUNC_EXIT
223 void DOSBoot(struct ExecBase *SysBase, struct DosLibrary *DOSBase)
225 struct TagItem bootprocess[] =
227 { NP_Entry, (IPTR) intBoot },
228 { NP_Name, (IPTR) "Boot Process" },
229 { NP_Input, (IPTR) NULL },
230 { NP_Output, (IPTR) NULL },
231 { NP_CurrentDir, (IPTR) NULL },
232 { NP_Cli, (IPTR) 0 },
233 { TAG_END, }
236 if( CreateNewProc( bootprocess ) == NULL )
238 D(bug
240 "CreateNewProc() failed with %ld\n",
241 ((struct Process *) FindTask( NULL ))->pr_Result2
243 Alert( AT_DeadEnd | AN_DOSLib | AG_ProcCreate );
247 #ifdef SysBase
248 #undef SysBase
249 #endif
251 #define SysBase (DOSBase->dl_SysBase)
253 BOOL mount( struct DeviceNode *dn, struct DosLibrary * DOSBase )
255 struct FileSysStartupMsg *fssm = BADDR(dn->dn_Startup);
256 struct IOFileSys *iofs;
257 struct MsgPort *mp = CreateMsgPort();
258 BOOL rc = FALSE;
260 if (mp != NULL)
262 iofs = (struct IOFileSys *)CreateIORequest(mp,
263 sizeof(struct IOFileSys));
264 if (iofs != NULL)
266 iofs->io_Union.io_OpenDevice.io_DeviceName = AROS_BSTR_ADDR(fssm->fssm_Device);
267 iofs->io_Union.io_OpenDevice.io_Unit = fssm->fssm_Unit;
268 iofs->io_Union.io_OpenDevice.io_Environ = BADDR(fssm->fssm_Environ);
269 iofs->io_Union.io_OpenDevice.io_DosName = dn->dn_NewName;
270 if (!OpenDevice(AROS_BSTR_ADDR(dn->dn_Handler), 0, &iofs->IOFS, 0))
272 if (AddDosEntry(dn))
274 dn->dn_Unit = iofs->IOFS.io_Unit;
275 dn->dn_Device = iofs->IOFS.io_Device;
276 /* Do not close filesys !!! */
277 rc = TRUE;
281 DeleteIORequest((struct IORequest *)iofs);
283 else
285 Alert(AT_DeadEnd | AG_NoMemory | AN_DOSLib);
288 DeleteMsgPort(mp);
290 else
292 Alert(AT_DeadEnd | AG_NoMemory | AN_DOSLib);
295 return rc;
298 #ifdef SysBase
299 #undef SysBase
300 #endif
302 #define SysBase (DOSBase->dl_SysBase)
304 BOOL isBootable( CONST_STRPTR deviceName, struct DosLibrary * DOSBase )
306 BOOL result = FALSE;
307 BPTR lock;
308 STRPTR buffer;
309 LONG bufferLength;
310 struct InfoData info;
312 bufferLength = strlen( deviceName ) + 2;
314 if( (buffer = AllocMem( bufferLength, MEMF_ANY ) ) == NULL )
316 Alert( AT_DeadEnd | AG_NoMemory | AN_DOSLib );
319 strcpy( buffer, deviceName );
320 strcat( buffer, ":" );
322 if( (lock = Lock( buffer, SHARED_LOCK )) == 0 )
324 D(bug( "dosboot: could not lock '%s'\n", buffer ));
325 goto cleanup;
328 if( !Info( lock, &info ) )
330 D(bug( "dosboot: could not get info on '%s'\n", buffer ));
331 goto cleanup;
334 if( info.id_DiskType != ID_NO_DISK_PRESENT )
336 result = TRUE;
339 cleanup:
340 if( buffer != NULL ) FreeMem( buffer, bufferLength );
341 if( lock != 0 ) UnLock( lock );
343 return result;
346 #ifdef SysBase
347 #undef SysBase
348 #endif