2 Copyright © 1995-2006, The AROS Development Team. All rights reserved.
5 Desc: Start up the ol' Dos boot process.
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>
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>
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
)
49 struct ExpansionBase
*ExpansionBase
= NULL
;
50 struct DosLibrary
*DOSBase
= NULL
;
51 struct BootNode
*bootNode
= NULL
;
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 );
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
)
82 "Node: %p, DevNode: %p, Name = %s\n",
83 bootNode
, bootNode
->bn_DeviceNode
,
84 deviceName
? deviceName
: "(null)"
86 #if (AROS_FLAVOUR & AROS_FLAVOUR_EMULATION)
87 AddDosEntry( (struct DosList
*) bootNode
->bn_DeviceNode
);
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.
94 if( !mount( (struct DeviceNode
*) bootNode
->bn_DeviceNode
,
95 (struct DosLibrary
*) DOSBase
))
102 /**** Try to find a bootable filesystem ****************************************/
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
114 if( isBootable( deviceName
, (struct DosLibrary
*)DOSBase
) )
120 kprintf( "No bootable disk was found.\n" );
121 kprintf( "Please insert a bootable disk in any drive.\n" );
124 for( second
= 5; second
> 0; second
-- ) {
125 kprintf( "Retrying in %d seconds...\n", second
);
129 kprintf( "Retrying in 5 seconds...\n" );
133 /* FIXME: Should there be a prompt instead of a automatic retry? */
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
);
167 Alert(AT_DeadEnd
| AG_BadParm
| AN_DOSLib
);
170 FreeMem( bootName
, bootNameLength
);
172 lock
= Lock("SYS:", SHARED_LOCK
);
180 Alert(AT_DeadEnd
| AG_BadParm
| AN_DOSLib
);
183 lock
= Lock("SYS:C", SHARED_LOCK
);
187 AssignLock("C", lock
);
190 lock
= Lock("SYS:S", SHARED_LOCK
);
194 AssignLock("S", lock
);
197 lock
= Lock("SYS:Libs", SHARED_LOCK
);
201 AssignLock("LIBS", lock
);
204 lock
= Lock("SYS:Devs", SHARED_LOCK
);
208 AssignLock("DEVS", lock
);
211 lock
= Lock("DEVS:Drivers", SHARED_LOCK
);
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
));
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 },
250 if( CreateNewProc( bootprocess
) == NULL
)
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();
270 iofs
= (struct IOFileSys
*)CreateIORequest(mp
,
271 sizeof(struct IOFileSys
));
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 !!! */
289 DeleteIORequest((struct IORequest
*)iofs
);
293 Alert(AT_DeadEnd
| AG_NoMemory
| AN_DOSLib
);
300 Alert(AT_DeadEnd
| AG_NoMemory
| AN_DOSLib
);
306 BOOL
isBootable( CONST_STRPTR deviceName
, struct DosLibrary
* DOSBase
)
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
));
332 if( !Info( lock
, &info
) )
334 D(bug( "dosboot: could not get info on '%s'\n", buffer
));
338 if( info
.id_DiskType
!= ID_NO_DISK_PRESENT
)
344 if( buffer
!= NULL
) FreeMem( buffer
, bufferLength
);
345 if( lock
!= 0 ) UnLock( lock
);