New bitmap method SetRGBConversionFunction which can be used to
[tangerine.git] / rom / dos / dosboot.c
blob6796323e97e6ff0ceb1718974c066d65e390b29f
1 /*
2 Copyright © 1995-2006, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Start up the ol' Dos boot process.
6 Lang: english
7 */
10 # define DEBUG 0
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 AddDosEntry( (struct DosList *) bootNode->bn_DeviceNode );
88 #else
89 /*
90 Try to mount the filesystem. If it fails, remove the BootNode
91 from the list so DOS doesn't try to boot from it later.
92 */
94 if( !mount( (struct DeviceNode *) bootNode->bn_DeviceNode ,
95 (struct DosLibrary *) DOSBase))
97 REMOVE( bootNode );
99 #endif
102 /**** Try to find a bootable filesystem ****************************************/
103 while( TRUE )
105 ForeachNode( &ExpansionBase->MountList, bootNode )
108 Check if the mounted filesystem is bootable. If it's not,
109 it's probably some kind of transient error (ie. no disk
110 in drive or wrong disk) so we only move it to the end of
111 the list.
114 if( isBootable( deviceName, (struct DosLibrary *)DOSBase ) )
116 goto boot;
120 kprintf( "No bootable disk was found.\n" );
121 kprintf( "Please insert a bootable disk in any drive.\n" );
123 #if 0
124 for( second = 5; second > 0; second-- ) {
125 kprintf( "Retrying in %d seconds...\n", second );
126 Delay( 50 );
128 #else
129 kprintf( "Retrying in 5 seconds...\n" );
130 Delay( 500 );
131 #endif
133 /* FIXME: Should there be a prompt instead of a automatic retry? */
136 boot:
138 /* Construct the complete device name of the boot device */
139 bootNameLength = strlen( deviceName ) + 2;
140 bootName = AllocMem( bootNameLength, MEMF_ANY);
142 if( bootName == NULL )
144 Alert(AT_DeadEnd | AG_NoMemory | AO_DOSLib | AN_StartMem);
147 strcpy( bootName, deviceName );
148 strcat( bootName, ":" );
150 kprintf("[DOS] Booting from device %s\n",bootName);
152 /* We don't need expansion.library any more */
153 CloseLibrary( (struct Library *) ExpansionBase );
155 /* Lock the boot device and add some default assigns */
156 D(bug("Locking primary boot device %s\n", bootName));
158 lock = Lock(bootName, SHARED_LOCK);
159 if (lock) DOSBase->dl_SYSLock = DupLock(lock);
161 if ((lock != NULL) && (DOSBase->dl_SYSLock != NULL))
163 AssignLock("SYS", lock);
165 else
167 Alert(AT_DeadEnd | AG_BadParm | AN_DOSLib);
170 FreeMem( bootName, bootNameLength );
172 lock = Lock("SYS:", SHARED_LOCK);
174 if (lock != NULL)
176 CurrentDir(lock);
178 else
180 Alert(AT_DeadEnd | AG_BadParm | AN_DOSLib);
183 lock = Lock("SYS:C", SHARED_LOCK);
185 if (lock != NULL)
187 AssignLock("C", lock);
190 lock = Lock("SYS:S", SHARED_LOCK);
192 if (lock != NULL)
194 AssignLock("S", lock);
197 lock = Lock("SYS:Libs", SHARED_LOCK);
199 if (lock != NULL)
201 AssignLock("LIBS", lock);
204 lock = Lock("SYS:Devs", SHARED_LOCK);
206 if (lock != NULL)
208 AssignLock("DEVS", lock);
211 lock = Lock("DEVS:Drivers", SHARED_LOCK);
213 if (lock != NULL)
215 AssignLock("DRIVERS", lock);
216 AssignAdd("LIBS", lock); /* Let hidds in DRIVERS: directory be found by OpenLibrary */
219 /* Late binding ENVARC: assign, only if used */
220 AssignLate("ENVARC", "SYS:Prefs/env-archive");
222 /* Initialize HIDDs */
223 init_hidds(SysBase, (struct DosLibrary *)DOSBase);
225 /* We now call the system dependant boot - should never return. */
226 AROS_UFC3(void, boot,
227 AROS_UFCA(STRPTR, argString, A0),
228 AROS_UFCA(ULONG, argSize, D0),
229 AROS_UFCA(struct ExecBase *, SysBase, A6));
231 # undef deviceName
233 AROS_USERFUNC_EXIT
236 void DOSBoot(struct ExecBase *SysBase, struct DosLibrary *DOSBase)
238 struct TagItem bootprocess[] =
240 { NP_Entry, (IPTR) intBoot },
241 { NP_Name, (IPTR) "Boot Process" },
242 { NP_Input, (IPTR) NULL },
243 { NP_Output, (IPTR) NULL },
244 { NP_CurrentDir, (IPTR) NULL },
245 { NP_StackSize, AROS_STACKSIZE * 2},
246 { NP_Cli, (IPTR) 0 },
247 { TAG_END, }
250 if( CreateNewProc( bootprocess ) == NULL )
252 D(bug
254 "CreateNewProc() failed with %ld\n",
255 ((struct Process *) FindTask( NULL ))->pr_Result2
257 Alert( AT_DeadEnd | AN_DOSLib | AG_ProcCreate );
261 BOOL mount( struct DeviceNode *dn, struct DosLibrary * DOSBase )
263 struct FileSysStartupMsg *fssm = BADDR(dn->dn_Startup);
264 struct IOFileSys *iofs;
265 struct MsgPort *mp = CreateMsgPort();
266 BOOL rc = FALSE;
268 if (mp != NULL)
270 iofs = (struct IOFileSys *)CreateIORequest(mp,
271 sizeof(struct IOFileSys));
272 if (iofs != NULL)
274 iofs->io_Union.io_OpenDevice.io_DeviceName = AROS_BSTR_ADDR(fssm->fssm_Device);
275 iofs->io_Union.io_OpenDevice.io_Unit = fssm->fssm_Unit;
276 iofs->io_Union.io_OpenDevice.io_Environ = BADDR(fssm->fssm_Environ);
277 iofs->io_Union.io_OpenDevice.io_DosName = dn->dn_NewName;
278 if (!OpenDevice(AROS_BSTR_ADDR(dn->dn_Handler), 0, &iofs->IOFS, 0))
280 if (AddDosEntry((struct DosList *) dn))
282 dn->dn_Unit = iofs->IOFS.io_Unit;
283 dn->dn_Device = iofs->IOFS.io_Device;
284 /* Do not close filesys !!! */
285 rc = TRUE;
289 DeleteIORequest((struct IORequest *)iofs);
291 else
293 Alert(AT_DeadEnd | AG_NoMemory | AN_DOSLib);
296 DeleteMsgPort(mp);
298 else
300 Alert(AT_DeadEnd | AG_NoMemory | AN_DOSLib);
303 return rc;
306 BOOL isBootable( CONST_STRPTR deviceName, struct DosLibrary * DOSBase )
308 BOOL result = FALSE;
309 BPTR lock;
310 STRPTR buffer;
311 LONG bufferLength;
312 struct InfoData info;
314 #define STARTUP_SEQUENCE_FILE ":S/Startup-Sequence"
316 bufferLength = strlen( deviceName ) + sizeof(STARTUP_SEQUENCE_FILE) + 1;
318 if( (buffer = AllocMem( bufferLength, MEMF_ANY ) ) == NULL )
320 Alert( AT_DeadEnd | AG_NoMemory | AN_DOSLib );
323 strcpy( buffer, deviceName );
324 strcat( buffer, STARTUP_SEQUENCE_FILE );
326 if( (lock = Lock( buffer, SHARED_LOCK )) == 0 )
328 D(bug( "dosboot: could not lock '%s'\n", buffer ));
329 goto cleanup;
332 if( !Info( lock, &info ) )
334 D(bug( "dosboot: could not get info on '%s'\n", buffer ));
335 goto cleanup;
338 if( info.id_DiskType != ID_NO_DISK_PRESENT )
340 result = TRUE;
343 cleanup:
344 if( buffer != NULL ) FreeMem( buffer, bufferLength );
345 if( lock != 0 ) UnLock( lock );
347 return result;