* Changed bootman.S to use the BIOS provided drive to stage load itself, as well
as when the boot menu entry has a 0 BIOS drive. This allows the boot loader to be installed on any drive. * Implemented BootDrive class, and changed LegacyBootMenu the way it should work now. Installing the boot menu should now work again, and the first time while installing Haiku. * Removed MakeArray.cpp - we already have such a tool in our repository. * Build BootLoader.h automatically during the build process - the only disadvantage is that you can only build it on x86 now (but other systems don't use this boot loader, anyway). * In general, the BootManager is prepared to handle different kinds of boot menus; one only needs to write a class BootMenu implementation for this to work - and have the possibility to choose between different menus, if there are more than one per platform/partitioning system. * Renamed quite a few methods. * Automatic whitespace cleanup. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@40149 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -0,0 +1,98 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2011, Axel Dörfler, [email protected].
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "BootDrive.h"
|
||||||
|
|
||||||
|
#include <DiskDevice.h>
|
||||||
|
#include <DiskDeviceRoster.h>
|
||||||
|
#include <Volume.h>
|
||||||
|
#include <VolumeRoster.h>
|
||||||
|
|
||||||
|
|
||||||
|
BootDrive::BootDrive(const char* path)
|
||||||
|
:
|
||||||
|
fPath(path)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BootDrive::~BootDrive()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BootMenu*
|
||||||
|
BootDrive::InstalledMenu(const BootMenuList& menus) const
|
||||||
|
{
|
||||||
|
for (int32 i = 0; i < menus.CountItems(); i++) {
|
||||||
|
BootMenu* menu = menus.ItemAt(i);
|
||||||
|
if (menu->IsInstalled(*this))
|
||||||
|
return menu;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
BootDrive::CanMenuBeInstalled(const BootMenuList& menus) const
|
||||||
|
{
|
||||||
|
status_t status = B_ERROR;
|
||||||
|
|
||||||
|
for (int32 i = 0; i < menus.CountItems(); i++) {
|
||||||
|
status = menus.ItemAt(i)->CanBeInstalled(*this);
|
||||||
|
if (status == B_OK)
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*! Adds all boot menus from the list \a from that support the drive to \a to.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
BootDrive::AddSupportedMenus(const BootMenuList& from, BootMenuList& to)
|
||||||
|
{
|
||||||
|
for (int32 i = 0; i < from.CountItems(); i++) {
|
||||||
|
BootMenu* menu = from.ItemAt(i);
|
||||||
|
if (menu->CanBeInstalled(*this))
|
||||||
|
to.AddItem(menu);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const char*
|
||||||
|
BootDrive::Path() const
|
||||||
|
{
|
||||||
|
return fPath.Path();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
BootDrive::IsBootDrive() const
|
||||||
|
{
|
||||||
|
BVolumeRoster volumeRoster;
|
||||||
|
BVolume volume;
|
||||||
|
if (volumeRoster.GetBootVolume(&volume) != B_OK)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
BDiskDeviceRoster roster;
|
||||||
|
BDiskDevice device;
|
||||||
|
if (roster.FindPartitionByVolume(volume, &device, NULL) == B_OK) {
|
||||||
|
BPath path;
|
||||||
|
if (device.GetPath(&path) == B_OK && path == fPath)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
BootDrive::GetDiskDevice(BDiskDevice& device) const
|
||||||
|
{
|
||||||
|
BDiskDeviceRoster roster;
|
||||||
|
return roster.GetDeviceForPath(fPath.Path(), &device);
|
||||||
|
}
|
||||||
@@ -6,21 +6,30 @@
|
|||||||
#define BOOT_DRIVE_H
|
#define BOOT_DRIVE_H
|
||||||
|
|
||||||
|
|
||||||
#include <File.h>
|
#include <Path.h>
|
||||||
|
|
||||||
|
#include "BootMenu.h"
|
||||||
|
|
||||||
|
|
||||||
|
class BDiskDevice;
|
||||||
|
|
||||||
|
|
||||||
class BootDrive {
|
class BootDrive {
|
||||||
public:
|
public:
|
||||||
BootDrive();
|
BootDrive(const char* path);
|
||||||
virtual ~BootDrive();
|
virtual ~BootDrive();
|
||||||
|
|
||||||
bool IsBootMenuInstalled() const;
|
BootMenu* InstalledMenu(
|
||||||
bool CanBootMenuBeInstalled() const;
|
const BootMenuList& menus) const;
|
||||||
|
status_t CanMenuBeInstalled(
|
||||||
|
const BootMenuList& menus) const;
|
||||||
|
void AddSupportedMenus(const BootMenuList& from,
|
||||||
|
BootMenuList& to);
|
||||||
|
|
||||||
|
const char* Path() const;
|
||||||
bool IsBootDrive() const;
|
bool IsBootDrive() const;
|
||||||
|
|
||||||
status_t GetStream(BPositionIO* stream);
|
status_t GetDiskDevice(BDiskDevice& device) const;
|
||||||
status_t GetBIOSDrive(uint8* drive);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BPath fPath;
|
BPath fPath;
|
||||||
|
|||||||
@@ -1,71 +0,0 @@
|
|||||||
// THIS FILE WAS GENERATED WITH
|
|
||||||
// ./make_array kBootLoader bootman.bin
|
|
||||||
|
|
||||||
static const uint8 kBootLoader[] = {
|
|
||||||
0xb8, 0xc0, 0x07, 0x8e, 0xd8, 0x8e, 0xc0, 0x8e, 0xd0, 0xbc, 0xf3, 0xff, 0x89, 0xe5, 0xfc, 0xb4,
|
|
||||||
0x06, 0x30, 0xc0, 0xb7, 0x0f, 0x31, 0xc9, 0xba, 0x4f, 0x18, 0xcd, 0x10, 0xe8, 0x63, 0x00, 0xb7,
|
|
||||||
0x00, 0xba, 0x1f, 0x01, 0x89, 0x56, 0x08, 0xbe, 0xa9, 0x00, 0xb3, 0x0f, 0xe8, 0x2f, 0x00, 0xba,
|
|
||||||
0x1b, 0x17, 0x89, 0x56, 0x08, 0xb3, 0x07, 0xbe, 0xbc, 0x00, 0xe8, 0x21, 0x00, 0xb4, 0x42, 0xb2,
|
|
||||||
0x80, 0xbe, 0x99, 0x00, 0xcd, 0x13, 0x72, 0x03, 0xe9, 0xb5, 0x01, 0xe8, 0x43, 0x00, 0xbe, 0xd7,
|
|
||||||
0x00, 0xb3, 0x04, 0xe8, 0x08, 0x00, 0xb4, 0x00, 0xcd, 0x16, 0xb2, 0x80, 0xcd, 0x19, 0x50, 0x53,
|
|
||||||
0x51, 0x52, 0x30, 0xff, 0xe9, 0x11, 0x00, 0x8b, 0x56, 0x08, 0xb4, 0x02, 0xcd, 0x10, 0xfe, 0x46,
|
|
||||||
0x08, 0xb9, 0x01, 0x00, 0xb4, 0x09, 0xcd, 0x10, 0xac, 0x3c, 0x00, 0x75, 0xea, 0x5a, 0x59, 0x5b,
|
|
||||||
0x58, 0xc3, 0xb4, 0x03, 0xcd, 0x10, 0x89, 0x4e, 0x0a, 0xb4, 0x01, 0xb9, 0x00, 0x20, 0xcd, 0x10,
|
|
||||||
0xc3, 0x8b, 0x4e, 0x0a, 0xb4, 0x01, 0xcd, 0x10, 0xc3, 0x10, 0x00, 0x03, 0x00, 0x00, 0x02, 0xc0,
|
|
||||||
0x07, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x61, 0x69, 0x6b, 0x75, 0x20, 0x42,
|
|
||||||
0x6f, 0x6f, 0x74, 0x20, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x00, 0x53, 0x65, 0x6c, 0x65,
|
|
||||||
0x63, 0x74, 0x20, 0x61, 0x6e, 0x20, 0x4f, 0x53, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x74, 0x68,
|
|
||||||
0x65, 0x20, 0x6d, 0x65, 0x6e, 0x75, 0x00, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x20, 0x6c, 0x6f, 0x61,
|
|
||||||
0x64, 0x69, 0x6e, 0x67, 0x20, 0x73, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x21, 0x00, 0x42, 0x42,
|
|
||||||
0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
|
|
||||||
0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
|
|
||||||
0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
|
|
||||||
0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
|
|
||||||
0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
|
|
||||||
0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
|
|
||||||
0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
|
|
||||||
0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
|
|
||||||
0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
|
|
||||||
0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
|
|
||||||
0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
|
|
||||||
0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
|
|
||||||
0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0xaa,
|
|
||||||
0xa1, 0x17, 0x04, 0x89, 0x46, 0x00, 0xb8, 0x13, 0x00, 0xf7, 0x26, 0x19, 0x04, 0x89, 0xd3, 0x50,
|
|
||||||
0xb4, 0x00, 0xcd, 0x1a, 0x58, 0x01, 0xd0, 0x11, 0xcb, 0x89, 0x46, 0x04, 0x89, 0x5e, 0x06, 0xa0,
|
|
||||||
0x15, 0x04, 0xd0, 0xe8, 0xb3, 0x0c, 0x28, 0xc3, 0x88, 0x5e, 0x02, 0xb4, 0x02, 0xcd, 0x16, 0x24,
|
|
||||||
0x08, 0x74, 0x06, 0xc7, 0x06, 0x19, 0x04, 0xff, 0xff, 0xe8, 0x64, 0x00, 0x81, 0x3e, 0x19, 0x04,
|
|
||||||
0xff, 0xff, 0x74, 0x25, 0xb4, 0x01, 0xcd, 0x16, 0x75, 0x1f, 0xe8, 0x05, 0x00, 0x73, 0xf5, 0xe9,
|
|
||||||
0xa6, 0x00, 0xb4, 0x00, 0xcd, 0x1a, 0x3b, 0x4e, 0x06, 0x72, 0x07, 0x77, 0x07, 0x3b, 0x56, 0x04,
|
|
||||||
0x77, 0x02, 0xf8, 0xc3, 0xf9, 0xc3, 0xe8, 0x37, 0x00, 0xb4, 0x00, 0xcd, 0x16, 0x80, 0xfc, 0x50,
|
|
||||||
0x74, 0x0d, 0x80, 0xfc, 0x48, 0x74, 0x19, 0x80, 0xfc, 0x1c, 0x75, 0xed, 0xe9, 0x79, 0x00, 0x8b,
|
|
||||||
0x46, 0x00, 0x40, 0x3b, 0x06, 0x15, 0x04, 0x75, 0x02, 0x31, 0xc0, 0x89, 0x46, 0x00, 0xeb, 0xd6,
|
|
||||||
0x8b, 0x46, 0x00, 0x09, 0xc0, 0x75, 0x03, 0xa1, 0x15, 0x04, 0x48, 0x89, 0x46, 0x00, 0xeb, 0xc6,
|
|
||||||
0x8a, 0x46, 0x02, 0x88, 0x46, 0x09, 0xbe, 0x1b, 0x04, 0x31, 0xc9, 0xac, 0x04, 0x03, 0xd0, 0xe8,
|
|
||||||
0xb2, 0x28, 0x28, 0xc2, 0x88, 0x56, 0x08, 0xb0, 0x10, 0xe8, 0x30, 0x00, 0xfe, 0x46, 0x08, 0x89,
|
|
||||||
0xcf, 0x81, 0xe7, 0x03, 0x00, 0x8a, 0x9d, 0xda, 0x03, 0x3b, 0x4e, 0x00, 0x75, 0x03, 0x80, 0xf3,
|
|
||||||
0x08, 0xe8, 0xb6, 0x00, 0x81, 0xc6, 0x09, 0x00, 0x80, 0x46, 0x08, 0x01, 0xb0, 0x11, 0xe8, 0x0b,
|
|
||||||
0x00, 0xfe, 0x46, 0x09, 0x41, 0x3b, 0x0e, 0x15, 0x04, 0x75, 0xc0, 0xc3, 0x3b, 0x4e, 0x00, 0x74,
|
|
||||||
0x02, 0xb0, 0x20, 0xb3, 0x0f, 0xe9, 0xb6, 0x00, 0xe8, 0x96, 0xfd, 0xe8, 0x83, 0x00, 0xac, 0x88,
|
|
||||||
0xc2, 0xbf, 0xd2, 0x03, 0xb9, 0x04, 0x00, 0xad, 0xab, 0xe2, 0xfc, 0xb4, 0x42, 0xbe, 0xca, 0x03,
|
|
||||||
0xcd, 0x13, 0xbe, 0xde, 0x03, 0x72, 0x40, 0xa1, 0xfe, 0x01, 0x3d, 0x55, 0xaa, 0xbe, 0xf4, 0x03,
|
|
||||||
0x75, 0x35, 0xb4, 0x06, 0x30, 0xc0, 0xb7, 0x0f, 0x31, 0xc9, 0xba, 0x4f, 0x18, 0xcd, 0x10, 0xc7,
|
|
||||||
0x46, 0x08, 0x00, 0x00, 0xbe, 0x0d, 0x04, 0xb3, 0x07, 0xe8, 0x4e, 0x00, 0xfe, 0x46, 0x08, 0xe8,
|
|
||||||
0x29, 0x00, 0x46, 0xe8, 0x44, 0x00, 0xba, 0x00, 0x01, 0x30, 0xff, 0xb4, 0x02, 0xcd, 0x10, 0xe8,
|
|
||||||
0x2f, 0x00, 0x8a, 0x14, 0xe9, 0xa9, 0xfc, 0xba, 0x1a, 0x15, 0x89, 0x56, 0x08, 0xbb, 0x0f, 0x00,
|
|
||||||
0xe8, 0x27, 0x00, 0xb4, 0x00, 0xcd, 0x16, 0xb2, 0x80, 0xcd, 0x19, 0xbe, 0x1b, 0x04, 0x8b, 0x4e,
|
|
||||||
0x00, 0x41, 0x30, 0xe4, 0xe9, 0x07, 0x00, 0xac, 0x01, 0xc6, 0x81, 0xc6, 0x09, 0x00, 0xe2, 0xf7,
|
|
||||||
0xc3, 0xe8, 0xe7, 0xff, 0xac, 0x30, 0xe4, 0x01, 0xc6, 0xc3, 0x50, 0x53, 0x51, 0x52, 0x30, 0xff,
|
|
||||||
0xe9, 0x11, 0x00, 0x8b, 0x56, 0x08, 0xb4, 0x02, 0xcd, 0x10, 0xfe, 0x46, 0x08, 0xb9, 0x01, 0x00,
|
|
||||||
0xb4, 0x09, 0xcd, 0x10, 0xac, 0x3c, 0x00, 0x75, 0xea, 0x5a, 0x59, 0x5b, 0x58, 0xc3, 0x50, 0x53,
|
|
||||||
0x51, 0x52, 0x30, 0xff, 0x8b, 0x56, 0x08, 0xb4, 0x02, 0xcd, 0x10, 0xfe, 0x46, 0x08, 0xb9, 0x01,
|
|
||||||
0x00, 0xb4, 0x09, 0xcd, 0x10, 0x5a, 0x59, 0x5b, 0x58, 0xc3, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00,
|
|
||||||
0xc0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x02, 0x03, 0x45, 0x72,
|
|
||||||
0x72, 0x6f, 0x72, 0x20, 0x6c, 0x6f, 0x61, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x73, 0x65, 0x63, 0x74,
|
|
||||||
0x6f, 0x72, 0x73, 0x00, 0x4e, 0x6f, 0x74, 0x20, 0x61, 0x20, 0x62, 0x6f, 0x6f, 0x74, 0x61, 0x62,
|
|
||||||
0x6c, 0x65, 0x20, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x4c, 0x6f, 0x61,
|
|
||||||
0x64, 0x69, 0x6e, 0x67, 0x00
|
|
||||||
};
|
|
||||||
@@ -3,6 +3,7 @@
|
|||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
* Authors:
|
* Authors:
|
||||||
|
* Axel Dörfler, [email protected]
|
||||||
* Michael Pfeiffer <[email protected]>
|
* Michael Pfeiffer <[email protected]>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -18,6 +19,7 @@
|
|||||||
#include <Path.h>
|
#include <Path.h>
|
||||||
#include <String.h>
|
#include <String.h>
|
||||||
|
|
||||||
|
#include "BootDrive.h"
|
||||||
#include "DefaultPartitionPage.h"
|
#include "DefaultPartitionPage.h"
|
||||||
#include "DescriptionPage.h"
|
#include "DescriptionPage.h"
|
||||||
#include "DrivesPage.h"
|
#include "DrivesPage.h"
|
||||||
@@ -39,11 +41,12 @@
|
|||||||
|
|
||||||
|
|
||||||
BootManagerController::BootManagerController()
|
BootManagerController::BootManagerController()
|
||||||
|
:
|
||||||
|
fBootDrive(NULL),
|
||||||
|
fBootMenu(NULL)
|
||||||
{
|
{
|
||||||
#if USE_TEST_BOOT_DRIVE
|
#if USE_TEST_BOOT_DRIVE
|
||||||
fBootMenu = new TestBootDrive();
|
fBootMenu = new TestBootDrive();
|
||||||
#else
|
|
||||||
fBootMenu = new LegacyBootMenu();
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// set defaults
|
// set defaults
|
||||||
@@ -65,7 +68,8 @@ BootManagerController::BootManagerController()
|
|||||||
fSettings.AddString("file", "");
|
fSettings.AddString("file", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
fReadPartitionsStatus = fBootMenu->ReadPartitions(&fSettings);
|
// That's the only boot menu we support at the moment.
|
||||||
|
fBootMenus.AddItem(new LegacyBootMenu());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -80,8 +84,8 @@ BootManagerController::Previous(WizardView* wizard)
|
|||||||
if (CurrentState() != kStateEntry)
|
if (CurrentState() != kStateEntry)
|
||||||
WizardController::Previous(wizard);
|
WizardController::Previous(wizard);
|
||||||
else {
|
else {
|
||||||
WizardController::Next(wizard);
|
|
||||||
fSettings.ReplaceBool("install", false);
|
fSettings.ReplaceBool("install", false);
|
||||||
|
WizardController::Next(wizard);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -89,9 +93,7 @@ BootManagerController::Previous(WizardView* wizard)
|
|||||||
int32
|
int32
|
||||||
BootManagerController::InitialState()
|
BootManagerController::InitialState()
|
||||||
{
|
{
|
||||||
if (fReadPartitionsStatus == B_OK)
|
return kStateEntry;
|
||||||
return kStateEntry;
|
|
||||||
return kStateErrorEntry;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -101,11 +103,29 @@ BootManagerController::NextState(int32 state)
|
|||||||
switch (state) {
|
switch (state) {
|
||||||
case kStateEntry:
|
case kStateEntry:
|
||||||
{
|
{
|
||||||
if (fSettings.FindBool("install")) {
|
const char* path;
|
||||||
if (fBootMenu->IsBootMenuInstalled(&fSettings))
|
if (fSettings.FindString("disk", &path) != B_OK)
|
||||||
return kStatePartitions;
|
return kStateErrorEntry;
|
||||||
|
|
||||||
return kStateSaveMBR;
|
delete fBootDrive;
|
||||||
|
|
||||||
|
fBootDrive = new BootDrive(path);
|
||||||
|
fBootMenu = fBootDrive->InstalledMenu(fBootMenus);
|
||||||
|
|
||||||
|
if (fSettings.FindBool("install")) {
|
||||||
|
int32 nextState = fBootMenu != NULL
|
||||||
|
? kStatePartitions : kStateSaveMBR;
|
||||||
|
|
||||||
|
// TODO: call BootDrive::AddSupportedMenus() once we support
|
||||||
|
// more than one type of boot menu - we'll probably need a
|
||||||
|
// requester to choose from them then as well.
|
||||||
|
if (fBootMenu == NULL)
|
||||||
|
fBootMenu = fBootMenus.ItemAt(0);
|
||||||
|
|
||||||
|
fCollectPartitionsStatus = fBootMenu->CollectPartitions(
|
||||||
|
*fBootDrive, fSettings);
|
||||||
|
|
||||||
|
return nextState;
|
||||||
}
|
}
|
||||||
|
|
||||||
return kStateUninstall;
|
return kStateUninstall;
|
||||||
@@ -186,7 +206,7 @@ BootManagerController::_WriteBootMenu()
|
|||||||
if (alert->Go() == 1)
|
if (alert->Go() == 1)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
fWriteBootMenuStatus = fBootMenu->WriteBootMenu(&fSettings);
|
fWriteBootMenuStatus = fBootMenu->Install(*fBootDrive, fSettings);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -238,7 +258,8 @@ BootManagerController::CreatePage(int32 state, WizardView* wizard)
|
|||||||
|
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case kStateEntry:
|
case kStateEntry:
|
||||||
page = new DrivesPage(wizard, &fSettings, "drives");
|
fSettings.ReplaceBool("install", true);
|
||||||
|
page = new DrivesPage(wizard, fBootMenus, &fSettings, "drives");
|
||||||
break;
|
break;
|
||||||
case kStateErrorEntry:
|
case kStateErrorEntry:
|
||||||
page = _CreateErrorEntryPage();
|
page = _CreateErrorEntryPage();
|
||||||
@@ -286,7 +307,7 @@ BootManagerController::_CreateErrorEntryPage()
|
|||||||
{
|
{
|
||||||
BString description;
|
BString description;
|
||||||
|
|
||||||
if (fReadPartitionsStatus == B_PARTITION_TOO_SMALL) {
|
if (fCollectPartitionsStatus == B_PARTITION_TOO_SMALL) {
|
||||||
description << B_TRANSLATE_COMMENT("Partition table not compatible",
|
description << B_TRANSLATE_COMMENT("Partition table not compatible",
|
||||||
"Title") << "\n\n"
|
"Title") << "\n\n"
|
||||||
<< B_TRANSLATE("The partition table of the first hard disk is not "
|
<< B_TRANSLATE("The partition table of the first hard disk is not "
|
||||||
|
|||||||
@@ -13,9 +13,10 @@
|
|||||||
|
|
||||||
#include <Message.h>
|
#include <Message.h>
|
||||||
|
|
||||||
|
#include "BootMenu.h"
|
||||||
|
|
||||||
|
|
||||||
class BootDrive;
|
class BootDrive;
|
||||||
class BootMenu;
|
|
||||||
class WizardView;
|
class WizardView;
|
||||||
class WizardPageView;
|
class WizardPageView;
|
||||||
|
|
||||||
@@ -72,9 +73,11 @@ private:
|
|||||||
WizardPageView* _CreateUninstalledPage();
|
WizardPageView* _CreateUninstalledPage();
|
||||||
|
|
||||||
BMessage fSettings;
|
BMessage fSettings;
|
||||||
|
BootMenuList fBootMenus;
|
||||||
|
BootDrive* fBootDrive;
|
||||||
BootMenu* fBootMenu;
|
BootMenu* fBootMenu;
|
||||||
|
|
||||||
status_t fReadPartitionsStatus;
|
status_t fCollectPartitionsStatus;
|
||||||
status_t fWriteBootMenuStatus;
|
status_t fWriteBootMenuStatus;
|
||||||
status_t fSaveMBRStatus;
|
status_t fSaveMBRStatus;
|
||||||
status_t fRestoreMBRStatus;
|
status_t fRestoreMBRStatus;
|
||||||
|
|||||||
@@ -11,12 +11,14 @@
|
|||||||
|
|
||||||
#include <File.h>
|
#include <File.h>
|
||||||
#include <Message.h>
|
#include <Message.h>
|
||||||
|
#include <ObjectList.h>
|
||||||
|
|
||||||
|
|
||||||
|
class BootDrive;
|
||||||
|
|
||||||
|
|
||||||
/* Setting BMessage Format:
|
/* Setting BMessage Format:
|
||||||
|
|
||||||
"disk" String (path to boot disk)
|
|
||||||
|
|
||||||
"partition" array of BMessage:
|
"partition" array of BMessage:
|
||||||
"show" bool (flag if entry should be added to boot menu)
|
"show" bool (flag if entry should be added to boot menu)
|
||||||
"name" String (the name as shown in boot menu)
|
"name" String (the name as shown in boot menu)
|
||||||
@@ -31,9 +33,14 @@ public:
|
|||||||
BootMenu() {}
|
BootMenu() {}
|
||||||
virtual ~BootMenu() {}
|
virtual ~BootMenu() {}
|
||||||
|
|
||||||
virtual bool IsBootMenuInstalled(BMessage* settings) = 0;
|
virtual bool IsInstalled(const BootDrive& drive) = 0;
|
||||||
virtual status_t ReadPartitions(BMessage* settings) = 0;
|
virtual status_t CanBeInstalled(const BootDrive& drive) = 0;
|
||||||
virtual status_t WriteBootMenu(BMessage* settings) = 0;
|
|
||||||
|
virtual status_t CollectPartitions(const BootDrive& drive,
|
||||||
|
BMessage& settings) = 0;
|
||||||
|
|
||||||
|
virtual status_t Install(const BootDrive& drive,
|
||||||
|
BMessage& settings) = 0;
|
||||||
virtual status_t SaveMasterBootRecord(BMessage* settings,
|
virtual status_t SaveMasterBootRecord(BMessage* settings,
|
||||||
BFile* file) = 0;
|
BFile* file) = 0;
|
||||||
virtual status_t RestoreMasterBootRecord(BMessage* settings,
|
virtual status_t RestoreMasterBootRecord(BMessage* settings,
|
||||||
@@ -45,5 +52,7 @@ public:
|
|||||||
BString& displayText) = 0;
|
BString& displayText) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef BObjectList<BootMenu> BootMenuList;
|
||||||
|
|
||||||
|
|
||||||
#endif // BOOT_MENU_H
|
#endif // BOOT_MENU_H
|
||||||
|
|||||||
@@ -31,7 +31,8 @@ const uint32 kMsgSelectionChanged = 'slch';
|
|||||||
|
|
||||||
class DriveItem : public BListItem {
|
class DriveItem : public BListItem {
|
||||||
public:
|
public:
|
||||||
DriveItem(const BDiskDevice& device);
|
DriveItem(const BDiskDevice& device,
|
||||||
|
const BootMenuList& menus);
|
||||||
virtual ~DriveItem();
|
virtual ~DriveItem();
|
||||||
|
|
||||||
bool IsInstalled() const;
|
bool IsInstalled() const;
|
||||||
@@ -39,7 +40,6 @@ public:
|
|||||||
bool IsBootDrive() const;
|
bool IsBootDrive() const;
|
||||||
const char* Path() const { return fPath.Path(); }
|
const char* Path() const { return fPath.Path(); }
|
||||||
|
|
||||||
BMessage& Settings() { return fSettings; }
|
|
||||||
BootDrive* Drive() { return fDrive; }
|
BootDrive* Drive() { return fDrive; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@@ -48,7 +48,6 @@ protected:
|
|||||||
virtual void Update(BView* owner, const BFont* font);
|
virtual void Update(BView* owner, const BFont* font);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BMessage fSettings;
|
|
||||||
BootDrive* fDrive;
|
BootDrive* fDrive;
|
||||||
BString fName;
|
BString fName;
|
||||||
BPath fPath;
|
BPath fPath;
|
||||||
@@ -56,21 +55,28 @@ private:
|
|||||||
float fBaselineOffset;
|
float fBaselineOffset;
|
||||||
float fSecondBaselineOffset;
|
float fSecondBaselineOffset;
|
||||||
float fSizeWidth;
|
float fSizeWidth;
|
||||||
|
status_t fCanBeInstalled;
|
||||||
|
bool fIsInstalled;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
DriveItem::DriveItem(const BDiskDevice& device)
|
DriveItem::DriveItem(const BDiskDevice& device, const BootMenuList& menus)
|
||||||
:
|
:
|
||||||
fBaselineOffset(0),
|
fBaselineOffset(0),
|
||||||
fSizeWidth(0)
|
fSizeWidth(0)
|
||||||
{
|
{
|
||||||
// TODO: retrieve disk name!
|
device.GetPath(&fPath);
|
||||||
if (device.Name() != NULL && device.Name()[0])
|
if (device.Name() != NULL && device.Name()[0])
|
||||||
fName = device.Name();
|
fName = device.Name();
|
||||||
|
else if (strstr(fPath.Path(), "usb") != NULL)
|
||||||
|
fName = B_TRANSLATE_COMMENT("USB Drive", "Default disk name");
|
||||||
else
|
else
|
||||||
fName = B_TRANSLATE_COMMENT("Hard Drive", "Default disk name");
|
fName = B_TRANSLATE_COMMENT("Hard Drive", "Default disk name");
|
||||||
|
|
||||||
device.GetPath(&fPath);
|
fDrive = new BootDrive(fPath.Path());
|
||||||
|
|
||||||
|
fIsInstalled = fDrive->InstalledMenu(menus) != NULL;
|
||||||
|
fCanBeInstalled = fDrive->CanMenuBeInstalled(menus);
|
||||||
|
|
||||||
char buffer[256];
|
char buffer[256];
|
||||||
fSize = string_for_size(device.Size(), buffer, sizeof(buffer));
|
fSize = string_for_size(device.Size(), buffer, sizeof(buffer));
|
||||||
@@ -85,21 +91,21 @@ DriveItem::~DriveItem()
|
|||||||
bool
|
bool
|
||||||
DriveItem::IsInstalled() const
|
DriveItem::IsInstalled() const
|
||||||
{
|
{
|
||||||
return true;
|
return fIsInstalled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
DriveItem::CanBeInstalled() const
|
DriveItem::CanBeInstalled() const
|
||||||
{
|
{
|
||||||
return true;
|
return fCanBeInstalled == B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
DriveItem::IsBootDrive() const
|
DriveItem::IsBootDrive() const
|
||||||
{
|
{
|
||||||
return true;
|
return fDrive->IsBootDrive();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -142,6 +148,14 @@ DriveItem::DrawItem(BView* owner, BRect frame, bool complete)
|
|||||||
owner->MovePenTo(frame.left + 4, frame.top + fBaselineOffset);
|
owner->MovePenTo(frame.left + 4, frame.top + fBaselineOffset);
|
||||||
owner->DrawString(fName.String());
|
owner->DrawString(fName.String());
|
||||||
|
|
||||||
|
if (fCanBeInstalled != B_OK) {
|
||||||
|
owner->SetHighColor(140, 0, 0);
|
||||||
|
owner->MovePenBy(fBaselineOffset, 0);
|
||||||
|
owner->DrawString(fCanBeInstalled == B_PARTITION_TOO_SMALL
|
||||||
|
? B_TRANSLATE_COMMENT("No space available!", "Cannot install")
|
||||||
|
: B_TRANSLATE_COMMENT("Cannot access!", "Cannot install"));
|
||||||
|
}
|
||||||
|
|
||||||
owner->PopState();
|
owner->PopState();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -177,8 +191,8 @@ DriveItem::Update(BView* owner, const BFont* font)
|
|||||||
// #pragma mark -
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
DrivesPage::DrivesPage(WizardView* wizardView, BMessage* settings,
|
DrivesPage::DrivesPage(WizardView* wizardView, const BootMenuList& menus,
|
||||||
const char* name)
|
BMessage* settings, const char* name)
|
||||||
:
|
:
|
||||||
WizardPageView(settings, name),
|
WizardPageView(settings, name),
|
||||||
fWizardView(wizardView)
|
fWizardView(wizardView)
|
||||||
@@ -193,7 +207,7 @@ DrivesPage::DrivesPage(WizardView* wizardView, BMessage* settings,
|
|||||||
fDrivesView = new BListView("drives");
|
fDrivesView = new BListView("drives");
|
||||||
fDrivesView->SetSelectionMessage(new BMessage(kMsgSelectionChanged));
|
fDrivesView->SetSelectionMessage(new BMessage(kMsgSelectionChanged));
|
||||||
|
|
||||||
bool any = _FillDrivesView();
|
bool any = _FillDrivesView(menus);
|
||||||
|
|
||||||
BScrollView* scrollView = new BScrollView("scrollView", fDrivesView, 0,
|
BScrollView* scrollView = new BScrollView("scrollView", fDrivesView, 0,
|
||||||
false, true);
|
false, true);
|
||||||
@@ -208,6 +222,8 @@ DrivesPage::DrivesPage(WizardView* wizardView, BMessage* settings,
|
|||||||
fWizardView->SetPreviousButtonLabel(
|
fWizardView->SetPreviousButtonLabel(
|
||||||
B_TRANSLATE_COMMENT("Uninstall", "Button"));
|
B_TRANSLATE_COMMENT("Uninstall", "Button"));
|
||||||
fWizardView->SetPreviousButtonHidden(false);
|
fWizardView->SetPreviousButtonHidden(false);
|
||||||
|
fWizardView->SetPreviousButtonEnabled(false);
|
||||||
|
fWizardView->SetPreviousButtonEnabled(false);
|
||||||
} else {
|
} else {
|
||||||
fWizardView->SetPreviousButtonHidden(true);
|
fWizardView->SetPreviousButtonHidden(true);
|
||||||
fWizardView->SetNextButtonLabel(
|
fWizardView->SetNextButtonLabel(
|
||||||
@@ -228,8 +244,6 @@ DrivesPage::PageCompleted()
|
|||||||
|
|
||||||
if (fSettings->ReplaceString("disk", item->Path()) != B_OK)
|
if (fSettings->ReplaceString("disk", item->Path()) != B_OK)
|
||||||
fSettings->AddString("disk", item->Path());
|
fSettings->AddString("disk", item->Path());
|
||||||
|
|
||||||
fSettings->ReplaceBool("install", true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -262,7 +276,7 @@ DrivesPage::MessageReceived(BMessage* message)
|
|||||||
selects the boot drive.
|
selects the boot drive.
|
||||||
*/
|
*/
|
||||||
bool
|
bool
|
||||||
DrivesPage::_FillDrivesView()
|
DrivesPage::_FillDrivesView(const BootMenuList& menus)
|
||||||
{
|
{
|
||||||
bool any = false;
|
bool any = false;
|
||||||
|
|
||||||
@@ -270,7 +284,7 @@ DrivesPage::_FillDrivesView()
|
|||||||
BDiskDevice device;
|
BDiskDevice device;
|
||||||
while (roster.GetNextDevice(&device) == B_OK) {
|
while (roster.GetNextDevice(&device) == B_OK) {
|
||||||
if (device.HasMedia() && !device.IsReadOnly()) {
|
if (device.HasMedia() && !device.IsReadOnly()) {
|
||||||
DriveItem* item = new DriveItem(device);
|
DriveItem* item = new DriveItem(device, menus);
|
||||||
if (item->CanBeInstalled())
|
if (item->CanBeInstalled())
|
||||||
any = true;
|
any = true;
|
||||||
fDrivesView->AddItem(item);
|
fDrivesView->AddItem(item);
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
#define DRIVES_PAGE_H
|
#define DRIVES_PAGE_H
|
||||||
|
|
||||||
|
|
||||||
|
#include "BootMenu.h"
|
||||||
#include "WizardPageView.h"
|
#include "WizardPageView.h"
|
||||||
|
|
||||||
|
|
||||||
@@ -19,6 +20,7 @@ class WizardView;
|
|||||||
class DrivesPage : public WizardPageView {
|
class DrivesPage : public WizardPageView {
|
||||||
public:
|
public:
|
||||||
DrivesPage(WizardView* wizardView,
|
DrivesPage(WizardView* wizardView,
|
||||||
|
const BootMenuList& menus,
|
||||||
BMessage* settings, const char* name);
|
BMessage* settings, const char* name);
|
||||||
virtual ~DrivesPage();
|
virtual ~DrivesPage();
|
||||||
|
|
||||||
@@ -29,7 +31,7 @@ protected:
|
|||||||
void MessageReceived(BMessage* message);
|
void MessageReceived(BMessage* message);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool _FillDrivesView();
|
bool _FillDrivesView(const BootMenuList& menus);
|
||||||
DriveItem* _SelectedDriveItem();
|
DriveItem* _SelectedDriveItem();
|
||||||
void _UpdateWizardButtons(DriveItem* item);
|
void _UpdateWizardButtons(DriveItem* item);
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ SubDir HAIKU_TOP src apps bootmanager ;
|
|||||||
UsePrivateHeaders shared storage tracker ;
|
UsePrivateHeaders shared storage tracker ;
|
||||||
|
|
||||||
local cataloguedSources =
|
local cataloguedSources =
|
||||||
|
BootDrive.cpp
|
||||||
BootManager.cpp
|
BootManager.cpp
|
||||||
BootManagerController.cpp
|
BootManagerController.cpp
|
||||||
BootManagerWindow.cpp
|
BootManagerWindow.cpp
|
||||||
@@ -18,21 +19,29 @@ local cataloguedSources =
|
|||||||
Application BootManager :
|
Application BootManager :
|
||||||
$(cataloguedSources)
|
$(cataloguedSources)
|
||||||
DescriptionPage.cpp
|
DescriptionPage.cpp
|
||||||
# TestBootDrive.cpp
|
|
||||||
WizardController.cpp
|
WizardController.cpp
|
||||||
WizardPageView.cpp
|
WizardPageView.cpp
|
||||||
:
|
|
||||||
be
|
: be textencoding tracker $(HAIKU_LOCALE_LIBS) $(TARGET_LIBSUPC++)
|
||||||
textencoding
|
: BootManager.rdef
|
||||||
tracker
|
|
||||||
$(HAIKU_LOCALE_LIBS)
|
|
||||||
$(TARGET_LIBSUPC++)
|
|
||||||
:
|
|
||||||
BootManager.rdef
|
|
||||||
;
|
;
|
||||||
|
|
||||||
DoCatalogs BootManager :
|
DoCatalogs BootManager : x-vnd.Haiku-BootManager : $(cataloguedSources) ;
|
||||||
x-vnd.Haiku-BootManager
|
|
||||||
:
|
# Assemble the boot loader, and convert it into a header file
|
||||||
$(cataloguedSources)
|
|
||||||
;
|
rule AssembleYasmBin object : source
|
||||||
|
{
|
||||||
|
SEARCH on $(source) = $(SUBDIR) ;
|
||||||
|
Depends $(object) : $(source) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
actions AssembleYasmBin
|
||||||
|
{
|
||||||
|
$(HAIKU_YASM) -f bin -o $(1) $(2)
|
||||||
|
}
|
||||||
|
|
||||||
|
AssembleYasmBin [ FGristFiles bootman.bin ] : bootman.S ;
|
||||||
|
|
||||||
|
DataFileToSourceFile [ FGristFiles BootLoader.h ] : [ FGristFiles bootman.bin ]
|
||||||
|
: kBootLoader : kBootLoaderSize ;
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
* Authors:
|
* Authors:
|
||||||
|
* Axel Dörfler, [email protected]
|
||||||
* Michael Pfeiffer <[email protected]>
|
* Michael Pfeiffer <[email protected]>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -10,6 +11,8 @@
|
|||||||
#include "LegacyBootMenu.h"
|
#include "LegacyBootMenu.h"
|
||||||
|
|
||||||
#include <new>
|
#include <new>
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include <Catalog.h>
|
#include <Catalog.h>
|
||||||
@@ -17,19 +20,19 @@
|
|||||||
#include <DiskDevice.h>
|
#include <DiskDevice.h>
|
||||||
#include <DiskDeviceRoster.h>
|
#include <DiskDeviceRoster.h>
|
||||||
#include <DiskDeviceVisitor.h>
|
#include <DiskDeviceVisitor.h>
|
||||||
|
#include <Drivers.h>
|
||||||
#include <File.h>
|
#include <File.h>
|
||||||
#include <Partition.h>
|
#include <Partition.h>
|
||||||
#include <Path.h>
|
#include <Path.h>
|
||||||
#include <String.h>
|
#include <String.h>
|
||||||
#include <UTF8.h>
|
#include <UTF8.h>
|
||||||
|
|
||||||
|
#include "BootDrive.h"
|
||||||
#include "BootLoader.h"
|
#include "BootLoader.h"
|
||||||
|
|
||||||
|
|
||||||
#undef B_TRANSLATE_CONTEXT
|
#undef B_TRANSLATE_CONTEXT
|
||||||
#define B_TRANSLATE_CONTEXT "LegacyBootMenu"
|
#define B_TRANSLATE_CONTEXT "LegacyBootMenu"
|
||||||
#define USE_SECOND_DISK 0
|
|
||||||
#define GET_FIRST_BIOS_DRIVE 1
|
|
||||||
|
|
||||||
|
|
||||||
struct MasterBootRecord {
|
struct MasterBootRecord {
|
||||||
@@ -53,10 +56,9 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class PartitionRecorder : public BDiskDeviceVisitor {
|
class PartitionVisitor : public BDiskDeviceVisitor {
|
||||||
public:
|
public:
|
||||||
PartitionRecorder(BMessage* settings,
|
PartitionVisitor();
|
||||||
int8 drive);
|
|
||||||
|
|
||||||
virtual bool Visit(BDiskDevice* device);
|
virtual bool Visit(BDiskDevice* device);
|
||||||
virtual bool Visit(BPartition* partition, int32 level);
|
virtual bool Visit(BPartition* partition, int32 level);
|
||||||
@@ -65,13 +67,25 @@ public:
|
|||||||
off_t FirstOffset() const;
|
off_t FirstOffset() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool _Record(BPartition* partition);
|
off_t fFirstOffset;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class PartitionRecorder : public BDiskDeviceVisitor {
|
||||||
|
public:
|
||||||
|
PartitionRecorder(BMessage& settings,
|
||||||
|
int8 biosDrive);
|
||||||
|
|
||||||
|
virtual bool Visit(BDiskDevice* device);
|
||||||
|
virtual bool Visit(BPartition* partition, int32 level);
|
||||||
|
|
||||||
|
bool FoundPartitions() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BMessage* fSettings;
|
BMessage& fSettings;
|
||||||
int8 fDrive;
|
int32 fUnnamedIndex;
|
||||||
int32 fIndex;
|
int8 fBIOSDrive;
|
||||||
off_t fFirstOffset;
|
bool fFound;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -149,12 +163,53 @@ LittleEndianMallocIO::Fill(int16 size, int8 fillByte)
|
|||||||
// #pragma mark -
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
PartitionRecorder::PartitionRecorder(BMessage* settings, int8 drive)
|
PartitionVisitor::PartitionVisitor()
|
||||||
|
:
|
||||||
|
fFirstOffset(LONGLONG_MAX)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
PartitionVisitor::Visit(BDiskDevice* device)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
PartitionVisitor::Visit(BPartition* partition, int32 level)
|
||||||
|
{
|
||||||
|
if (partition->Offset() < fFirstOffset)
|
||||||
|
fFirstOffset = partition->Offset();
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
PartitionVisitor::HasPartitions() const
|
||||||
|
{
|
||||||
|
return fFirstOffset != LONGLONG_MAX;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
off_t
|
||||||
|
PartitionVisitor::FirstOffset() const
|
||||||
|
{
|
||||||
|
return fFirstOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
|
PartitionRecorder::PartitionRecorder(BMessage& settings, int8 biosDrive)
|
||||||
:
|
:
|
||||||
fSettings(settings),
|
fSettings(settings),
|
||||||
fDrive(drive),
|
fUnnamedIndex(0),
|
||||||
fIndex(0),
|
fBIOSDrive(biosDrive),
|
||||||
fFirstOffset(LONGLONG_MAX)
|
fFound(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -168,27 +223,6 @@ PartitionRecorder::Visit(BDiskDevice* device)
|
|||||||
|
|
||||||
bool
|
bool
|
||||||
PartitionRecorder::Visit(BPartition* partition, int32 level)
|
PartitionRecorder::Visit(BPartition* partition, int32 level)
|
||||||
{
|
|
||||||
return _Record(partition);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool
|
|
||||||
PartitionRecorder::HasPartitions() const
|
|
||||||
{
|
|
||||||
return fFirstOffset != LONGLONG_MAX;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
off_t
|
|
||||||
PartitionRecorder::FirstOffset() const
|
|
||||||
{
|
|
||||||
return fFirstOffset;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool
|
|
||||||
PartitionRecorder::_Record(BPartition* partition)
|
|
||||||
{
|
{
|
||||||
if (partition->ContainsPartitioningSystem())
|
if (partition->ContainsPartitioningSystem())
|
||||||
return false;
|
return false;
|
||||||
@@ -199,9 +233,8 @@ PartitionRecorder::_Record(BPartition* partition)
|
|||||||
BString buffer;
|
BString buffer;
|
||||||
const char* name = partition->ContentName();
|
const char* name = partition->ContentName();
|
||||||
if (name == NULL) {
|
if (name == NULL) {
|
||||||
fIndex ++;
|
|
||||||
BString number;
|
BString number;
|
||||||
number << fIndex;
|
number << ++fUnnamedIndex;
|
||||||
buffer << B_TRANSLATE_COMMENT("Unnamed %d",
|
buffer << B_TRANSLATE_COMMENT("Unnamed %d",
|
||||||
"Default name of a partition whose name could not be read from "
|
"Default name of a partition whose name could not be read from "
|
||||||
"disk; characters in codepage 437 are allowed only");
|
"disk; characters in codepage 437 are allowed only");
|
||||||
@@ -220,21 +253,25 @@ PartitionRecorder::_Record(BPartition* partition)
|
|||||||
message.AddString("name", name);
|
message.AddString("name", name);
|
||||||
message.AddString("type", type);
|
message.AddString("type", type);
|
||||||
message.AddString("path", partitionPath.Path());
|
message.AddString("path", partitionPath.Path());
|
||||||
message.AddInt8("drive", fDrive);
|
if (fBIOSDrive != 0)
|
||||||
|
message.AddInt8("drive", fBIOSDrive);
|
||||||
message.AddInt64("size", partition->Size());
|
message.AddInt64("size", partition->Size());
|
||||||
// Specific data
|
message.AddInt64("offset", partition->Offset());
|
||||||
off_t offset = partition->Offset();
|
|
||||||
message.AddInt64("offset", offset);
|
|
||||||
|
|
||||||
fSettings->AddMessage("partition", &message);
|
fSettings.AddMessage("partition", &message);
|
||||||
|
fFound = true;
|
||||||
if (offset < fFirstOffset)
|
|
||||||
fFirstOffset = offset;
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
PartitionRecorder::FoundPartitions() const
|
||||||
|
{
|
||||||
|
return fFound;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark -
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
@@ -249,67 +286,78 @@ LegacyBootMenu::~LegacyBootMenu()
|
|||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
LegacyBootMenu::IsBootMenuInstalled(BMessage* settings)
|
LegacyBootMenu::IsInstalled(const BootDrive& drive)
|
||||||
{
|
{
|
||||||
// TODO detect bootman
|
// TODO: detect bootman
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
LegacyBootMenu::ReadPartitions(BMessage *settings)
|
LegacyBootMenu::CanBeInstalled(const BootDrive& drive)
|
||||||
|
{
|
||||||
|
BDiskDevice device;
|
||||||
|
status_t status = drive.GetDiskDevice(device);
|
||||||
|
if (status != B_OK)
|
||||||
|
return status;
|
||||||
|
|
||||||
|
PartitionVisitor visitor;
|
||||||
|
device.VisitEachDescendant(&visitor);
|
||||||
|
|
||||||
|
// Enough space to write boot menu to drive?
|
||||||
|
if (!visitor.HasPartitions() || visitor.FirstOffset() < sizeof(kBootLoader))
|
||||||
|
return B_PARTITION_TOO_SMALL;
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
LegacyBootMenu::CollectPartitions(const BootDrive& drive, BMessage& settings)
|
||||||
{
|
{
|
||||||
status_t status = B_ERROR;
|
status_t status = B_ERROR;
|
||||||
|
|
||||||
|
// Remove previous partitions, if any
|
||||||
|
settings.RemoveName("partition");
|
||||||
|
|
||||||
BDiskDeviceRoster diskDeviceRoster;
|
BDiskDeviceRoster diskDeviceRoster;
|
||||||
BDiskDevice device;
|
BDiskDevice device;
|
||||||
bool diskFound = false;
|
bool partitionsFound = false;
|
||||||
|
|
||||||
while (diskDeviceRoster.GetNextDevice(&device) == B_OK) {
|
while (diskDeviceRoster.GetNextDevice(&device) == B_OK) {
|
||||||
BPath path;
|
BPath path;
|
||||||
status_t status = device.GetPath(&path);
|
status_t status = device.GetPath(&path);
|
||||||
if (status != B_OK)
|
if (status != B_OK)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// skip not from BIOS bootable drives
|
// Skip not from BIOS bootable drives that are not the target disk
|
||||||
int8 drive;
|
int8 biosDrive = 0;
|
||||||
if (!_GetBiosDrive(path.Path(), &drive))
|
if (path != drive.Path()
|
||||||
|
&& _GetBIOSDrive(path.Path(), biosDrive) != B_OK)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
PartitionRecorder recorder(settings, drive);
|
PartitionRecorder recorder(settings, biosDrive);
|
||||||
device.VisitEachDescendant(&recorder);
|
device.VisitEachDescendant(&recorder);
|
||||||
|
|
||||||
if (!diskFound) {
|
partitionsFound |= recorder.FoundPartitions();
|
||||||
settings->AddString("disk", path.Path());
|
|
||||||
diskFound = true;
|
|
||||||
|
|
||||||
// Enough space to write boot menu to drive?
|
|
||||||
// (ignored in test build)
|
|
||||||
off_t size = sizeof(kBootLoader);
|
|
||||||
if (!recorder.HasPartitions() || recorder.FirstOffset() < size)
|
|
||||||
status = B_PARTITION_TOO_SMALL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return diskFound ? B_OK : status;
|
return partitionsFound ? B_OK : status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
LegacyBootMenu::WriteBootMenu(BMessage *settings)
|
LegacyBootMenu::Install(const BootDrive& drive, BMessage& settings)
|
||||||
{
|
{
|
||||||
BString path;
|
|
||||||
if (settings->FindString("disk", &path) != B_OK)
|
|
||||||
return B_BAD_VALUE;
|
|
||||||
|
|
||||||
int32 defaultPartitionIndex;
|
int32 defaultPartitionIndex;
|
||||||
if (settings->FindInt32("defaultPartition", &defaultPartitionIndex) != B_OK)
|
if (settings.FindInt32("defaultPartition", &defaultPartitionIndex) != B_OK)
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
int32 timeout;
|
int32 timeout;
|
||||||
if (settings->FindInt32("timeout", &timeout) != B_OK)
|
if (settings.FindInt32("timeout", &timeout) != B_OK)
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
int fd = open(path.String(), O_RDWR);
|
int fd = open(drive.Path(), O_RDWR);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
return B_IO_ERROR;
|
return B_IO_ERROR;
|
||||||
|
|
||||||
@@ -338,7 +386,7 @@ LegacyBootMenu::WriteBootMenu(BMessage *settings)
|
|||||||
int defaultMenuEntry = 0;
|
int defaultMenuEntry = 0;
|
||||||
BMessage partition;
|
BMessage partition;
|
||||||
int32 index;
|
int32 index;
|
||||||
for (index = 0; settings->FindMessage("partition", index,
|
for (index = 0; settings.FindMessage("partition", index,
|
||||||
&partition) == B_OK; index ++) {
|
&partition) == B_OK; index ++) {
|
||||||
bool show;
|
bool show;
|
||||||
partition.FindBool("show", &show);
|
partition.FindBool("show", &show);
|
||||||
@@ -353,7 +401,7 @@ LegacyBootMenu::WriteBootMenu(BMessage *settings)
|
|||||||
newBootLoader.WriteInt16(defaultMenuEntry);
|
newBootLoader.WriteInt16(defaultMenuEntry);
|
||||||
newBootLoader.WriteInt16(timeout);
|
newBootLoader.WriteInt16(timeout);
|
||||||
|
|
||||||
for (index = 0; settings->FindMessage("partition", index,
|
for (index = 0; settings.FindMessage("partition", index,
|
||||||
&partition) == B_OK; index ++) {
|
&partition) == B_OK; index ++) {
|
||||||
bool show;
|
bool show;
|
||||||
BString name;
|
BString name;
|
||||||
@@ -537,20 +585,16 @@ LegacyBootMenu::_ConvertToBIOSText(const char* text, BString& biosText)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
status_t
|
||||||
LegacyBootMenu::_GetBiosDrive(const char* device, int8* drive)
|
LegacyBootMenu::_GetBIOSDrive(const char* device, int8& drive)
|
||||||
{
|
{
|
||||||
#if !GET_FIRST_BIOS_DRIVE
|
int fd = open(device, O_RDONLY);
|
||||||
int fd = open(device, O_RDONLY);
|
if (fd < 0)
|
||||||
if (fd < 0)
|
return errno;
|
||||||
return false;
|
|
||||||
bool isBootableDrive = ioctl(fd, B_GET_BIOS_DRIVE_ID, drive, 1) == B_OK;
|
status_t status = ioctl(fd, B_GET_BIOS_DRIVE_ID, drive, 1);
|
||||||
close(fd);
|
close(fd);
|
||||||
return isBootableDrive;
|
return status;
|
||||||
#else
|
|
||||||
*drive = 0x80;
|
|
||||||
return true;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
* Authors:
|
* Authors:
|
||||||
|
* Axel Dörfler, [email protected]
|
||||||
* Michael Pfeiffer <[email protected]>
|
* Michael Pfeiffer <[email protected]>
|
||||||
*/
|
*/
|
||||||
#ifndef LEGACY_BOOT_MENU_H
|
#ifndef LEGACY_BOOT_MENU_H
|
||||||
@@ -22,9 +23,14 @@ public:
|
|||||||
LegacyBootMenu();
|
LegacyBootMenu();
|
||||||
virtual ~LegacyBootMenu();
|
virtual ~LegacyBootMenu();
|
||||||
|
|
||||||
virtual bool IsBootMenuInstalled(BMessage* settings);
|
virtual bool IsInstalled(const BootDrive& drive);
|
||||||
virtual status_t ReadPartitions(BMessage* settings);
|
virtual status_t CanBeInstalled(const BootDrive& drive);
|
||||||
virtual status_t WriteBootMenu(BMessage* settings);
|
|
||||||
|
virtual status_t CollectPartitions(const BootDrive& drive,
|
||||||
|
BMessage& settings);
|
||||||
|
|
||||||
|
virtual status_t Install(const BootDrive& drive,
|
||||||
|
BMessage& settings);
|
||||||
virtual status_t SaveMasterBootRecord(BMessage* settings,
|
virtual status_t SaveMasterBootRecord(BMessage* settings,
|
||||||
BFile* file);
|
BFile* file);
|
||||||
virtual status_t RestoreMasterBootRecord(BMessage* settings,
|
virtual status_t RestoreMasterBootRecord(BMessage* settings,
|
||||||
@@ -35,7 +41,8 @@ public:
|
|||||||
private:
|
private:
|
||||||
bool _ConvertToBIOSText(const char* text,
|
bool _ConvertToBIOSText(const char* text,
|
||||||
BString& biosText);
|
BString& biosText);
|
||||||
bool _GetBiosDrive(const char* device, int8* drive);
|
status_t _GetBIOSDrive(const char* device,
|
||||||
|
int8& drive);
|
||||||
status_t _ReadBlocks(int fd, uint8* buffer, size_t size);
|
status_t _ReadBlocks(int fd, uint8* buffer, size_t size);
|
||||||
status_t _WriteBlocks(int fd, const uint8* buffer,
|
status_t _WriteBlocks(int fd, const uint8* buffer,
|
||||||
size_t size);
|
size_t size);
|
||||||
|
|||||||
@@ -1,51 +0,0 @@
|
|||||||
#include <fcntl.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
|
|
||||||
int
|
|
||||||
main(int argc, char* argv[])
|
|
||||||
{
|
|
||||||
const char* application = argv[0];
|
|
||||||
if (argc != 3) {
|
|
||||||
fprintf(stderr, "Usage:\n%s <variable name> <file>", application);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
const char* variableName = argv[1];
|
|
||||||
const char* fileName = argv[2];
|
|
||||||
|
|
||||||
int fd = open(fileName, 0);
|
|
||||||
if (fd < 0) {
|
|
||||||
fprintf(stderr, "%s: Error opening file '%s'!\n", application,
|
|
||||||
fileName);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
const int kSize = 1024;
|
|
||||||
unsigned char buffer[kSize];
|
|
||||||
int size = read(fd, buffer, kSize);
|
|
||||||
const int COLUMNS = 16;
|
|
||||||
int column = COLUMNS - 1;
|
|
||||||
bool first = true;
|
|
||||||
printf("// THIS FILE WAS GENERATED WITH\n");
|
|
||||||
printf("// %s %s %s\n\n", application, variableName, fileName);
|
|
||||||
printf("static const uint8 %s[] = {", variableName);
|
|
||||||
while (size > 0) {
|
|
||||||
for (int i = 0; i < size; i ++) {
|
|
||||||
if (first)
|
|
||||||
first = false;
|
|
||||||
else
|
|
||||||
printf(", ");
|
|
||||||
column ++;
|
|
||||||
if (column == COLUMNS) {
|
|
||||||
printf("\n\t");
|
|
||||||
column = 0;
|
|
||||||
}
|
|
||||||
printf("0x%2.2x", (int)buffer[i]);
|
|
||||||
}
|
|
||||||
size = read(fd, buffer, kSize);
|
|
||||||
}
|
|
||||||
printf("\n};\n");
|
|
||||||
|
|
||||||
close(fd);
|
|
||||||
}
|
|
||||||
@@ -64,8 +64,12 @@ WizardView::PageCompleted()
|
|||||||
if (fPage != NULL)
|
if (fPage != NULL)
|
||||||
fPage->PageCompleted();
|
fPage->PageCompleted();
|
||||||
|
|
||||||
|
// Restore initial state
|
||||||
SetNextButtonLabel(B_TRANSLATE_COMMENT("Next", "Button"));
|
SetNextButtonLabel(B_TRANSLATE_COMMENT("Next", "Button"));
|
||||||
SetPreviousButtonLabel(B_TRANSLATE_COMMENT("Previous", "Button"));
|
SetPreviousButtonLabel(B_TRANSLATE_COMMENT("Previous", "Button"));
|
||||||
|
SetNextButtonEnabled(true);
|
||||||
|
SetPreviousButtonEnabled(true);
|
||||||
|
SetPreviousButtonHidden(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -2,14 +2,9 @@
|
|||||||
; Copyright 2007, Dengg David, [email protected]. All rights reserved.
|
; Copyright 2007, Dengg David, [email protected]. All rights reserved.
|
||||||
; Copyright 2008, Michael Pfeiffer, [email protected]. All rights reserved.
|
; Copyright 2008, Michael Pfeiffer, [email protected]. All rights reserved.
|
||||||
; Copyright 2005, Ingo Weinhold, [email protected].
|
; Copyright 2005, Ingo Weinhold, [email protected].
|
||||||
|
; Copyright 2011, Axel Dörfler, [email protected].
|
||||||
; Distributed under the terms of the MIT License.
|
; Distributed under the terms of the MIT License.
|
||||||
|
|
||||||
; Steps to create BootLoader.h
|
|
||||||
; 1. nasm -f bin bootman.S -o bootman.bin
|
|
||||||
; 2. cc MakeArray.cpp -o make_array -lstdc++
|
|
||||||
; 3. ./make_array kBootLoader bootman.bin > BootLoader.h
|
|
||||||
; or
|
|
||||||
; nasm -f bin bootman.S -o bootman.bin && ./make_array kBootLoader bootman.bin > BootLoader.h
|
|
||||||
|
|
||||||
%assign USE_TEST_MENU 0
|
%assign USE_TEST_MENU 0
|
||||||
|
|
||||||
@@ -155,7 +150,7 @@
|
|||||||
%define TITLE 'Haiku Boot Manager'
|
%define TITLE 'Haiku Boot Manager'
|
||||||
%strlen TITLE_LENGTH TITLE
|
%strlen TITLE_LENGTH TITLE
|
||||||
%define SELECT_OS_MESSAGE 'Select an OS from the menu'
|
%define SELECT_OS_MESSAGE 'Select an OS from the menu'
|
||||||
%strlen SELECT_OS_MESSAGE_LENGTH SELECT_OS_MESSAGE
|
%strlen SELECT_OS_MESSAGE_LENGTH SELECT_OS_MESSAGE
|
||||||
|
|
||||||
; 16 bit code
|
; 16 bit code
|
||||||
SECTION
|
SECTION
|
||||||
@@ -212,13 +207,13 @@ cursorPosition equ cursorX
|
|||||||
mov dx, [bp + cursorPosition]
|
mov dx, [bp + cursorPosition]
|
||||||
mov ah, SET_CURSOR
|
mov ah, SET_CURSOR
|
||||||
int BIOS_VIDEO_SERVICES
|
int BIOS_VIDEO_SERVICES
|
||||||
|
|
||||||
inc byte [bp + cursorX]
|
inc byte [bp + cursorX]
|
||||||
|
|
||||||
mov cx, 1
|
mov cx, 1
|
||||||
mov ah, WRITE_CHAR
|
mov ah, WRITE_CHAR
|
||||||
int BIOS_VIDEO_SERVICES
|
int BIOS_VIDEO_SERVICES
|
||||||
.loop_condition
|
.loop_condition
|
||||||
lodsb
|
lodsb
|
||||||
cmp al, 0
|
cmp al, 0
|
||||||
jnz .loop
|
jnz .loop
|
||||||
@@ -254,22 +249,23 @@ endstruc
|
|||||||
%define printstr printStringStage1
|
%define printstr printStringStage1
|
||||||
|
|
||||||
stage1:
|
stage1:
|
||||||
mov ax, 0x07C0 ; BOOT_BLOCK_START_ADDRESS / 16
|
mov ax, 0x07c0 ; BOOT_BLOCK_START_ADDRESS / 16
|
||||||
mov ds, ax ; Setup segment registers
|
mov ds, ax ; Setup segment registers
|
||||||
mov es, ax
|
mov es, ax
|
||||||
mov ss, ax
|
mov ss, ax
|
||||||
|
|
||||||
mov sp, 0xFFFF - sizeof(Locals) ; Make stack empty
|
mov sp, 0xFFFF - sizeof(Locals) ; Make stack empty
|
||||||
mov bp, sp
|
mov bp, sp
|
||||||
|
|
||||||
cld ; String operations increment index registers
|
mov [bootDrive], dl ; Store boot drive
|
||||||
|
cld ; String operations increment index
|
||||||
|
; registers
|
||||||
CLEAR_SCREEN
|
CLEAR_SCREEN
|
||||||
call hideCursor
|
call hideCursor
|
||||||
|
|
||||||
mov bh, 0 ; Text output on page 0
|
mov bh, 0 ; Text output on page 0
|
||||||
|
|
||||||
; Print title centered at row 2
|
; Print title centered at row 2
|
||||||
mov dx, 1 * 0x100 + (40 - TITLE_LENGTH / 2)
|
mov dx, 1 * 0x100 + (40 - TITLE_LENGTH / 2)
|
||||||
mov [bp + cursorPosition], dx
|
mov [bp + cursorPosition], dx
|
||||||
|
|
||||||
@@ -281,28 +277,28 @@ stage1:
|
|||||||
mov dx, (TEXT_ROWS-2) * 0x100 + (40 - SELECT_OS_MESSAGE_LENGTH / 2)
|
mov dx, (TEXT_ROWS-2) * 0x100 + (40 - SELECT_OS_MESSAGE_LENGTH / 2)
|
||||||
mov [bp + cursorPosition], dx
|
mov [bp + cursorPosition], dx
|
||||||
|
|
||||||
mov bl, LIGHT_GRAY
|
mov bl, LIGHT_GRAY
|
||||||
mov si, kSelectOSMessage
|
mov si, kSelectOSMessage
|
||||||
call printstr
|
call printstr
|
||||||
|
|
||||||
; Chain load rest of boot loader
|
; Chain load rest of boot loader
|
||||||
mov ah, EXTENDED_READ ; Load 3 more sectors
|
mov ah, EXTENDED_READ ; Load 3 more sectors
|
||||||
mov dl, 0x80 ; First HDD
|
mov dl, [bootDrive]
|
||||||
mov si, nextStageDAP
|
mov si, nextStageDAP
|
||||||
int BIOS_DISK_SERVICES
|
int BIOS_DISK_SERVICES
|
||||||
jc .error ; I/O error
|
jc .error ; I/O error
|
||||||
jmp stage2 ; Continue in loaded stage 2
|
jmp stage2 ; Continue in loaded stage 2
|
||||||
|
|
||||||
.error:
|
.error:
|
||||||
call showCursor
|
call showCursor
|
||||||
mov si, kError
|
mov si, kError
|
||||||
mov bl, RED
|
mov bl, RED
|
||||||
call printstr
|
call printstr
|
||||||
|
|
||||||
mov ah, READ_CHAR
|
mov ah, READ_CHAR
|
||||||
int BIOS_KEYBOARD_SERVICES
|
int BIOS_KEYBOARD_SERVICES
|
||||||
|
|
||||||
mov dl, 0x80
|
mov dl, [bootDrive]
|
||||||
int BIOS_REBOOT
|
int BIOS_REBOOT
|
||||||
|
|
||||||
printStringStage1:
|
printStringStage1:
|
||||||
@@ -312,10 +308,10 @@ hideCursor:
|
|||||||
mov ah, GET_CURSOR
|
mov ah, GET_CURSOR
|
||||||
int BIOS_VIDEO_SERVICES
|
int BIOS_VIDEO_SERVICES
|
||||||
mov [bp + cursorShape], cx
|
mov [bp + cursorShape], cx
|
||||||
|
|
||||||
mov ah, SET_CURSOR_SHAPE
|
mov ah, SET_CURSOR_SHAPE
|
||||||
mov cx, 0x2000
|
mov cx, 0x2000
|
||||||
int BIOS_VIDEO_SERVICES
|
int BIOS_VIDEO_SERVICES
|
||||||
ret
|
ret
|
||||||
|
|
||||||
showCursor:
|
showCursor:
|
||||||
@@ -324,7 +320,7 @@ showCursor:
|
|||||||
int BIOS_VIDEO_SERVICES
|
int BIOS_VIDEO_SERVICES
|
||||||
ret
|
ret
|
||||||
|
|
||||||
nextStageDAP:
|
nextStageDAP:
|
||||||
istruc AddressPacket
|
istruc AddressPacket
|
||||||
at AddressPacket.packet_size, db 0x10
|
at AddressPacket.packet_size, db 0x10
|
||||||
at AddressPacket.block_count, db 0x03
|
at AddressPacket.block_count, db 0x03
|
||||||
@@ -332,6 +328,9 @@ nextStageDAP:
|
|||||||
at AddressPacket.offset, dw 1
|
at AddressPacket.offset, dw 1
|
||||||
iend
|
iend
|
||||||
|
|
||||||
|
bootDrive:
|
||||||
|
db 0
|
||||||
|
|
||||||
kTitle:
|
kTitle:
|
||||||
db TITLE, 0x00
|
db TITLE, 0x00
|
||||||
kSelectOSMessage:
|
kSelectOSMessage:
|
||||||
@@ -367,21 +366,21 @@ kMBRSignature:
|
|||||||
stage2:
|
stage2:
|
||||||
mov ax, [defaultItem] ; Select default item
|
mov ax, [defaultItem] ; Select default item
|
||||||
mov [bp + selection], ax
|
mov [bp + selection], ax
|
||||||
|
|
||||||
mov ax, TICKS_PER_SECOND ; Calculate timeout ticks
|
mov ax, TICKS_PER_SECOND ; Calculate timeout ticks
|
||||||
mul word [timeout]
|
mul word [timeout]
|
||||||
mov bx, dx
|
mov bx, dx
|
||||||
push ax
|
push ax
|
||||||
|
|
||||||
mov ah, READ_CLOCK
|
mov ah, READ_CLOCK
|
||||||
int BIOS_TIME_SERVICES
|
int BIOS_TIME_SERVICES
|
||||||
|
|
||||||
pop ax ; Add current ticks
|
pop ax ; Add current ticks
|
||||||
add ax, dx
|
add ax, dx
|
||||||
adc bx, cx
|
adc bx, cx
|
||||||
mov [bp + timeoutTicks], ax
|
mov [bp + timeoutTicks], ax
|
||||||
mov [bp + timeoutTicks + 2], bx
|
mov [bp + timeoutTicks + 2], bx
|
||||||
|
|
||||||
mov al, [listItemCount] ; Calculate start row for menu
|
mov al, [listItemCount] ; Calculate start row for menu
|
||||||
shr al, 1
|
shr al, 1
|
||||||
mov bl, TEXT_ROWS / 2
|
mov bl, TEXT_ROWS / 2
|
||||||
@@ -422,21 +421,21 @@ isTimeoutReached:
|
|||||||
.returnTrue:
|
.returnTrue:
|
||||||
stc
|
stc
|
||||||
ret
|
ret
|
||||||
|
|
||||||
; ================== Wait for a key and do something with it ==================
|
; ================== Wait for a key and do something with it ==================
|
||||||
mainLoop:
|
mainLoop:
|
||||||
call printMenu
|
call printMenu
|
||||||
|
|
||||||
inputLoop:
|
inputLoop:
|
||||||
mov ah, READ_CHAR
|
mov ah, READ_CHAR
|
||||||
int BIOS_KEYBOARD_SERVICES ; AL = ASCII Code, AH = Scancode
|
int BIOS_KEYBOARD_SERVICES ; AL = ASCII Code, AH = Scancode
|
||||||
|
|
||||||
cmp ah, KEY_DOWN
|
cmp ah, KEY_DOWN
|
||||||
je selectNextPartition
|
je selectNextPartition
|
||||||
|
|
||||||
cmp ah, KEY_UP
|
cmp ah, KEY_UP
|
||||||
je selectPreviousPartition
|
je selectPreviousPartition
|
||||||
|
|
||||||
cmp ah, KEY_RETURN
|
cmp ah, KEY_RETURN
|
||||||
jne inputLoop
|
jne inputLoop
|
||||||
jmp bootSelectedPartition
|
jmp bootSelectedPartition
|
||||||
@@ -450,26 +449,26 @@ selectNextPartition:
|
|||||||
.done:
|
.done:
|
||||||
mov [bp + selection], ax
|
mov [bp + selection], ax
|
||||||
jmp mainLoop
|
jmp mainLoop
|
||||||
|
|
||||||
selectPreviousPartition:
|
selectPreviousPartition:
|
||||||
mov ax, [bp + selection]
|
mov ax, [bp + selection]
|
||||||
or ax, ax
|
or ax, ax
|
||||||
jnz .done ; At top of list?
|
jnz .done ; At top of list?
|
||||||
mov ax, [listItemCount] ; Then jump to last entry
|
mov ax, [listItemCount] ; Then jump to last entry
|
||||||
.done:
|
.done:
|
||||||
dec ax
|
dec ax
|
||||||
mov [bp + selection], ax
|
mov [bp + selection], ax
|
||||||
jmp mainLoop
|
jmp mainLoop
|
||||||
|
|
||||||
|
|
||||||
; ======================= Print the OS list ============================
|
; ======================= Print the OS list ============================
|
||||||
printMenu:
|
printMenu:
|
||||||
mov al, [bp + firstLine]
|
mov al, [bp + firstLine]
|
||||||
mov [bp + cursorY], al
|
mov [bp + cursorY], al
|
||||||
|
|
||||||
mov si, list ; Start at top of list
|
mov si, list ; Start at top of list
|
||||||
xor cx, cx ; The index of the current item
|
xor cx, cx ; The index of the current item
|
||||||
|
|
||||||
.loop:
|
.loop:
|
||||||
lodsb ; String length incl. 0-terminator
|
lodsb ; String length incl. 0-terminator
|
||||||
add al, 3 ; center menu item
|
add al, 3 ; center menu item
|
||||||
@@ -493,17 +492,17 @@ printMenu:
|
|||||||
.print:
|
.print:
|
||||||
call printstr
|
call printstr
|
||||||
add si, sizeof(BootLoaderAddress)
|
add si, sizeof(BootLoaderAddress)
|
||||||
|
|
||||||
add byte [bp + cursorX], 1
|
add byte [bp + cursorX], 1
|
||||||
mov al, TRIANGLE_TO_LEFT
|
mov al, TRIANGLE_TO_LEFT
|
||||||
call updateMarker
|
call updateMarker
|
||||||
|
|
||||||
inc byte [bp + cursorY]
|
inc byte [bp + cursorY]
|
||||||
inc cx
|
inc cx
|
||||||
|
|
||||||
cmp cx, [listItemCount]
|
cmp cx, [listItemCount]
|
||||||
jne .loop
|
jne .loop
|
||||||
ret
|
ret
|
||||||
|
|
||||||
updateMarker:
|
updateMarker:
|
||||||
cmp cx, [bp + selection]
|
cmp cx, [bp + selection]
|
||||||
@@ -520,10 +519,10 @@ bootSelectedPartition:
|
|||||||
|
|
||||||
call showCursor
|
call showCursor
|
||||||
|
|
||||||
call getSelectedBootLoaderAddress
|
call getSelectedBootLoaderAddress
|
||||||
lodsb ; Set boot drive
|
lodsb ; Set boot drive
|
||||||
mov dl, al
|
mov dl, al
|
||||||
|
|
||||||
mov di, bootSectorDAP+AddressPacket.offset ; Copy start sector
|
mov di, bootSectorDAP+AddressPacket.offset ; Copy start sector
|
||||||
mov cx, 4 ; It is stored in a quad word
|
mov cx, 4 ; It is stored in a quad word
|
||||||
.copy_start_sector
|
.copy_start_sector
|
||||||
@@ -541,39 +540,39 @@ bootSelectedPartition:
|
|||||||
cmp ax, MBR_SIGNATURE
|
cmp ax, MBR_SIGNATURE
|
||||||
mov si, kNoBootablePartitionError
|
mov si, kNoBootablePartitionError
|
||||||
jne printAndHalt ; Missing signature
|
jne printAndHalt ; Missing signature
|
||||||
|
|
||||||
CLEAR_SCREEN
|
CLEAR_SCREEN
|
||||||
|
|
||||||
; Print "Loading <name>" at top of screen
|
; Print "Loading <name>" at top of screen
|
||||||
mov word [bp + cursorPosition], 0
|
mov word [bp + cursorPosition], 0
|
||||||
mov si, kLoadingMessage
|
mov si, kLoadingMessage
|
||||||
mov bl, LIGHT_GRAY
|
mov bl, LIGHT_GRAY
|
||||||
call printstr
|
call printstr
|
||||||
|
|
||||||
inc byte [bp + cursorX]
|
inc byte [bp + cursorX]
|
||||||
call getSelectedMenuItem
|
call getSelectedMenuItem
|
||||||
inc si ; Skip string length byte
|
inc si ; Skip string length byte
|
||||||
call printstr
|
call printstr
|
||||||
|
|
||||||
mov dx, 0x100
|
mov dx, 0x100
|
||||||
xor bh, bh
|
xor bh, bh
|
||||||
mov ah, SET_CURSOR
|
mov ah, SET_CURSOR
|
||||||
int BIOS_VIDEO_SERVICES
|
int BIOS_VIDEO_SERVICES
|
||||||
|
|
||||||
call getSelectedBootLoaderAddress
|
call getSelectedBootLoaderAddress
|
||||||
mov dl, [si] ; drive number in dl
|
mov dl, [si] ; drive number in dl
|
||||||
|
|
||||||
jmp $$ ; Start loaded boot loader
|
jmp $$ ; Start loaded boot loader
|
||||||
|
|
||||||
|
|
||||||
printAndHalt:
|
printAndHalt:
|
||||||
mov dx, (TEXT_ROWS-4) * 0x100 + (TEXT_COLUMNS / 3)
|
mov dx, (TEXT_ROWS-4) * 0x100 + (TEXT_COLUMNS / 3)
|
||||||
mov [bp + cursorPosition], dx
|
mov [bp + cursorPosition], dx
|
||||||
|
|
||||||
mov bx, 0x0F ; Page number and foreground color
|
mov bx, 0x0F ; Page number and foreground color
|
||||||
call printstr
|
call printstr
|
||||||
mov ah, READ_CHAR
|
mov ah, READ_CHAR
|
||||||
int BIOS_KEYBOARD_SERVICES
|
int BIOS_KEYBOARD_SERVICES
|
||||||
mov dl, 0x80
|
mov dl, 0x80
|
||||||
int BIOS_REBOOT
|
int BIOS_REBOOT
|
||||||
|
|
||||||
@@ -582,15 +581,15 @@ printAndHalt:
|
|||||||
; Trashes:
|
; Trashes:
|
||||||
; ax, cx
|
; ax, cx
|
||||||
getSelectedMenuItem:
|
getSelectedMenuItem:
|
||||||
mov si, list ; Search address of start sector
|
mov si, list ; Search address of start sector
|
||||||
; of the selected item.
|
; of the selected item.
|
||||||
mov cx, [bp + selection]
|
mov cx, [bp + selection]
|
||||||
inc cx ; Number of required iterations
|
inc cx ; Number of required iterations
|
||||||
|
|
||||||
xor ah, ah ; The high-byte of the string length
|
xor ah, ah ; The high-byte of the string length
|
||||||
; see loop body
|
; see loop body
|
||||||
jmp .entry
|
jmp .entry
|
||||||
|
|
||||||
.loop:
|
.loop:
|
||||||
lodsb ; Length of menu item name
|
lodsb ; Length of menu item name
|
||||||
add si, ax ; Skip name to BootLoaderAddess
|
add si, ax ; Skip name to BootLoaderAddess
|
||||||
@@ -598,13 +597,20 @@ getSelectedMenuItem:
|
|||||||
|
|
||||||
.entry:
|
.entry:
|
||||||
loop .loop
|
loop .loop
|
||||||
ret
|
ret
|
||||||
|
|
||||||
getSelectedBootLoaderAddress:
|
getSelectedBootLoaderAddress:
|
||||||
call getSelectedMenuItem
|
call getSelectedMenuItem
|
||||||
lodsb
|
lodsb
|
||||||
xor ah, ah
|
xor ah, ah
|
||||||
add si, ax ; Skip name
|
add si, ax ; Skip name
|
||||||
|
mov dl, [si]
|
||||||
|
test dl, 0 ; if drive is 0, use boot drive
|
||||||
|
jz .takeOverBootDrive
|
||||||
|
ret
|
||||||
|
.takeOverBootDrive:
|
||||||
|
mov dl, [bootDrive]
|
||||||
|
mov [si], dl
|
||||||
ret
|
ret
|
||||||
|
|
||||||
printStringStage2:
|
printStringStage2:
|
||||||
@@ -617,13 +623,13 @@ printChar:
|
|||||||
push bx
|
push bx
|
||||||
push cx
|
push cx
|
||||||
push dx
|
push dx
|
||||||
|
|
||||||
xor bh, bh ; Write on page 0
|
xor bh, bh ; Write on page 0
|
||||||
|
|
||||||
mov dx, [bp + cursorPosition]
|
mov dx, [bp + cursorPosition]
|
||||||
mov ah, SET_CURSOR
|
mov ah, SET_CURSOR
|
||||||
int BIOS_VIDEO_SERVICES
|
int BIOS_VIDEO_SERVICES
|
||||||
|
|
||||||
inc byte [bp + cursorX]
|
inc byte [bp + cursorX]
|
||||||
|
|
||||||
mov cx, 1
|
mov cx, 1
|
||||||
@@ -635,7 +641,7 @@ printChar:
|
|||||||
pop bx
|
pop bx
|
||||||
pop ax
|
pop ax
|
||||||
ret
|
ret
|
||||||
|
|
||||||
; ================================ DATA ===========================
|
; ================================ DATA ===========================
|
||||||
|
|
||||||
bootSectorDAP:
|
bootSectorDAP:
|
||||||
@@ -646,7 +652,7 @@ bootSectorDAP:
|
|||||||
iend
|
iend
|
||||||
|
|
||||||
kColorTable:
|
kColorTable:
|
||||||
db BLUE, RED, GREEN, CYAN
|
db BLUE, RED, GREEN, CYAN
|
||||||
kReadError:
|
kReadError:
|
||||||
db 'Error loading sectors', 0x00
|
db 'Error loading sectors', 0x00
|
||||||
kNoBootablePartitionError:
|
kNoBootablePartitionError:
|
||||||
@@ -659,7 +665,7 @@ listItemCount:
|
|||||||
defaultItem equ listItemCount + 2
|
defaultItem equ listItemCount + 2
|
||||||
timeout equ defaultItem + 2
|
timeout equ defaultItem + 2
|
||||||
list equ timeout + 2
|
list equ timeout + 2
|
||||||
|
|
||||||
; dw number of entries
|
; dw number of entries
|
||||||
; dw the default entry
|
; dw the default entry
|
||||||
; dw the timeout (-1 for none)
|
; dw the timeout (-1 for none)
|
||||||
@@ -671,9 +677,9 @@ list equ timeout + 2
|
|||||||
|
|
||||||
%if USE_TEST_MENU
|
%if USE_TEST_MENU
|
||||||
dw 0x06
|
dw 0x06
|
||||||
|
|
||||||
dw 2
|
dw 2
|
||||||
|
|
||||||
dw 5
|
dw 5
|
||||||
|
|
||||||
db 0x06
|
db 0x06
|
||||||
@@ -705,7 +711,7 @@ list equ timeout + 2
|
|||||||
db 'OpenBSD', 0
|
db 'OpenBSD', 0
|
||||||
db 0x80
|
db 0x80
|
||||||
dw 0xAAAA, 0, 0, 0
|
dw 0xAAAA, 0, 0, 0
|
||||||
|
|
||||||
dw kStage1UnusedSpace
|
dw kStage1UnusedSpace
|
||||||
%endif
|
%endif
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user