Example #1
0
status_t
device_node::_RegisterDynamic(device_node* previous)
{
	// If this is not a bus, we don't have to scan it
	if (find_attr(this, B_DEVICE_BUS, false, B_STRING_TYPE) == NULL)
		return B_OK;

	// If we're not being probed, we honour the B_FIND_CHILD_ON_DEMAND
	// requirements
	if (!IsProbed() && (fFlags & B_FIND_CHILD_ON_DEMAND) != 0
		&& !_AlwaysRegisterDynamic())
		return B_OK;

	KPath path;

	if ((fFlags & B_FIND_MULTIPLE_CHILDREN) == 0) {
		// find the one driver
		driver_module_info* bestDriver = NULL;
		float bestSupport = 0.0;
		void* cookie = NULL;

		while (_GetNextDriverPath(cookie, path) == B_OK) {
			_FindBestDriver(path.Path(), bestDriver, bestSupport, previous);
		}

		if (bestDriver != NULL) {
			TRACE(("  register best module \"%s\", support %f\n",
				bestDriver->info.name, bestSupport));
			if (bestDriver->register_device(this) == B_OK) {
				// There can only be one node of this driver
				// (usually only one at all, but there might be a new driver
				// "waiting" for its turn)
				device_node* child = FindChild(bestDriver->info.name);
				if (child != NULL) {
					child->fSupportsParent = bestSupport;
					if (previous != NULL) {
						previous->fFlags |= NODE_FLAG_OBSOLETE_DRIVER;
						previous->Release();
						child->fFlags |= NODE_FLAG_WAITING_FOR_DRIVER;
					}
				}
				// TODO: if this fails, we could try the second best driver,
				// and so on...
			}
			put_module(bestDriver->info.name);
		}
	} else {
		// register all drivers that match
		void* cookie = NULL;
		while (_GetNextDriverPath(cookie, path) == B_OK) {
			_RegisterPath(path.Path());
		}
	}

	return B_OK;
}
Example #2
0
status_t
PackageSettings::Load(dev_t mountPointDeviceID, ino_t mountPointNodeID,
	PackageFSMountType mountType)
{
	status_t error = fPackageItems.Init();
	if (error != B_OK)
		RETURN_ERROR(error);

	// get the mount point relative settings file path
	const char* settingsFilePath = mountType == PACKAGE_FS_MOUNT_TYPE_HOME
		? kUserSettingsGlobalDirectory "/packages"
			+ strlen(kUserConfigDirectory) + 1
		: kSystemSettingsDirectory "/packages" + strlen(kSystemDirectory) + 1;

	// get an absolute path
	KPath path;
	if (path.InitCheck() != B_OK)
		RETURN_ERROR(path.InitCheck());

	error = vfs_entry_ref_to_path(mountPointDeviceID, mountPointNodeID,
		NULL, true, path.LockBuffer(), path.BufferSize());
	if (error != B_OK)
		return error;
	path.UnlockBuffer();

	error = path.Append(settingsFilePath);
	if (error != B_OK)
		return error;

	// load the driver settings
	void* settingsHandle = load_driver_settings(path.Path());
	if (settingsHandle == NULL)
		return B_ENTRY_NOT_FOUND;
	CObjectDeleter<void, status_t> settingsDeleter(settingsHandle,
		&unload_driver_settings);

	const driver_settings* settings = get_driver_settings(settingsHandle);
	for (int i = 0; i < settings->parameter_count; i++) {
		const driver_parameter& parameter = settings->parameters[i];
		if (strcmp(parameter.name, "Package") != 0
			|| parameter.value_count < 1) {
			continue;
		}

		error = _AddPackageSettingsItem(parameter);
		// abort only in case of serious issues (memory shortage)
		if (error == B_NO_MEMORY)
			return error;
	}

	return B_OK;
}
Example #3
0
status_t
device_node::_AddPath(Stack<KPath*>& stack, const char* basePath,
	const char* subPath)
{
	KPath* path = new(std::nothrow) KPath;
	if (path == NULL)
		return B_NO_MEMORY;

	status_t status = path->SetTo(basePath);
	if (status == B_OK && subPath != NULL && subPath[0])
		status = path->Append(subPath);
	if (status == B_OK)
		status = stack.Push(path);

	TRACE(("  add path: \"%s\", %" B_PRId32 "\n", path->Path(), status));

	if (status != B_OK)
		delete path;

	return status;
}
Example #4
0
status_t
PackagesDirectory::_Init(struct vnode* vnode, struct stat& _st)
{
	fDirFD = vfs_open_vnode(vnode, O_RDONLY, true);

	if (fDirFD < 0) {
		ERROR("Failed to open packages directory \"%s\"\n", strerror(fDirFD));
		vfs_put_vnode(vnode);
		RETURN_ERROR(fDirFD);
	}
	// Our vnode reference has been transferred to the FD.

	// Is it a directory at all?
	struct stat& st = _st;
	if (fstat(fDirFD, &st) < 0)
		RETURN_ERROR(errno);

	fNodeRef.device = st.st_dev;
	fNodeRef.node = st.st_ino;

	// get a normalized path
	KPath normalizedPath;
	if (normalizedPath.InitCheck() != B_OK)
		RETURN_ERROR(normalizedPath.InitCheck());

	char* normalizedPathBuffer = normalizedPath.LockBuffer();
	status_t error = vfs_entry_ref_to_path(fNodeRef.device, fNodeRef.node, NULL,
		true, normalizedPathBuffer, normalizedPath.BufferSize());
	if (error != B_OK)
		RETURN_ERROR(error);

	fPath = strdup(normalizedPathBuffer);
	if (fPath == NULL)
		RETURN_ERROR(B_NO_MEMORY);

	return B_OK;
}
Example #5
0
// SetTo
status_t
KFileDiskDevice::SetTo(const char *filePath, const char *devicePath)
{
    // check params
    if (!filePath || strlen(filePath) > B_PATH_NAME_LENGTH
            || (devicePath && strlen(devicePath) > B_PATH_NAME_LENGTH)) {
        return B_BAD_VALUE;
    }
    // normalize the file path
    // (should actually not be necessary, since this method is only invoked
    // by the DDM, which has already normalized the path)
    KPath tmpFilePath;
    status_t error = tmpFilePath.SetTo(filePath, true);
    if (error != B_OK)
        return error;
    // check the file
    struct stat st;
    if (stat(filePath, &st) != 0)
        return errno;
    if (!S_ISREG(st.st_mode))
        return B_BAD_VALUE;
    // create the device, if requested
    KPath tmpDevicePath;
    if (!devicePath) {
        // no device path: we shall create a new device entry
        if (tmpDevicePath.InitCheck() != B_OK)
            return tmpDevicePath.InitCheck();
// TODO: Cleanup. The directory creation is done automatically by the devfs.
//		// make the file devices dir
//		if (mkdir(kFileDevicesDir, 0777) != 0) {
//			if (errno != B_FILE_EXISTS)
//				return errno;
//		}
        // make the directory
        status_t error = _GetDirectoryPath(ID(), &tmpDevicePath);
        if (error != B_OK)
            return error;
//		if (mkdir(tmpDevicePath.Path(), 0777) != 0)
//			return errno;
        // get the device path name
        error = tmpDevicePath.Append("raw");
        if (error != B_OK)
            return error;
        devicePath = tmpDevicePath.Path();
        // register the file as virtual disk device
        error = _RegisterDevice(filePath, devicePath);
        if (error != B_OK)
            return error;
    }
    error = set_string(fFilePath, filePath);
    if (error != B_OK)
        return error;

    error = KDiskDevice::SetTo(devicePath);
    if (error != B_OK)
        return error;

    // reset the B_DISK_DEVICE_IS_FILE flag -- KDiskDevice::SetTo() has cleared
    // it
    SetDeviceFlags(DeviceFlags() | B_DISK_DEVICE_IS_FILE);

    return B_OK;
}
Example #6
0
static int32
main2(void *unused)
{
	(void)(unused);

	TRACE("start of main2: initializing devices\n");

	boot_splash_init(sKernelArgs.boot_splash);

	commpage_init_post_cpus();

	TRACE("init ports\n");
	port_init(&sKernelArgs);

	TRACE("init user mutex\n");
	user_mutex_init();

	TRACE("Init modules\n");
	boot_splash_set_stage(BOOT_SPLASH_STAGE_1_INIT_MODULES);
	module_init_post_threads();

	// init userland debugging
	TRACE("Init Userland debugging\n");
	init_user_debug();

	// init the messaging service
	TRACE("Init Messaging Service\n");
	init_messaging_service();

	/* bootstrap all the filesystems */
	TRACE("Bootstrap file systems\n");
	boot_splash_set_stage(BOOT_SPLASH_STAGE_2_BOOTSTRAP_FS);
	vfs_bootstrap_file_systems();

	TRACE("Init Device Manager\n");
	boot_splash_set_stage(BOOT_SPLASH_STAGE_3_INIT_DEVICES);
	device_manager_init(&sKernelArgs);

	TRACE("Add preloaded old-style drivers\n");
	legacy_driver_add_preloaded(&sKernelArgs);

	int_init_post_device_manager(&sKernelArgs);

	TRACE("Mount boot file system\n");
	boot_splash_set_stage(BOOT_SPLASH_STAGE_4_MOUNT_BOOT_FS);
	vfs_mount_boot_file_system(&sKernelArgs);

#if ENABLE_SWAP_SUPPORT
	TRACE("swap_init_post_modules\n");
	swap_init_post_modules();
#endif

	// CPU specific modules may now be available
	boot_splash_set_stage(BOOT_SPLASH_STAGE_5_INIT_CPU_MODULES);
	cpu_init_post_modules(&sKernelArgs);

	TRACE("vm_init_post_modules\n");
	boot_splash_set_stage(BOOT_SPLASH_STAGE_6_INIT_VM_MODULES);
	vm_init_post_modules(&sKernelArgs);

	TRACE("debug_init_post_modules\n");
	debug_init_post_modules(&sKernelArgs);

	TRACE("device_manager_init_post_modules\n");
	device_manager_init_post_modules(&sKernelArgs);

	boot_splash_set_stage(BOOT_SPLASH_STAGE_7_RUN_BOOT_SCRIPT);
	boot_splash_uninit();
		// NOTE: We could introduce a syscall to draw more icons indicating
		// stages in the boot script itself. Then we should not free the image.
		// In that case we should copy it over to the kernel heap, so that we
		// can still free the kernel args.

	// The boot splash screen is the last user of the kernel args.
	// Note: don't confuse the kernel_args structure (which is never freed)
	// with the kernel args ranges it contains (and which are freed here).
	vm_free_kernel_args(&sKernelArgs);

	// start the init process
	{
		KPath bootScriptPath;
		status_t status = find_directory(B_BEOS_SYSTEM_DIRECTORY, gBootDevice,
			false, bootScriptPath.LockBuffer(), bootScriptPath.BufferSize());
		if (status != B_OK)
			dprintf("main2: find_directory() failed: %s\n", strerror(status));
		bootScriptPath.UnlockBuffer();
		status = bootScriptPath.Append("boot/Bootscript");
		if (status != B_OK) {
			dprintf("main2: constructing path to Bootscript failed: "
				"%s\n", strerror(status));
		}

		const char *args[] = { "/bin/sh", bootScriptPath.Path(), NULL };
		int32 argc = 2;
		thread_id thread;

		thread = load_image(argc, args, NULL);
		if (thread >= B_OK) {
			resume_thread(thread);
			TRACE("Bootscript started\n");
		} else
			dprintf("error starting \"%s\" error = %ld \n", args[0], thread);
	}

	return 0;
}
Example #7
0
void
vfs_mount_boot_file_system(kernel_args* args)
{
	PartitionStack partitions;
	status_t status = get_boot_partitions(args, partitions);
	if (status < B_OK) {
		panic("get_boot_partitions failed!");
	}
	if (partitions.IsEmpty()) {
		panic("did not find any boot partitions!");
	}

	KPartition* bootPartition;
	while (partitions.Pop(&bootPartition)) {
		KPath path;
		if (bootPartition->GetPath(&path) != B_OK)
			panic("could not get boot device!\n");

		const char* fsName = NULL;
		bool readOnly = false;
		if (strcmp(bootPartition->ContentType(), "ISO9660 File System") == 0) {
			fsName = "iso9660:write_overlay:attribute_overlay";
			readOnly = true;
		} else if (bootPartition->IsReadOnly()
			&& strcmp(bootPartition->ContentType(), "Be File System") == 0) {
			fsName = "bfs:write_overlay";
			readOnly = true;
		}

		TRACE(("trying to mount boot partition: %s\n", path.Path()));
		gBootDevice = _kern_mount("/boot", path.Path(), fsName, 0, NULL, 0);
		if (gBootDevice >= B_OK) {
			gReadOnlyBootDevice = readOnly;
			break;
		}
	}

	if (gBootDevice < B_OK)
		panic("could not mount boot device!\n");

	// create link for the name of the boot device

	fs_info info;
	if (_kern_read_fs_info(gBootDevice, &info) == B_OK) {
		char path[B_FILE_NAME_LENGTH + 1];
		snprintf(path, sizeof(path), "/%s", info.volume_name);

		_kern_create_symlink(-1, path, "/boot", 0);
	}

	// Do post-boot-volume module initialization. The module code wants to know
	// whether the module images the boot loader has pre-loaded are the same as
	// on the boot volume. That is the case when booting from hard disk or CD,
	// but not via network.
	int32 bootMethodType = args->boot_volume.GetInt32(BOOT_METHOD,
		BOOT_METHOD_DEFAULT);
	bool bootingFromBootLoaderVolume = bootMethodType == BOOT_METHOD_HARD_DISK
		|| bootMethodType == BOOT_METHOD_CD;
	module_init_post_boot_device(bootingFromBootLoaderVolume);

	file_cache_init_post_boot_device();

	// search for other disk systems
	KDiskDeviceManager *manager = KDiskDeviceManager::Default();
	manager->RescanDiskSystems();
	manager->StartMonitoring();
}
Example #8
0
status_t
device_node::_GetNextDriverPath(void*& cookie, KPath& _path)
{
	Stack<KPath*>* stack = NULL;

	if (cookie == NULL) {
		// find all paths and add them
		stack = new(std::nothrow) Stack<KPath*>();
		if (stack == NULL)
			return B_NO_MEMORY;

		StackDeleter<KPath*> stackDeleter(stack);

		bool generic = false;
		uint16 type = 0;
		uint16 subType = 0;
		uint16 interface = 0;
		if (get_attr_uint16(this, B_DEVICE_TYPE, &type, false) != B_OK
			|| get_attr_uint16(this, B_DEVICE_SUB_TYPE, &subType, false)
					!= B_OK)
			generic = true;

		get_attr_uint16(this, B_DEVICE_INTERFACE, &interface, false);

		// TODO: maybe make this extendible via settings file?
		switch (type) {
			case PCI_mass_storage:
				switch (subType) {
					case PCI_scsi:
						_AddPath(*stack, "busses", "scsi");
						_AddPath(*stack, "busses", "virtio");
						break;
					case PCI_ide:
						_AddPath(*stack, "busses", "ata");
						_AddPath(*stack, "busses", "ide");
						break;
					case PCI_sata:
						// TODO: check for ahci interface
						_AddPath(*stack, "busses", "scsi");
						_AddPath(*stack, "busses", "ata");
						_AddPath(*stack, "busses", "ide");
						break;
					default:
						_AddPath(*stack, "busses");
						break;
				}
				break;
			case PCI_serial_bus:
				switch (subType) {
					case PCI_firewire:
						_AddPath(*stack, "busses", "firewire");
						break;
					case PCI_usb:
						_AddPath(*stack, "busses", "usb");
						break;
					default:
						_AddPath(*stack, "busses");
						break;
				}
				break;
			case PCI_network:
				_AddPath(*stack, "drivers", "net");
				_AddPath(*stack, "busses", "virtio");
				break;
			case PCI_display:
				_AddPath(*stack, "drivers", "graphics");
				break;
			case PCI_multimedia:
				switch (subType) {
					case PCI_audio:
					case PCI_hd_audio:
						_AddPath(*stack, "drivers", "audio");
						break;
					case PCI_video:
						_AddPath(*stack, "drivers", "video");
						break;
					default:
						_AddPath(*stack, "drivers");
						break;
				}
				break;
			default:
				if (sRootNode == this) {
					_AddPath(*stack, "busses/pci");
					_AddPath(*stack, "bus_managers");
				} else if (!generic) {
					_AddPath(*stack, "busses", "virtio");
					_AddPath(*stack, "drivers");
				} else {
					// For generic drivers, we only allow busses when the
					// request is more specified
					if (sGenericContextPath != NULL
						&& (!strcmp(sGenericContextPath, "disk")
							|| !strcmp(sGenericContextPath, "ports")
							|| !strcmp(sGenericContextPath, "bus"))) {
						_AddPath(*stack, "busses");
					}
					_AddPath(*stack, "drivers", sGenericContextPath);
					_AddPath(*stack, "busses/scsi");
					_AddPath(*stack, "busses/random");
				}
				break;
		}

		stackDeleter.Detach();

		cookie = (void*)stack;
	} else
		stack = static_cast<Stack<KPath*>*>(cookie);

	KPath* path;
	if (stack->Pop(&path)) {
		_path.Adopt(*path);
		delete path;
		return B_OK;
	}

	delete stack;
	return B_ENTRY_NOT_FOUND;
}