haiku/headers/private/kernel/boot/vfs.h

189 lines
5.2 KiB
C
Raw Normal View History

/*
* Copyright 2003-2005, Axel Dörfler, axeld@pinc-software.de.
* Distributed under the terms of the MIT License.
*/
#ifndef KERNEL_BOOT_VFS_H
#define KERNEL_BOOT_VFS_H
#include <dirent.h>
#include <SupportDefs.h>
#include <util/DoublyLinkedList.h>
#include <boot/stage2_args.h>
#ifdef __cplusplus
struct file_map_run;
struct stat;
class PackageVolumeInfo;
class PackageVolumeState;
/** This is the base class for all VFS nodes */
class Node : public DoublyLinkedListLinkImpl<Node> {
public:
Node();
virtual ~Node();
virtual status_t Open(void **_cookie, int mode);
virtual status_t Close(void *cookie);
virtual ssize_t ReadAt(void *cookie, off_t pos, void *buffer,
size_t bufferSize) = 0;
virtual ssize_t WriteAt(void *cookie, off_t pos, const void *buffer,
size_t bufferSize) = 0;
virtual status_t ReadLink(char* buffer, size_t bufferSize);
virtual status_t GetName(char *nameBuffer, size_t bufferSize) const;
virtual status_t GetFileMap(struct file_map_run *runs, int32 *count);
virtual int32 Type() const;
virtual off_t Size() const;
virtual ino_t Inode() const;
void Stat(struct stat& stat);
status_t Acquire();
status_t Release();
protected:
int32 fRefCount;
};
typedef DoublyLinkedList<Node> NodeList;
typedef NodeList::Iterator NodeIterator;
class Directory : public Node {
public:
Directory();
virtual ssize_t ReadAt(void *cookie, off_t pos, void *buffer, size_t bufferSize);
virtual ssize_t WriteAt(void *cookie, off_t pos, const void *buffer, size_t bufferSize);
virtual int32 Type() const;
virtual Node* Lookup(const char* name, bool traverseLinks);
virtual Node* LookupDontTraverse(const char* name) = 0;
virtual status_t GetNextEntry(void *cookie, char *nameBuffer, size_t bufferSize) = 0;
virtual status_t GetNextNode(void *cookie, Node **_node) = 0;
virtual status_t Rewind(void *cookie) = 0;
virtual bool IsEmpty() = 0;
virtual status_t CreateFile(const char *name, mode_t permissions,
Node **_node);
};
/** The console based nodes don't need cookies for I/O, they
* also don't support to change the stream position.
* Live is simple in the boot loader :-)
*/
class ConsoleNode : public Node {
public:
ConsoleNode();
virtual ssize_t Read(void *buffer, size_t bufferSize);
virtual ssize_t Write(const void *buffer, size_t bufferSize);
virtual void ClearScreen() = 0;
virtual int32 Width() = 0;
virtual int32 Height() = 0;
virtual void SetCursor(int32 x, int32 y) = 0;
virtual void SetCursorVisible(bool visible) = 0;
virtual void SetColors(int32 foreground, int32 background) = 0;
};
[Sorry, couldn't split this one up any further.] * Images preloaded by the boot loader had to be modules to be of any use to the kernel. Extended the mechanism so that any images not accepted by the module code would later be tried to be added as drivers by the devfs. This is a little hacky ATM, since the devfs manages the drivers using a hash map keyed by the drivers inode ID, which those drivers obviously don't have. * The devfs emulates read_pages() using read(), if the device driver doesn't implement the former (all old-style drivers), thus making it possible to BFS, which uses the file cache which in turn requires read_pages(), on the device. write_pages() emulation is still missing. * Replaced the kernel_args::boot_disk structure by a KMessage, which can more flexibly be extended and deals more gracefully with arbitrarily-size data. The disk_identifier structure still exists, though. It is added as message field in cases where needed (non net boot). Moved the boot_drive_number field of the bios_ia32 platform specific args into the message. * Made the stage 1 PXE boot loader superfluous. Moved the relevant initialization code into the stage 2 loader, which can now be loaded directly via PXE. * The PXE boot loader does now download a boot tgz archive via TFTP. It does no longer use the RemoteDisk protocol (it could actually be removed from the boot loader). It also parses the DHCP options in the DHCPACK packet provided by PXE and extracts the root path to be mounted by the kernel. * Reorganized the boot volume search in the kernel (vfs_boot.cpp) and added support for network boot. In this case the net stack is initialized and the network interface the boot loader used is brought up and configured. Since NBD and RemoteDisk are our only options for net boot (and those aren't really configurable dynamically) ATM, the the boot device is found automatically by the disk device manager. Booting via PXE does work to some degree now. The most grievous problem is that loading certain drivers or kernel modules (or related activity) causes a reboot (likely a triple fault, though one wonders where our double fault handler is on vacation). Namely the keyboard and mouse input server add-ons need to be deactivated as well as the media server. A smaller problem is the net server, which apparently tries to (re-)configure the network interface we're using to boot, which obviously doesn't work out that well. So, if all this stuff is disabled Haiku does fully boot, when using the RemoteDisk protocol (not being able to use keyboard or mouse doesn't make this a particular fascinating experience, though ;-)). I had no luck with NBD -- it seemed to have protocol problems with the servers I tried. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21611 a95241bf-73f2-0310-859d-f6bbb57e9c96
2007-07-15 06:10:15 +04:00
class MemoryDisk : public Node {
public:
MemoryDisk(const uint8* data, size_t size, const char* name);
virtual ssize_t ReadAt(void* cookie, off_t pos, void* buffer,
size_t bufferSize);
virtual ssize_t WriteAt(void* cookie, off_t pos, const void* buffer,
size_t bufferSize);
virtual off_t Size() const;
virtual status_t GetName(char *nameBuffer, size_t bufferSize) const;
private:
const uint8* fData;
size_t fSize;
char fName[64];
};
class BootVolume {
public:
BootVolume();
~BootVolume();
status_t SetTo(Directory* rootDirectory,
PackageVolumeInfo* packageVolumeInfo
= NULL,
PackageVolumeState* packageVolumeState
= NULL);
2013-10-09 05:28:07 +04:00
void Unset();
2013-10-09 05:28:07 +04:00
bool IsValid() const
{ return fRootDirectory != NULL; }
2013-10-09 05:28:07 +04:00
Directory* RootDirectory() const
{ return fRootDirectory; }
2013-10-09 05:28:07 +04:00
Directory* SystemDirectory() const
{ return fSystemDirectory; }
2013-10-09 05:28:07 +04:00
bool IsPackaged() const
{ return fPackageVolumeInfo != NULL; }
PackageVolumeInfo* GetPackageVolumeInfo() const
{ return fPackageVolumeInfo; }
PackageVolumeState* GetPackageVolumeState() const
{ return fPackageVolumeState; }
private:
status_t _SetTo(Directory* rootDirectory,
PackageVolumeInfo* packageVolumeInfo,
PackageVolumeState* packageVolumeState);
int _OpenSystemPackage();
private:
Directory* fRootDirectory;
// root directory of the volume
Directory* fSystemDirectory;
// "system" directory of the volume; if packaged the root
// directory of the mounted packagefs
PackageVolumeInfo* fPackageVolumeInfo;
PackageVolumeState* fPackageVolumeState;
};
/* function prototypes */
extern status_t vfs_init(stage2_args *args);
extern status_t register_boot_file_system(BootVolume& bootVolume);
extern status_t get_boot_file_system(stage2_args* args,
BootVolume& _bootVolume);
extern status_t mount_file_systems(stage2_args *args);
extern int open_node(Node *node, int mode);
extern int open_from(Directory *directory, const char *path, int mode,
mode_t permissions = 0);
extern DIR* open_directory(Directory* baseDirectory, const char* path);
extern status_t get_stat(Directory* directory, const char* path,
struct stat& st);
extern Node* get_node_from(int fd);
// returns a reference
extern Directory* directory_from(DIR* dir);
// does not return a reference
extern status_t add_partitions_for(int fd, bool mountFileSystems, bool isBootDevice = false);
extern status_t add_partitions_for(Node *device, bool mountFileSystems, bool isBootDevice = false);
#endif /* __cplusplus */
#endif /* KERNEL_BOOT_VFS_H */