2 Copyright © 1995-2007, The AROS Development Team. All rights reserved.
5 Desc: Start up the ol' Dos boot process.
9 /* Uncomment this definition in order to enable mounting
10 disk-based handlers (e.g. fat.handler) at bootup.
11 This code works however fat.handler itself currently has
12 problems, so this option is disabled for now
13 #define MOUNT_DISK_HANDLERS */
16 # include <aros/debug.h>
18 #include <aros/macros.h>
20 #include <exec/types.h>
21 #include <exec/nodes.h>
22 #include <exec/lists.h>
23 #include <exec/execbase.h>
24 #include <exec/alerts.h>
25 #include <exec/memory.h>
26 #include <dos/dosextens.h>
27 #include <dos/dostags.h>
28 #include <libraries/expansionbase.h>
29 #include <aros/asmcall.h>
31 #include <dos/filehandler.h>
32 #include <dos/filesystem.h>
33 #include <devices/trackdisk.h>
35 #include <proto/exec.h>
36 #include <proto/dos.h>
40 #include "dos_intern.h"
42 #define BNF_RETRY 0x8000 /* Private flag for the BootNode */
46 BOOL
init_hidds( struct ExecBase
*, struct DosLibrary
* );
47 BOOL
mount( struct DeviceNode
*dn
, struct DosLibrary
* );
48 BOOL
isBootable( CONST_STRPTR deviceNam
, struct DosLibrary
* );
50 AROS_UFH3(void, intBoot
,
51 AROS_UFHA(APTR
, argString
, A0
),
52 AROS_UFHA(ULONG
, argSize
, D0
),
53 AROS_UFHA(struct ExecBase
*,SysBase
, A6
)
58 struct ExpansionBase
*ExpansionBase
= NULL
;
59 struct DosLibrary
*DOSBase
= NULL
;
60 struct BootNode
*bootNode
= NULL
;
66 # define deviceName (((struct DosList *) bootNode->bn_DeviceNode)->dol_Ext.dol_AROS.dol_DevName)
68 /**** Open all required libraries **********************************************/
69 DOSBase
= (struct DosLibrary
*) OpenLibrary( "dos.library", 0 );
70 ExpansionBase
= (struct ExpansionBase
*) OpenLibrary( "expansion.library", 0 );
74 D(bug( "Could not open dos.library, something's wrong!\n" ));
75 Alert(AT_DeadEnd
| AG_OpenLib
| AN_DOSLib
| AO_DOSLib
);
78 if( ExpansionBase
== NULL
)
80 D(bug( "Could not open expansion.library, something's wrong!\n"));
81 Alert(AT_DeadEnd
| AG_OpenLib
| AN_DOSLib
| AO_ExpansionLib
);
84 /**** Try to mount all filesystems in the MountList ****************************/
85 D(bug( "Examining MountList:\n" ));
87 ForeachNode( &ExpansionBase
->MountList
, bootNode
)
91 "Node: %p, DevNode: %p, Name = %s\n",
92 bootNode
, bootNode
->bn_DeviceNode
,
93 deviceName
? deviceName
: "(null)"
96 Try to mount the filesystem. If it fails, mark the BootNode
97 so DOS doesn't try to boot from it later but will retry to
98 mount it after boot device is found and system directories
102 if( !mount( (struct DeviceNode
*) bootNode
->bn_DeviceNode
,
103 (struct DosLibrary
*) DOSBase
))
105 #ifdef MOUNT_DISK_HANDLERS
106 bootNode
->bn_Flags
|= BNF_RETRY
;
112 bootNode
->bn_Flags
&= ~BNF_RETRY
;
115 /**** Try to find a bootable filesystem ****************************************/
118 ForeachNode( &ExpansionBase
->MountList
, bootNode
)
121 Check if the mounted filesystem is bootable. If it's not,
122 it's probably some kind of transient error (ie. no disk
123 in drive or wrong disk) so we only move it to the end of
127 if((!(bootNode
->bn_Flags
& BNF_RETRY
)) && isBootable( deviceName
, (struct DosLibrary
*)DOSBase
) )
133 kprintf( "No bootable disk was found.\n" );
134 kprintf( "Please insert a bootable disk in any drive.\n" );
137 for( second
= 5; second
> 0; second
-- ) {
138 kprintf( "Retrying in %d seconds...\n", second
);
142 kprintf( "Retrying in 5 seconds...\n" );
146 /* FIXME: Should there be a prompt instead of a automatic retry? */
151 /* Construct the complete device name of the boot device */
152 bootNameLength
= strlen( deviceName
) + 2;
153 bootName
= AllocMem( bootNameLength
, MEMF_ANY
);
155 if( bootName
== NULL
)
157 Alert(AT_DeadEnd
| AG_NoMemory
| AO_DOSLib
| AN_StartMem
);
160 strcpy( bootName
, deviceName
);
161 strcat( bootName
, ":" );
163 kprintf("[DOS] Booting from device %s\n",bootName
);
165 /* Lock the boot device and add some default assigns */
166 lock
= Lock(bootName
, SHARED_LOCK
);
167 if (lock
) DOSBase
->dl_SYSLock
= DupLock(lock
);
169 if ((lock
!= NULL
) && (DOSBase
->dl_SYSLock
!= NULL
))
171 AssignLock("SYS", lock
);
175 Alert(AT_DeadEnd
| AG_BadParm
| AN_DOSLib
);
178 FreeMem( bootName
, bootNameLength
);
180 lock
= Lock("SYS:", SHARED_LOCK
);
188 Alert(AT_DeadEnd
| AG_BadParm
| AN_DOSLib
);
191 lock
= Lock("SYS:C", SHARED_LOCK
);
195 AssignLock("C", lock
);
198 lock
= Lock("SYS:S", SHARED_LOCK
);
202 AssignLock("S", lock
);
205 lock
= Lock("SYS:Libs", SHARED_LOCK
);
209 AssignLock("LIBS", lock
);
212 lock
= Lock("SYS:Devs", SHARED_LOCK
);
216 AssignLock("DEVS", lock
);
219 lock
= Lock("DEVS:Drivers", SHARED_LOCK
);
223 AssignLock("DRIVERS", lock
);
224 AssignAdd("LIBS", lock
); /* Let hidds in DRIVERS: directory be found by OpenLibrary */
227 lock
= Lock("SYS:L", SHARED_LOCK
);
231 AssignLock("L", lock
);
234 /* Late binding ENVARC: assign, only if used */
235 AssignLate("ENVARC", "SYS:Prefs/env-archive");
238 Retry to mount marked filesystems. If it fails again,
239 remove the BootNode from the list.
241 ForeachNode( &ExpansionBase
->MountList
, bootNode
)
243 if (bootNode
->bn_Flags
& BNF_RETRY
) {
246 "Retry node: %p, DevNode: %p, Name = %s\n",
247 bootNode
, bootNode
->bn_DeviceNode
,
248 deviceName
? deviceName
: "(null)"
250 if( !mount( (struct DeviceNode
*) bootNode
->bn_DeviceNode
,
251 (struct DosLibrary
*) DOSBase
))
258 /* We don't need expansion.library any more */
259 CloseLibrary( (struct Library
*) ExpansionBase
);
261 /* Initialize HIDDs */
262 init_hidds(SysBase
, (struct DosLibrary
*)DOSBase
);
264 /* We now call the system dependant boot - should never return. */
265 AROS_UFC3(void, boot
,
266 AROS_UFCA(STRPTR
, argString
, A0
),
267 AROS_UFCA(ULONG
, argSize
, D0
),
268 AROS_UFCA(struct ExecBase
*, SysBase
, A6
));
275 void DOSBoot(struct ExecBase
*SysBase
, struct DosLibrary
*DOSBase
)
277 struct TagItem bootprocess
[] =
279 { NP_Entry
, (IPTR
) intBoot
},
280 { NP_Name
, (IPTR
) "Boot Process" },
281 { NP_Input
, (IPTR
) NULL
},
282 { NP_Output
, (IPTR
) NULL
},
283 { NP_WindowPtr
, -1 },
284 { NP_CurrentDir
, (IPTR
) NULL
},
285 { NP_StackSize
, AROS_STACKSIZE
* 2},
286 { NP_Cli
, (IPTR
) 0 },
290 if( CreateNewProc( bootprocess
) == NULL
)
294 "CreateNewProc() failed with %ld\n",
295 ((struct Process
*) FindTask( NULL
))->pr_Result2
297 Alert( AT_DeadEnd
| AN_DOSLib
| AG_ProcCreate
);
301 BOOL
mount( struct DeviceNode
*dn
, struct DosLibrary
* DOSBase
)
305 if (!dn
->dn_Ext
.dn_AROS
.dn_Device
)
306 rc
= RunHandler(dn
, DOSBase
);
311 if (!AddDosEntry((struct DosList
*) dn
))
313 Alert(AT_DeadEnd
| AG_NoMemory
| AN_DOSLib
);
319 BOOL
isBootable( CONST_STRPTR deviceName
, struct DosLibrary
* DOSBase
)
325 struct InfoData info
;
327 #define STARTUP_SEQUENCE_FILE ":S/Startup-Sequence"
329 bufferLength
= strlen( deviceName
) + sizeof(STARTUP_SEQUENCE_FILE
) + 1;
331 if( (buffer
= AllocMem( bufferLength
, MEMF_ANY
) ) == NULL
)
333 Alert( AT_DeadEnd
| AG_NoMemory
| AN_DOSLib
);
336 strcpy( buffer
, deviceName
);
337 strcat( buffer
, STARTUP_SEQUENCE_FILE
);
339 D(bug("Trying to get a lock on '%s'\n", buffer
));
341 if( (lock
= Lock( buffer
, SHARED_LOCK
)) == 0 )
343 D(bug( "dosboot: could not lock '%s'\n", buffer
));
347 if( !Info( lock
, &info
) )
349 D(bug( "dosboot: could not get info on '%s'\n", buffer
));
353 if( info
.id_DiskType
!= ID_NO_DISK_PRESENT
)
359 if( buffer
!= NULL
) FreeMem( buffer
, bufferLength
);
360 if( lock
!= 0 ) UnLock( lock
);