2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
12 #include <aros/debug.h>
13 #include <exec/alerts.h>
14 #include <aros/asmcall.h>
15 #include <aros/bootloader.h>
16 #include <exec/lists.h>
17 #include <exec/memory.h>
18 #include <exec/resident.h>
19 #include <exec/types.h>
20 #include <libraries/configvars.h>
21 #include <libraries/expansion.h>
22 #include <libraries/expansionbase.h>
23 #include <libraries/partition.h>
24 #include <utility/tagitem.h>
25 #include <devices/bootblock.h>
26 #include <devices/timer.h>
27 #include <dos/dosextens.h>
28 #include <resources/filesysres.h>
30 #include <proto/exec.h>
31 #include <proto/expansion.h>
32 #include <proto/partition.h>
33 #include <proto/bootloader.h>
35 #include LC_LIBDEFS_FILE
37 #include "dosboot_intern.h"
40 /* Delay just like Dos/Delay(), ticks are
41 * in 1/50th of a second.
43 static void bootDelay(ULONG timeout
)
45 struct timerequest timerio
;
46 struct MsgPort timermp
;
48 memset(&timermp
, 0, sizeof(timermp
));
50 timermp
.mp_Node
.ln_Type
= NT_MSGPORT
;
51 timermp
.mp_Flags
= PA_SIGNAL
;
52 timermp
.mp_SigBit
= SIGB_SINGLE
;
53 timermp
.mp_SigTask
= FindTask(NULL
);
54 NEWLIST(&timermp
.mp_MsgList
);
56 timerio
.tr_node
.io_Message
.mn_Node
.ln_Type
= NT_REPLYMSG
;
57 timerio
.tr_node
.io_Message
.mn_ReplyPort
= &timermp
;
58 timerio
.tr_node
.io_Message
.mn_Length
= sizeof(timermp
);
60 if (OpenDevice("timer.device", UNIT_VBLANK
, (struct IORequest
*)&timerio
, 0) != 0) {
61 D(bug("dosboot: Can't open timer.device unit 0\n"));
65 timerio
.tr_node
.io_Command
= TR_ADDREQUEST
;
66 timerio
.tr_time
.tv_secs
= timeout
/ TICKS_PER_SECOND
;
67 timerio
.tr_time
.tv_micro
= 1000000UL / TICKS_PER_SECOND
* (timeout
% TICKS_PER_SECOND
);
69 SetSignal(0, SIGF_SINGLE
);
71 DoIO(&timerio
.tr_node
);
73 CloseDevice((struct IORequest
*)&timerio
);
76 int dosboot_Init(LIBBASETYPEPTR LIBBASE
)
78 struct ExpansionBase
*ExpansionBase
;
80 BOOL WantBootMenu
= FALSE
;
83 LIBBASE
->delayTicks
= 50;
85 D(bug("dosboot_Init: GO GO GO!\n"));
87 ExpansionBase
= (APTR
)OpenLibrary("expansion.library", 0);
89 D(bug("[Strap] ExpansionBase 0x%p\n", ExpansionBase
));
90 if( ExpansionBase
== NULL
)
92 D(bug( "Could not open expansion.library, something's wrong!\n"));
93 Alert(AT_DeadEnd
| AG_OpenLib
| AN_BootStrap
| AO_ExpansionLib
);
96 ExpansionBase
->Flags
|= EBF_SILENTSTART
;
98 LIBBASE
->bm_ExpansionBase
= ExpansionBase
;
101 * Search the kernel parameters for the bootdelay=%d string. It determines the
104 if ((BootLoaderBase
= OpenResource("bootloader.resource")) != NULL
)
106 struct List
*args
= GetBootInfo(BL_Args
);
112 ForeachNode(args
, node
)
114 if (0 == strncmp(node
->ln_Name
, "bootdelay=", 10))
116 ULONG delay
= atoi(&node
->ln_Name
[10]);
118 D(bug("[Boot] delay of %d seconds requested.", delay
));
120 bootDelay(delay
* 50);
122 else if (0 == stricmp(node
->ln_Name
, "bootmenu"))
124 D(bug("[BootMenu] bootmenu_Init: Forced with bootloader argument\n"));
128 * TODO: The following two flags should have corresponding switches
129 * in 'display options' page.
131 else if (0 == stricmp(node
->ln_Name
, "nomonitors"))
133 LIBBASE
->db_BootFlags
|= BF_NO_DISPLAY_DRIVERS
;
135 else if (0 == stricmp(node
->ln_Name
, "nocomposition"))
137 LIBBASE
->db_BootFlags
|= BF_NO_COMPOSITION
;
139 else if (0 == strnicmp(node
->ln_Name
, "bootdevice=", 11))
141 LIBBASE
->db_BootDevice
= &node
->ln_Name
[11];
142 selectBootDevice(LIBBASE
);
144 else if (0 == stricmp(node
->ln_Name
, "econsole"))
146 LIBBASE
->db_BootFlags
|= BF_EMERGENCY_CONSOLE
;
147 D(bug("[Boot] Emergency console selected\n"));
150 ExpansionBase
->eb_BootFlags
= LIBBASE
->db_BootFlags
;
154 /* Scan for any additional partition volumes */
155 dosboot_BootScan(LIBBASE
);
157 /* Show the boot menu if needed */
158 bootmenu_Init(LIBBASE
, WantBootMenu
);
160 /* We want to be able to find ourselves in RTF_AFTERDOS */
161 LIBBASE
->bm_Screen
= NULL
;
162 AddResource(&LIBBASE
->db_Node
);
164 /* Attempt to boot until we succeed */
167 dosboot_BootStrap(LIBBASE
);
169 if (!LIBBASE
->bm_Screen
)
170 LIBBASE
->bm_Screen
= NoBootMediaScreen(LIBBASE
);
172 D(bug("No bootable disk was found.\n"));
173 D(bug("Please insert a bootable disk in any drive.\n"));
174 D(bug("Retrying in 3 seconds...\n"));
176 for (t
= 0; t
< 150; t
+= LIBBASE
->delayTicks
)
178 bootDelay(LIBBASE
->delayTicks
);
180 if (LIBBASE
->bm_Screen
)
181 anim_Animate(LIBBASE
->bm_Screen
, LIBBASE
);
185 /* We never get here */
189 ADD2INITLIB(dosboot_Init
, 1)