2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
5 ROMTag scanner. Adapted from the original i386-native to become
9 #include <exec/types.h>
10 #include <exec/lists.h>
11 #include <exec/nodes.h>
12 #include <exec/memory.h>
13 #include <exec/resident.h>
14 #include <proto/exec.h>
16 #include "exec_intern.h"
19 #include <aros/debug.h>
23 * This function scans kernel for existing Resident modules. If two modules
24 * with the same name are found, the one with higher version or priority
27 * After building list of kernel modules, the KickTagPtr and KickMemPtr are
28 * checksummed. If checksum is proper and all memory pointed in KickMemPtr
29 * may be allocated, then all modules from KickTagPtr are added to RT list
31 * Afterwards the proper RomTagList is created (see InitCode() for details)
32 * and memory after list and nodes is freed.
34 * The array ranges gives a [ start, end ] pair to scan, with an entry of
35 * -1 used to break the loop.
41 struct Resident
*module
;
44 ULONG
**AROS_SLIB_ENTRY(RomTagScanner
,Exec
)
46 struct ExecBase
*SysBase
,
50 struct List rtList
; /* List of modules */
52 UWORD
*ptr
; /* Start looking here */
54 struct Resident
*res
; /* module found */
62 /* Look in whole kernel for resident modules */
63 while (*ranges
!= (UWORD
*)~0)
68 D(bug("RomTagScanner: Start = %p, End = %p\n", ptr
, end
));
71 res
= (struct Resident
*)ptr
;
73 /* Do we have RTC_MATCHWORD and rt_MatchTag*/
74 if ( res
->rt_MatchWord
== RTC_MATCHWORD
75 && res
->rt_MatchTag
== res
78 /* Yes, it is Resident module */
81 /* Check if there is module with such name already */
82 node
= (struct rt_node
*)FindName(&rtList
, res
->rt_Name
);
86 Rules for replacing modules:
87 1. Higher version always wins.
88 2. If the versions are equal, then lower priority
93 node
->module
->rt_Version
< res
->rt_Version
96 node
->module
->rt_Version
== res
->rt_Version
97 && node
->node
.ln_Pri
<= res
->rt_Pri
101 node
->node
.ln_Pri
= res
->rt_Pri
;
104 /* Have to re-add the node at it's new position. */
105 Remove((struct Node
*)node
);
106 Enqueue(&rtList
, (struct Node
*)node
);
111 /* New module. Allocate some memory for it */
112 node
= (struct rt_node
*)
113 AllocMem(sizeof(struct rt_node
),MEMF_PUBLIC
|MEMF_CLEAR
);
117 node
->node
.ln_Name
= res
->rt_Name
;
118 node
->node
.ln_Pri
= res
->rt_Pri
;
121 Enqueue(&rtList
,(struct Node
*)node
);
125 /* Get address of EndOfResident from RomTag but only when
126 * it's higher then present one - this avoids strange locks
127 * when not all modules have Resident structure in .text
129 ptr
= ((ULONG
)res
->rt_EndSkip
> (ULONG
)ptr
)
130 ? (UWORD
*)res
->rt_EndSkip
- 2
133 if ((ULONG
)ptr
& 0x01)
134 ptr
= (UWORD
*)((ULONG
)ptr
+1);
137 /* Get next address... */
139 } while (ptr
< (UWORD
*)end
);
143 * By now we have valid (and sorted) list of kernel resident modules.
145 * Now, we will have to analyze used-defined RomTags (via KickTagPtr and
148 #warning TODO: Implement external modules!
151 * Everything is done now. Allocate buffer for normal RomTag and convert
155 ListLength(&rtList
,i
); /* Get length of the list */
157 RomTag
= AllocMem((i
+1)*4,MEMF_PUBLIC
| MEMF_CLEAR
);
159 kprintf("Resident modules (addr: pri version name):\n");
167 n
= (struct rt_node
*)RemHead(&rtList
);
168 kprintf("+ 0x%08.8lx: %3d %3d \"%s\"\n",
171 n
->module
->rt_Version
,
173 RomTag
[j
] = (ULONG
*)n
->module
;
175 FreeMem(n
, sizeof(struct rt_node
));