partition.library: Move .bss data into the Library base.
[AROS.git] / rom / partition / fsloader.c
blobb881c813fc94ec6e397ce24191c777c7bfa3bbfa
1 /*
2 * This hook is called after dos.library wakes up.
3 * Its job is to load all queued filesystems and add to the system.
4 */
6 #include <aros/asmcall.h>
7 #include <aros/debug.h>
8 #include <exec/resident.h>
9 #include <resources/filesysres.h>
10 #include <proto/alib.h>
11 #include <proto/dos.h>
12 #include <proto/exec.h>
13 #include <proto/partition.h>
15 #include "partition_support.h"
16 #include "fsloader.h"
18 extern const UBYTE Partition_LibID[];
19 extern int Partition_End;
21 AROS_UFP3(static APTR, FSLoader_Init,
22 AROS_UFPA(void *, dummy1, D0),
23 AROS_UFPA(BPTR, dummy2, A0),
24 AROS_UFPA(struct ExecBase *, SysBase, A6));
27 * This ROMTag is placed in the file after the first one,
28 * provided by genmodule. rt_Skip of that ROMTag points to
29 * our one. This is specified in .conf * file (addromtag option).
30 * It needs to be in this way because disk-based library loader
31 * will find and initialize only the first ROMTag in the file.
32 * It must be the main library's ROMTag in order for disk-based library
33 * to work.
35 const struct Resident FSLoader_resident =
37 RTC_MATCHWORD,
38 (struct Resident *)&FSLoader_resident,
39 &Partition_End,
40 RTF_AFTERDOS,
42 NT_PROCESS,
43 -121, /* dos.library corresponds to -120 and is run manually. We can run next. */
44 "FSLoader",
45 &Partition_LibID[6], /* This points to partition.library version string */
46 FSLoader_Init
49 AROS_UFH3(static APTR, FSLoader_Init,
50 AROS_UFHA(void *, dummy1, D0),
51 AROS_UFHA(BPTR, dummy2, A0),
52 AROS_UFHA(struct ExecBase *, SysBase, A6))
54 AROS_USERFUNC_INIT
56 struct BootFileSystem *bfs, *bfs2;
57 struct PartitionBase_intern *PartitionBase = (struct PartitionBase_intern *)OpenLibrary("partition.library", 2);
59 if (!PartitionBase)
60 return NULL;
62 /* We should really have dos.library online now */
63 PartitionBase->pb_DOSBase = OpenLibrary("dos.library", 36);
64 D(bug("[FSLoader] DOSBase 0x%p\n", PartitionBase->pb_DOSBase));
66 if (PartitionBase->pb_DOSBase)
68 ForeachNodeSafe(&PartitionBase->bootList, bfs, bfs2)
71 * Unfortunately we have no way to process errors here.
72 * Well, let's hope that everything will be okay.
74 D(bug("[FSLoader] Loading %s...\n", bfs->ln.ln_Name));
76 AddFS(&PartitionBase->partbase.lib, bfs->handle);
77 bfs->handle->handler->freeFileSystem(bfs->handle);
78 FreeMem(bfs, sizeof(struct BootFileSystem));
81 /* All nodes are already freed, reinitialize the list */
82 NewList(&PartitionBase->bootList);
85 CloseLibrary(&PartitionBase->partbase.lib);
86 return 0;
88 AROS_USERFUNC_EXIT
91 static struct FileSysEntry *FindResidentFS(struct FileSysResource *fsr, ULONG dostype, ULONG version)
93 struct FileSysEntry *fsrnode;
95 ForeachNode(&fsr->fsr_FileSysEntries, fsrnode)
97 if (fsrnode->fse_DosType == dostype && fsrnode->fse_Version >= version)
98 return fsrnode;
101 return NULL;
104 ULONG AddFS(struct Library *PartitionBase, struct FileSysHandle *fs)
106 struct DosLibrary *DOSBase = (struct DosLibrary *)((struct PartitionBase_intern *)PartitionBase)->pb_DOSBase;
107 struct FileSysResource *fsr;
108 struct FileSysEntry *fsrnode;
109 ULONG dostype;
110 ULONG version;
112 fsr = OpenResource("FileSystem.resource");
113 if (!fsr)
114 return ERROR_INVALID_RESIDENT_LIBRARY;
116 GetFileSystemAttrs(&fs->ln, FST_ID, &dostype, FST_VERSION, &version, TAG_DONE);
119 * First we want to check if we already have this filesystem in the resource.
120 * Unfortunately the resource doesn't have any locking, so we have to use
121 * Forbid()/Permit() pair. In order not to hold it for a while, we repeat
122 * the check below after loading the handler (to eliminate race condition
123 * when someone loads newer version of the filesystem that we are loading
124 * at the moment.
126 Forbid();
127 fsrnode = FindResidentFS(fsr, dostype, version);
128 Permit();
130 if (fsrnode)
131 return ERROR_OBJECT_EXISTS;
133 fsrnode = AllocVec(sizeof(struct FileSysEntry), MEMF_PUBLIC | MEMF_CLEAR);
134 if (!fsrnode)
135 return ERROR_NO_FREE_STORE;
137 GetFileSystemAttrs(&fs->ln, FST_FSENTRY, fsrnode, TAG_DONE);
138 fsrnode->fse_SegList = LoadFileSystem(&fs->ln);
141 * FIXME: Name of the filesystem is currently not filled in.
142 * I left it this way just because this was originally done in m68k-specific hack.
143 * May be it should be added?
146 if (fsrnode->fse_SegList)
148 struct FileSysEntry *dup;
151 * Repeat checking, and insert the filesystem only if still not found.
152 * If found, unload our seglist and return error.
153 * This really sucks but nothing can be done with it. Even if we implement
154 * a global semaphore on the resource original m68k software won't know
155 * about it.
157 Forbid();
159 dup = FindResidentFS(fsr, dostype, version);
160 if (!dup)
162 * Entries in the list are not sorted by priority.
163 * Adding to head makes them sorted by version.
165 AddHead(&fsr->fsr_FileSysEntries, &fsrnode->fse_Node);
167 Permit();
169 if (dup)
171 UnLoadSeg(fsrnode->fse_SegList);
172 FreeVec(fsrnode);
174 return ERROR_OBJECT_EXISTS;
177 return 0;
180 /* InternalLoadSeg() will leave its error code in IoErr() */
181 return IoErr();