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.
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)
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
);
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.
98 if( !mount( (struct DeviceNode
*) bootNode
->bn_DeviceNode
,
99 (struct DosLibrary
*) DOSBase
))
106 /**** Try to find a bootable filesystem ****************************************/
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
118 if( isBootable( deviceName
, (struct DosLibrary
*)DOSBase
) )
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
);
132 /* FIXME: Should there be a prompt instead of a automatic retry? */
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
);
158 AssignLock("SYS", lock
);
162 Alert(AT_DeadEnd
| AG_BadParm
| AN_DOSLib
);
165 FreeMem( bootName
, bootNameLength
);
166 lock
= Lock("SYS:", SHARED_LOCK
);
174 Alert(AT_DeadEnd
| AG_BadParm
| AN_DOSLib
);
177 lock
= Lock("SYS:C", SHARED_LOCK
);
181 AssignLock("C", lock
);
184 lock
= Lock("SYS:S", SHARED_LOCK
);
188 AssignLock("S", lock
);
191 lock
= Lock("SYS:Libs", SHARED_LOCK
);
195 AssignLock("LIBS", lock
);
198 lock
= Lock("SYS:Devs", SHARED_LOCK
);
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
));
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 },
236 if( CreateNewProc( bootprocess
) == NULL
)
240 "CreateNewProc() failed with %ld\n",
241 ((struct Process
*) FindTask( NULL
))->pr_Result2
243 Alert( AT_DeadEnd
| AN_DOSLib
| AG_ProcCreate
);
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();
262 iofs
= (struct IOFileSys
*)CreateIORequest(mp
,
263 sizeof(struct IOFileSys
));
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))
274 dn
->dn_Unit
= iofs
->IOFS
.io_Unit
;
275 dn
->dn_Device
= iofs
->IOFS
.io_Device
;
276 /* Do not close filesys !!! */
281 DeleteIORequest((struct IORequest
*)iofs
);
285 Alert(AT_DeadEnd
| AG_NoMemory
| AN_DOSLib
);
292 Alert(AT_DeadEnd
| AG_NoMemory
| AN_DOSLib
);
302 #define SysBase (DOSBase->dl_SysBase)
304 BOOL
isBootable( CONST_STRPTR deviceName
, struct DosLibrary
* DOSBase
)
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
));
328 if( !Info( lock
, &info
) )
330 D(bug( "dosboot: could not get info on '%s'\n", buffer
));
334 if( info
.id_DiskType
!= ID_NO_DISK_PRESENT
)
340 if( buffer
!= NULL
) FreeMem( buffer
, bufferLength
);
341 if( lock
!= 0 ) UnLock( lock
);