Compare commits
53
Commits
315d8895a7
..
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
95de7ad674 | ||
|
|
4495b81769 | ||
|
|
999b1a073e | ||
|
|
1433657697 | ||
|
|
59077f0f72 | ||
|
|
645150039a | ||
|
|
8a5557f4ae | ||
|
|
b20a1640b2 | ||
|
|
aca9f459ed | ||
|
|
ef469ab043 | ||
|
|
d2f4137894 | ||
|
|
94b2105cd6 | ||
|
|
1d618ea39d | ||
|
|
c6694f6a28 | ||
|
|
631fec7c4d | ||
|
|
68c741d54d | ||
|
|
f9487b63b0 | ||
|
|
1a3dc080e6 | ||
|
|
1a227504e2 | ||
|
|
69d8927c12 | ||
|
|
9b5fd077d2 | ||
|
|
889415b22a | ||
|
|
da94e21dbe | ||
|
|
501783e9ae | ||
|
|
f1f2f2aa25 | ||
|
|
f2d08a85a5 | ||
|
|
44189938d7 | ||
|
|
c6536260c3 | ||
|
|
d22ff2cbc4 | ||
|
|
48d8902e98 | ||
|
|
b4349511f4 | ||
|
|
b42b16add7 | ||
|
|
8fd18eef4d | ||
|
|
1e7afa11d7 | ||
|
|
1cfcd76588 | ||
|
|
179f76114b | ||
|
|
65e559596b | ||
|
|
98c11ee33b | ||
|
|
2f4fec9ab9 | ||
|
|
a38e29c59d | ||
|
|
c6a435ed36 | ||
|
|
2e22ebf0b5 | ||
|
|
cd6269d406 | ||
|
|
9a9a4fe8c0 | ||
|
|
f163dacce5 | ||
|
|
7e7ca3d929 | ||
|
|
c00f37b930 | ||
|
|
ace5edfda2 | ||
|
|
17813f3fcf | ||
|
|
cce6e417df | ||
|
|
8eb572d038 | ||
|
|
cee65bd68e | ||
|
|
74d7a48c4b |
@@ -9,7 +9,7 @@ This is my hobby operating system written in C++. Currently supports x86\_64 and
|
||||
|
||||
You can find a live demo [here](https://bananymous.com/banan-os)
|
||||
|
||||
If you want to try out DOOM, you should first enter the GUI environment using the `start-gui` command. Then you can run `doom` in the GUI terminal.
|
||||

|
||||
|
||||
### Features
|
||||
|
||||
@@ -18,6 +18,8 @@ If you want to try out DOOM, you should first enter the GUI environment using th
|
||||
- [x] SMP (multiprocessing)
|
||||
- [x] Linear framebuffer (VESA and GOP)
|
||||
- [x] Network stack
|
||||
- [x] USB stack
|
||||
- [x] Audio support
|
||||
- [x] ELF executable loading
|
||||
- [x] AML interpreter (partial)
|
||||
- [x] Basic graphical environment
|
||||
@@ -27,16 +29,14 @@ If you want to try out DOOM, you should first enter the GUI environment using th
|
||||
- [ ] Some nice apps
|
||||
- [x] ELF dynamic linking
|
||||
- [x] copy-on-write memory
|
||||
- [x] file mappings
|
||||
- [ ] anonymous mappings
|
||||
|
||||
#### Drivers
|
||||
- [x] NVMe disks
|
||||
- [x] ATA (IDE, SATA) disks
|
||||
- [x] E1000 and E1000E NICs
|
||||
- [x] RTL8111/8168/8211/8411 NICs
|
||||
- [x] PS2 keyboard (all scancode sets)
|
||||
- [x] PS2 mouse
|
||||
- [x] AC97 and iHDA audio cards
|
||||
- [x] PS2 keyboard and mouse
|
||||
- [x] USB
|
||||
- [x] xHCI
|
||||
- [ ] EHCI
|
||||
@@ -46,7 +46,8 @@ If you want to try out DOOM, you should first enter the GUI environment using th
|
||||
- [x] Mouse
|
||||
- [x] Mass storage
|
||||
- [x] Hubs
|
||||
- [ ] ...
|
||||
- [ ] Network
|
||||
- [ ] Audio
|
||||
- [ ] virtio devices (network, storage)
|
||||
|
||||
#### Network
|
||||
@@ -54,7 +55,7 @@ If you want to try out DOOM, you should first enter the GUI environment using th
|
||||
- [x] ICMP
|
||||
- [x] IPv4
|
||||
- [x] UDP
|
||||
- [x] TCP (partial and buggy)
|
||||
- [x] TCP
|
||||
- [x] Unix domain sockets
|
||||
- [ ] SSL
|
||||
|
||||
@@ -65,7 +66,6 @@ If you want to try out DOOM, you should first enter the GUI environment using th
|
||||
- [x] Dev
|
||||
- [x] Ram
|
||||
- [x] Proc
|
||||
- [ ] Sys
|
||||
- [ ] 9P
|
||||
|
||||
#### Bootloader support
|
||||
@@ -73,8 +73,6 @@ If you want to try out DOOM, you should first enter the GUI environment using th
|
||||
- [x] Custom BIOS bootloader
|
||||
- [ ] Custom UEFI bootloader
|
||||
|
||||

|
||||
|
||||
## Code structure
|
||||
|
||||
Each major component and library has its own subdirectory (kernel, userspace, libc, ...). Each directory contains directory *include*, which has **all** of the header files of the component. Every header is included by its absolute path.
|
||||
@@ -125,8 +123,22 @@ If you have corrupted your disk image or want to create new one, you can either
|
||||
./bos image-full
|
||||
```
|
||||
|
||||
To test on real hardware, I have a script to generate a compressed ISO. The ISO can be copied directly to an USB drive with for example `dd`. The file is created at build/banan-os.iso and can be generated with
|
||||
```sh
|
||||
./bos iso
|
||||
```
|
||||
|
||||
I have also created shell completion script for zsh. You can either copy the file in _script/shell-completion/zsh/\_bos_ to _/usr/share/zsh/site-functions/_ or add the _script/shell-completion/zsh_ to your fpath in _.zshrc_.
|
||||
|
||||
### Package Manager
|
||||
|
||||
banan-os uses xbps as its package manager for ports. All upstream ports are packaged into xbps packages hosted on a [repository on my server](https://packages.bananymous.com/banan-os). You can manage sysroot's xbps packages with `./bos` wrapper. You can use `xbps-install`, `xbps-remove` and `xbps-query` with repository and sysroot set to the correct values. For example to install xbps that can be used inside banan-os you can use
|
||||
```sh
|
||||
./bos xbps-install -S xbps
|
||||
```
|
||||
For xbps usage see [their documentation](https://docs.voidlinux.org/xbps/index.html).
|
||||
|
||||
|
||||
## Contributing
|
||||
|
||||
As the upstream is hosted on my server https://git.bananymous.com/Bananymous/banan-os, merging contributions is not as trivial as it would be on GitHub. You can still send PRs in GitHub in which case I should be able to download the diff and apply it manually. If you want, I can also provide you an account to my git server. In this case please contact me ([email](mailto:[email protected]), [discord](https://discord.gg/ehjGySwYdK)).
|
||||
|
||||
@@ -41,6 +41,7 @@ set(KERNEL_SOURCES
|
||||
kernel/FS/USTARModule.cpp
|
||||
kernel/FS/VirtualFileSystem.cpp
|
||||
kernel/GDT.cpp
|
||||
kernel/Graphics/BGA.cpp
|
||||
kernel/IDT.cpp
|
||||
kernel/Input/InputDevice.cpp
|
||||
kernel/Input/PS2/Controller.cpp
|
||||
|
||||
@@ -54,6 +54,7 @@ namespace Kernel::ACPI
|
||||
|
||||
BAN::ErrorOr<void> initialize_embedded_controller(const AML::Scope& embedded_controller);
|
||||
BAN::ErrorOr<void> initialize_embedded_controllers();
|
||||
void initialize_embedded_controller_gpes();
|
||||
|
||||
BAN::Optional<GAS> find_gpe_block(size_t index);
|
||||
bool enable_gpe(uint8_t gpe);
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace Kernel::ACPI
|
||||
class EmbeddedController
|
||||
{
|
||||
public:
|
||||
static BAN::ErrorOr<BAN::UniqPtr<EmbeddedController>> create(AML::Scope&& scope, uint16_t command_port, uint16_t data_port, BAN::Optional<uint8_t> gpe);
|
||||
static BAN::ErrorOr<BAN::UniqPtr<EmbeddedController>> create(AML::Scope&& scope, uint16_t command_port, uint16_t data_port);
|
||||
~EmbeddedController();
|
||||
|
||||
BAN::ErrorOr<uint8_t> read_byte(uint8_t offset);
|
||||
@@ -22,21 +22,21 @@ namespace Kernel::ACPI
|
||||
|
||||
const AML::Scope& scope() const { return m_scope; }
|
||||
|
||||
static void handle_gpe_trampoline(void*);
|
||||
|
||||
private:
|
||||
EmbeddedController(AML::Scope&& scope, uint16_t command_port, uint16_t data_port, bool has_gpe)
|
||||
EmbeddedController(AML::Scope&& scope, uint16_t command_port, uint16_t data_port)
|
||||
: m_scope(BAN::move(scope))
|
||||
, m_command_port(command_port)
|
||||
, m_data_port(data_port)
|
||||
, m_has_gpe(has_gpe)
|
||||
{ }
|
||||
|
||||
private:
|
||||
void wait_status_bit(uint8_t bit, uint8_t value);
|
||||
void wait_status_bit(uint8_t mask, bool set);
|
||||
|
||||
uint8_t read_one(uint16_t port);
|
||||
void write_one(uint16_t port, uint8_t value);
|
||||
|
||||
static void handle_gpe_wrapper(void*);
|
||||
void handle_gpe();
|
||||
|
||||
BAN::ErrorOr<void> call_query_method(uint8_t notification);
|
||||
@@ -57,7 +57,6 @@ namespace Kernel::ACPI
|
||||
const AML::Scope m_scope;
|
||||
const uint16_t m_command_port;
|
||||
const uint16_t m_data_port;
|
||||
const bool m_has_gpe;
|
||||
|
||||
Mutex m_mutex;
|
||||
ThreadBlocker m_thread_blocker;
|
||||
|
||||
@@ -6,15 +6,22 @@
|
||||
namespace Kernel
|
||||
{
|
||||
|
||||
class BGAController;
|
||||
|
||||
class FramebufferDevice : public CharacterDevice
|
||||
{
|
||||
public:
|
||||
static BAN::ErrorOr<BAN::RefPtr<FramebufferDevice>> create(paddr_t paddr, uint32_t width, uint32_t height, uint32_t pitch, uint8_t bpp);
|
||||
static BAN::ErrorOr<BAN::RefPtr<FramebufferDevice>> create(BAN::RefPtr<BGAController>);
|
||||
static BAN::ErrorOr<BAN::RefPtr<FramebufferDevice>> create_from_boot_framebuffer();
|
||||
static BAN::RefPtr<FramebufferDevice> boot_framebuffer();
|
||||
~FramebufferDevice();
|
||||
|
||||
uint32_t width() const { return m_width; }
|
||||
uint32_t height() const { return m_height; }
|
||||
uint8_t bpp() const { return m_bpp; }
|
||||
|
||||
BAN::ErrorOr<void> set_bga_controller(BAN::RefPtr<BGAController>);
|
||||
|
||||
uint32_t get_pixel(uint32_t x, uint32_t y) const;
|
||||
void set_pixel(uint32_t x, uint32_t y, uint32_t rgb);
|
||||
@@ -51,13 +58,15 @@ namespace Kernel
|
||||
const BAN::String m_name;
|
||||
|
||||
vaddr_t m_video_memory_vaddr { 0 };
|
||||
const paddr_t m_video_memory_paddr;
|
||||
const uint32_t m_width;
|
||||
const uint32_t m_height;
|
||||
const uint32_t m_pitch;
|
||||
const uint8_t m_bpp;
|
||||
paddr_t m_video_memory_paddr { 0 };
|
||||
|
||||
uint32_t m_width { 0 };
|
||||
uint32_t m_height { 0 };
|
||||
uint32_t m_pitch { 0 };
|
||||
uint8_t m_bpp { 0 };
|
||||
|
||||
BAN::UniqPtr<VirtualRange> m_video_buffer;
|
||||
BAN::RefPtr<BGAController> m_bga_controller;
|
||||
|
||||
friend class FramebufferMemoryRegion;
|
||||
};
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
#pragma once
|
||||
|
||||
#include <BAN/RefPtr.h>
|
||||
#include <kernel/Lock/SpinLock.h>
|
||||
#include <kernel/PCI.h>
|
||||
|
||||
#include <sys/framebuffer.h>
|
||||
|
||||
namespace Kernel
|
||||
{
|
||||
|
||||
class BGAController : public BAN::RefCounted<BGAController>
|
||||
{
|
||||
public:
|
||||
static BAN::ErrorOr<BAN::RefPtr<BGAController>> create(PCI::Device&);
|
||||
|
||||
fb_fix_info get_fb_fix_info() const;
|
||||
fb_var_info get_fb_var_info() const;
|
||||
BAN::ErrorOr<void> set_fb_var_info(const fb_var_info&);
|
||||
|
||||
private:
|
||||
BGAController(PCI::Device&);
|
||||
BAN::ErrorOr<void> initialize();
|
||||
|
||||
void write_reg(uint16_t reg, uint16_t value);
|
||||
uint16_t read_reg(uint16_t reg);
|
||||
|
||||
private:
|
||||
mutable RecursiveSpinLock m_lock;
|
||||
PCI::Device& m_pci_device;
|
||||
BAN::UniqPtr<PCI::BarRegion> m_lfb_bar;
|
||||
|
||||
fb_fix_info m_fix_info {};
|
||||
fb_var_info m_var_info {};
|
||||
};
|
||||
|
||||
}
|
||||
@@ -61,9 +61,6 @@ namespace Kernel
|
||||
uint32_t m_lock_depth { 0 };
|
||||
};
|
||||
|
||||
template<typename Lock>
|
||||
class SpinLockGuardAsMutex;
|
||||
|
||||
template<typename Lock>
|
||||
class SpinLockGuard
|
||||
{
|
||||
@@ -85,7 +82,6 @@ namespace Kernel
|
||||
private:
|
||||
Lock& m_lock;
|
||||
InterruptState m_state;
|
||||
friend class SpinLockGuardAsMutex<Lock>;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -286,7 +286,7 @@ namespace Kernel
|
||||
BAN::ErrorOr<FileParent> find_parent_file(int fd, const char* path, int flags) const;
|
||||
BAN::ErrorOr<VirtualFileSystem::File> find_relative_parent(int fd, const char* path) const;
|
||||
|
||||
BAN::ErrorOr<MemoryRegion*> validate_and_pin_pointer_access(const void*, size_t, bool needs_write);
|
||||
BAN::ErrorOr<void> validate_and_pin_pointer_access(const void*, size_t, bool needs_write, BAN::Vector<MemoryRegion*>&);
|
||||
|
||||
uint64_t signal_pending_mask() const
|
||||
{
|
||||
|
||||
@@ -22,7 +22,6 @@ namespace Kernel
|
||||
class GDT;
|
||||
class IDT;
|
||||
class Scheduler;
|
||||
class SchedulerThreadNode;
|
||||
class Thread;
|
||||
|
||||
#if ARCH(x86_64) || ARCH(i686)
|
||||
@@ -54,8 +53,8 @@ namespace Kernel
|
||||
union
|
||||
{
|
||||
TLBEntry flush_tlb;
|
||||
SchedulerThreadNode* new_thread;
|
||||
SchedulerThreadNode* unblock_thread;
|
||||
Thread* new_thread;
|
||||
Thread* unblock_thread;
|
||||
bool dummy;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -41,9 +41,8 @@ namespace Kernel
|
||||
void on_timer_interrupt();
|
||||
void on_yield(YieldRegisters*);
|
||||
|
||||
static BAN::ErrorOr<void> bind_thread_to_processor(Thread*, ProcessorID);
|
||||
// if thread is already bound, this will never fail
|
||||
BAN::ErrorOr<void> add_thread(Thread*);
|
||||
static void bind_thread_to_processor(Thread*, ProcessorID);
|
||||
void add_thread(Thread*);
|
||||
|
||||
void block_current_thread(ThreadBlocker* thread_blocker, uint64_t wake_time_ns, BaseMutex* mutex);
|
||||
void unblock_thread(Thread*);
|
||||
@@ -68,9 +67,6 @@ namespace Kernel
|
||||
|
||||
class ProcessorID find_least_loaded_processor() const;
|
||||
|
||||
void add_thread(SchedulerThreadNode*);
|
||||
void unblock_thread(SchedulerThreadNode*);
|
||||
|
||||
private:
|
||||
SchedulerQueue m_run_list;
|
||||
SchedulerHeap m_block_list;
|
||||
|
||||
@@ -53,6 +53,8 @@ namespace Kernel
|
||||
|
||||
virtual bool master_has_closed() const { return false; }
|
||||
|
||||
virtual bool is_vtty() const { return false; }
|
||||
|
||||
protected:
|
||||
TTY(termios termios, mode_t mode, uid_t uid, gid_t gid);
|
||||
|
||||
@@ -100,9 +102,9 @@ namespace Kernel
|
||||
termios m_termios;
|
||||
|
||||
protected:
|
||||
Mutex m_mutex;
|
||||
Mutex m_input_mutex;
|
||||
|
||||
Mutex m_write_lock;
|
||||
RecursiveSpinLock m_write_lock;
|
||||
ThreadBlocker m_write_blocker;
|
||||
};
|
||||
|
||||
|
||||
@@ -21,6 +21,9 @@ namespace Kernel
|
||||
|
||||
void clear() override;
|
||||
|
||||
bool is_vtty() const override { return true; }
|
||||
BAN::ErrorOr<void> set_terminal_driver(BAN::RefPtr<TerminalDriver>);
|
||||
|
||||
protected:
|
||||
BAN::StringView name() const override { return m_name; }
|
||||
bool putchar_impl(uint8_t ch) override;
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <kernel/InterruptStack.h>
|
||||
#include <kernel/Lock/Mutex.h>
|
||||
#include <kernel/Memory/VirtualRange.h>
|
||||
#include <kernel/SchedulerThreadNode.h>
|
||||
|
||||
#include <LibELF/AuxiliaryVector.h>
|
||||
|
||||
@@ -192,7 +193,7 @@ namespace Kernel
|
||||
vaddr_t m_fsbase { 0 };
|
||||
vaddr_t m_gsbase { 0 };
|
||||
|
||||
SchedulerThreadNode* m_scheduler_node { nullptr };
|
||||
SchedulerThreadNode m_scheduler_node;
|
||||
|
||||
YieldRegisters m_yield_registers { };
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ namespace Kernel
|
||||
Hub = 0x09,
|
||||
BillboardDeviceClass = 0x11,
|
||||
DiagnosticDevice = 0xDC,
|
||||
WirelessController = 0xE0,
|
||||
Miscellaneous = 0xEF,
|
||||
VendorSpecific = 0xFF,
|
||||
};
|
||||
|
||||
+64
-55
@@ -784,26 +784,6 @@ acpi_release_global_lock:
|
||||
|
||||
BAN::ErrorOr<void> ACPI::initialize_embedded_controller(const AML::Scope& embedded_controller)
|
||||
{
|
||||
BAN::Optional<uint8_t> gpe_int;
|
||||
|
||||
do {
|
||||
auto [gpe_path, gpe_obj] = TRY(m_namespace->find_named_object(embedded_controller, TRY(AML::NameString::from_string("_GPE"_sv)), true));
|
||||
if (gpe_obj == nullptr)
|
||||
{
|
||||
dwarnln("EC {} does not have _GPE", embedded_controller);
|
||||
break;
|
||||
}
|
||||
|
||||
auto gpe = TRY(AML::evaluate_node(gpe_path, gpe_obj->node));
|
||||
if (gpe.type == AML::Node::Type::Package)
|
||||
{
|
||||
dwarnln("TODO: EC {} has package _GPE");
|
||||
break;
|
||||
}
|
||||
|
||||
gpe_int = TRY(AML::convert_node(BAN::move(gpe), AML::ConvInteger, -1)).as.integer.value;
|
||||
} while (false);
|
||||
|
||||
auto [crs_path, crs_obj] = TRY(m_namespace->find_named_object(embedded_controller, TRY(AML::NameString::from_string("_CRS"_sv)), true));
|
||||
if (crs_obj == nullptr)
|
||||
{
|
||||
@@ -857,7 +837,7 @@ acpi_release_global_lock:
|
||||
const auto data_port = TRY(extract_io_port(crs_buffer));
|
||||
const auto command_port = TRY(extract_io_port(crs_buffer));
|
||||
|
||||
TRY(m_embedded_controllers.push_back(TRY(EmbeddedController::create(TRY(embedded_controller.copy()), command_port, data_port, gpe_int))));
|
||||
TRY(m_embedded_controllers.push_back(TRY(EmbeddedController::create(TRY(embedded_controller.copy()), command_port, data_port))));
|
||||
return {};
|
||||
}
|
||||
|
||||
@@ -877,6 +857,33 @@ acpi_release_global_lock:
|
||||
return {};
|
||||
}
|
||||
|
||||
void ACPI::initialize_embedded_controller_gpes()
|
||||
{
|
||||
const auto initialize_gpe = [this](EmbeddedController& embedded_controller) -> BAN::ErrorOr<void> {
|
||||
auto [gpe_path, gpe_obj] = TRY(m_namespace->find_named_object(embedded_controller.scope(), TRY(AML::NameString::from_string("_GPE"_sv)), true));
|
||||
if (gpe_obj == nullptr)
|
||||
{
|
||||
dprintln("EC {} does not have _GPE", embedded_controller.scope());
|
||||
return {};
|
||||
}
|
||||
|
||||
auto gpe = TRY(AML::evaluate_node(gpe_path, gpe_obj->node));
|
||||
if (gpe.type == AML::Node::Type::Package)
|
||||
{
|
||||
dwarnln("TODO: EC {} has package _GPE");
|
||||
return {};
|
||||
}
|
||||
|
||||
const auto gpe_int = TRY(AML::convert_node(BAN::move(gpe), AML::ConvInteger, -1)).as.integer.value;
|
||||
TRY(register_gpe_handler(gpe_int, &EmbeddedController::handle_gpe_trampoline, &embedded_controller));
|
||||
|
||||
return {};
|
||||
};
|
||||
|
||||
for (auto& embedded_controller : m_embedded_controllers)
|
||||
(void)initialize_gpe(*embedded_controller);
|
||||
}
|
||||
|
||||
BAN::ErrorOr<void> ACPI::register_gpe_handler(uint8_t gpe, void (*callback)(void*), void* argument)
|
||||
{
|
||||
if (m_gpe_methods[gpe].method)
|
||||
@@ -996,42 +1003,12 @@ acpi_release_global_lock:
|
||||
// FIXME: add support for GPE blocks inside the ACPI namespace
|
||||
}
|
||||
|
||||
if (auto ret = initialize_embedded_controllers(); ret.is_error())
|
||||
dwarnln("Failed to initialize Embedded Controllers: {}", ret.error());
|
||||
|
||||
if (auto ret = m_namespace->post_load_initialize(); ret.is_error())
|
||||
dwarnln("Failed to initialize ACPI namespace: {}", ret.error());
|
||||
|
||||
auto [pic_path, pic_obj] = TRY(m_namespace->find_named_object({}, TRY(AML::NameString::from_string("\\_PIC"_sv))));
|
||||
if (pic_obj && pic_obj->node.type == AML::Node::Type::Method)
|
||||
{
|
||||
auto& pic_node = pic_obj->node;
|
||||
if (pic_node.as.method.arg_count != 1)
|
||||
{
|
||||
dwarnln("Method \\_PIC has {} arguments, expected 1", pic_node.as.method.arg_count);
|
||||
return BAN::Error::from_errno(EINVAL);
|
||||
}
|
||||
|
||||
AML::Reference arg_ref;
|
||||
arg_ref.node.type = AML::Node::Type::Integer;
|
||||
arg_ref.node.as.integer.value = InterruptController::get().is_using_apic() ? 1 : 0;
|
||||
arg_ref.ref_count = 2;
|
||||
|
||||
BAN::Array<AML::Reference*, 7> arguments(nullptr);
|
||||
arguments[0] = &arg_ref; // method call should not delete argument
|
||||
TRY(AML::method_call(pic_path, pic_node, BAN::move(arguments)));
|
||||
}
|
||||
|
||||
dprintln("Evaluated \\_PIC({})", InterruptController::get().is_using_apic() ? 1 : 0);
|
||||
|
||||
uint8_t irq = fadt().sci_int;
|
||||
if (auto ret = InterruptController::get().reserve_irq(irq); ret.is_error())
|
||||
dwarnln("Could not enable ACPI interrupt: {}", ret.error());
|
||||
else
|
||||
{
|
||||
auto hex_sv_to_int =
|
||||
[](BAN::StringView sv) -> BAN::Optional<uint32_t>
|
||||
{
|
||||
const auto hex_sv_to_int = [](BAN::StringView sv) -> BAN::Optional<uint32_t> {
|
||||
uint32_t ret = 0;
|
||||
for (char c : sv)
|
||||
{
|
||||
@@ -1092,11 +1069,43 @@ acpi_release_global_lock:
|
||||
|
||||
if (auto thread_or_error = Thread::create_kernel([](void*) { get().acpi_event_task(); }, nullptr); thread_or_error.is_error())
|
||||
dwarnln("Failed to create ACPI thread, power button will not work: {}", thread_or_error.error());
|
||||
else if (auto ret = Processor::scheduler().add_thread(thread_or_error.value()); ret.is_error())
|
||||
dwarnln("Failed to create ACPI thread, power button will not work: {}", ret.error());
|
||||
else
|
||||
{
|
||||
Processor::scheduler().add_thread(thread_or_error.value());
|
||||
dprintln("Initialized ACPI interrupts");
|
||||
}
|
||||
}
|
||||
|
||||
dprintln("Initialized ACPI interrupts");
|
||||
if (auto ret = initialize_embedded_controllers(); ret.is_error())
|
||||
dwarnln("Failed to initialize Embedded Controllers: {}", ret.error());
|
||||
|
||||
if (auto ret = m_namespace->post_load_initialize(); ret.is_error())
|
||||
dwarnln("Failed to initialize ACPI namespace: {}", ret.error());
|
||||
|
||||
// NOTE: We cannot initialize EC GPEs before the post init is done, but post init does need ECs initialized
|
||||
initialize_embedded_controller_gpes();
|
||||
|
||||
auto [pic_path, pic_obj] = TRY(m_namespace->find_named_object({}, TRY(AML::NameString::from_string("\\_PIC"_sv))));
|
||||
if (pic_obj && pic_obj->node.type == AML::Node::Type::Method)
|
||||
{
|
||||
auto& pic_node = pic_obj->node;
|
||||
if (pic_node.as.method.arg_count != 1)
|
||||
{
|
||||
dwarnln("Method \\_PIC has {} arguments, expected 1", pic_node.as.method.arg_count);
|
||||
return BAN::Error::from_errno(EINVAL);
|
||||
}
|
||||
|
||||
AML::Reference arg_ref;
|
||||
arg_ref.node.type = AML::Node::Type::Integer;
|
||||
arg_ref.node.as.integer.value = InterruptController::get().is_using_apic() ? 1 : 0;
|
||||
arg_ref.ref_count = 2;
|
||||
|
||||
BAN::Array<AML::Reference*, 7> arguments(nullptr);
|
||||
arguments[0] = &arg_ref; // method call should not delete argument
|
||||
TRY(AML::method_call(pic_path, pic_node, BAN::move(arguments)));
|
||||
|
||||
dprintln("Evaluated \\_PIC({})", InterruptController::get().is_using_apic() ? 1 : 0);
|
||||
}
|
||||
|
||||
if (InterruptController::get().is_using_apic())
|
||||
{
|
||||
|
||||
@@ -494,8 +494,23 @@ namespace Kernel::ACPI::AML
|
||||
|
||||
return TRY(embedded_controller->read_byte(offset));
|
||||
}
|
||||
case GAS::AddressSpaceID::SMBus:
|
||||
case GAS::AddressSpaceID::SystemCMOS:
|
||||
if (byte_offset >= 64)
|
||||
{
|
||||
dwarnln("CMOS read from offset 0x{H}", byte_offset);
|
||||
return BAN::Error::from_errno(ENOTSUP);
|
||||
}
|
||||
switch (access_size)
|
||||
{
|
||||
case 1:
|
||||
IO::outb(0x70, offset);
|
||||
return IO::inb(0x71);
|
||||
default:
|
||||
dwarnln("{} byte read from CMOS offset {2H}", access_size, byte_offset);
|
||||
return BAN::Error::from_errno(EINVAL);
|
||||
}
|
||||
ASSERT_NOT_REACHED();
|
||||
case GAS::AddressSpaceID::SMBus:
|
||||
case GAS::AddressSpaceID::PCIBarTarget:
|
||||
case GAS::AddressSpaceID::IPMI:
|
||||
case GAS::AddressSpaceID::GeneralPurposeIO:
|
||||
@@ -581,8 +596,24 @@ namespace Kernel::ACPI::AML
|
||||
TRY(embedded_controller->write_byte(offset, value));
|
||||
return {};
|
||||
}
|
||||
case GAS::AddressSpaceID::SMBus:
|
||||
case GAS::AddressSpaceID::SystemCMOS:
|
||||
if (byte_offset >= 64)
|
||||
{
|
||||
dwarnln("CMOS write to offset 0x{H}", byte_offset);
|
||||
return BAN::Error::from_errno(ENOTSUP);
|
||||
}
|
||||
switch (access_size)
|
||||
{
|
||||
case 1:
|
||||
IO::outb(0x70, offset);
|
||||
IO::outb(0x71, value);
|
||||
break;
|
||||
default:
|
||||
dwarnln("{} byte write to CMOS offset {2H}", access_size, byte_offset);
|
||||
return BAN::Error::from_errno(EINVAL);
|
||||
}
|
||||
return {};
|
||||
case GAS::AddressSpaceID::SMBus:
|
||||
case GAS::AddressSpaceID::PCIBarTarget:
|
||||
case GAS::AddressSpaceID::IPMI:
|
||||
case GAS::AddressSpaceID::GeneralPurposeIO:
|
||||
|
||||
@@ -30,28 +30,18 @@ namespace Kernel::ACPI
|
||||
CMD_QUERY = 0x84,
|
||||
};
|
||||
|
||||
BAN::ErrorOr<BAN::UniqPtr<EmbeddedController>> EmbeddedController::create(AML::Scope&& scope, uint16_t command_port, uint16_t data_port, BAN::Optional<uint8_t> gpe)
|
||||
BAN::ErrorOr<BAN::UniqPtr<EmbeddedController>> EmbeddedController::create(AML::Scope&& scope, uint16_t command_port, uint16_t data_port)
|
||||
{
|
||||
auto* embedded_controller_ptr = new EmbeddedController(BAN::move(scope), command_port, data_port, gpe.has_value());
|
||||
auto* embedded_controller_ptr = new EmbeddedController(BAN::move(scope), command_port, data_port);
|
||||
if (embedded_controller_ptr == nullptr)
|
||||
return BAN::Error::from_errno(ENOMEM);
|
||||
|
||||
auto* thread = TRY(Thread::create_kernel([](void* ec) { static_cast<EmbeddedController*>(ec)->thread_task(); }, embedded_controller_ptr));
|
||||
TRY(Processor::scheduler().add_thread(thread));
|
||||
Processor::scheduler().add_thread(thread);
|
||||
|
||||
auto embedded_controller = BAN::UniqPtr<EmbeddedController>::adopt(embedded_controller_ptr);
|
||||
embedded_controller->m_thread = thread;
|
||||
|
||||
if (gpe.has_value())
|
||||
TRY(ACPI::get().register_gpe_handler(gpe.value(), &handle_gpe_wrapper, embedded_controller.ptr()));
|
||||
else
|
||||
{
|
||||
// FIXME: Restructure EC such that SCI_EVT can be polled.
|
||||
// Simple solution would be spawning another thread,
|
||||
// but that feels too hacky.
|
||||
dwarnln("TODO: SCI_EVT polling without GPE");
|
||||
}
|
||||
|
||||
return embedded_controller;
|
||||
}
|
||||
|
||||
@@ -95,26 +85,25 @@ namespace Kernel::ACPI
|
||||
|
||||
uint8_t EmbeddedController::read_one(uint16_t port)
|
||||
{
|
||||
wait_status_bit(STS_OBF, 1);
|
||||
wait_status_bit(STS_OBF, true);
|
||||
return IO::inb(port);
|
||||
}
|
||||
|
||||
void EmbeddedController::write_one(uint16_t port, uint8_t value)
|
||||
{
|
||||
wait_status_bit(STS_IBF, 0);
|
||||
wait_status_bit(STS_IBF, false);
|
||||
IO::outb(port, value);
|
||||
}
|
||||
|
||||
void EmbeddedController::wait_status_bit(uint8_t bit, uint8_t value)
|
||||
void EmbeddedController::wait_status_bit(uint8_t mask, bool set)
|
||||
{
|
||||
// FIXME: timeouts
|
||||
const uint8_t mask = 1 << bit;
|
||||
const uint8_t comp = value ? mask : 0;
|
||||
const uint8_t comp = set ? mask : 0;
|
||||
while ((IO::inb(m_command_port) & mask) != comp)
|
||||
continue;
|
||||
}
|
||||
|
||||
void EmbeddedController::handle_gpe_wrapper(void* embedded_controller)
|
||||
void EmbeddedController::handle_gpe_trampoline(void* embedded_controller)
|
||||
{
|
||||
static_cast<EmbeddedController*>(embedded_controller)->handle_gpe();
|
||||
}
|
||||
@@ -217,7 +206,7 @@ namespace Kernel::ACPI
|
||||
|
||||
for (;;)
|
||||
{
|
||||
Command* const command = m_queued_command.has_value() ? m_queued_command.value() : nullptr;
|
||||
auto* const command = m_queued_command.value_or(nullptr);
|
||||
m_queued_command.clear();
|
||||
|
||||
if (command == nullptr)
|
||||
@@ -226,12 +215,10 @@ namespace Kernel::ACPI
|
||||
continue;
|
||||
}
|
||||
|
||||
m_mutex.unlock();
|
||||
|
||||
if (command)
|
||||
{
|
||||
// TODO: use burst mode
|
||||
|
||||
m_mutex.unlock();
|
||||
|
||||
write_one(m_command_port, command->command);
|
||||
if (command->data1.has_value())
|
||||
write_one(m_data_port, command->data1.value());
|
||||
@@ -241,12 +228,9 @@ namespace Kernel::ACPI
|
||||
*command->response = read_one(m_data_port);
|
||||
|
||||
m_mutex.lock();
|
||||
|
||||
command->done = true;
|
||||
m_thread_blocker.unblock();
|
||||
m_mutex.unlock();
|
||||
}
|
||||
|
||||
m_mutex.lock();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -343,6 +343,7 @@ namespace Kernel
|
||||
using HDAudio::AFGWidget;
|
||||
case AFGWidget::Type::OutputConverter:
|
||||
case AFGWidget::Type::Mixer:
|
||||
case AFGWidget::Type::Selector:
|
||||
case AFGWidget::Type::PinComplex:
|
||||
break;
|
||||
default:
|
||||
@@ -439,6 +440,9 @@ namespace Kernel
|
||||
}
|
||||
break;
|
||||
|
||||
case AFGWidget::Type::Selector:
|
||||
break;
|
||||
|
||||
case AFGWidget::Type::PinComplex:
|
||||
// enable output and H-Phn
|
||||
TRY(m_controller->send_command({
|
||||
@@ -525,6 +529,7 @@ namespace Kernel
|
||||
|
||||
case AFGWidget::Type::OutputConverter:
|
||||
case AFGWidget::Type::Mixer:
|
||||
case AFGWidget::Type::Selector:
|
||||
break;
|
||||
|
||||
case AFGWidget::Type::PinComplex:
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include <kernel/Device/DeviceNumbers.h>
|
||||
#include <kernel/Device/FramebufferDevice.h>
|
||||
#include <kernel/FS/DevFS/FileSystem.h>
|
||||
#include <kernel/Graphics/BGA.h>
|
||||
#include <kernel/Memory/Heap.h>
|
||||
#include <kernel/Terminal/FramebufferTerminal.h>
|
||||
|
||||
@@ -26,19 +27,14 @@ namespace Kernel
|
||||
return s_boot_framebuffer;
|
||||
}
|
||||
|
||||
BAN::ErrorOr<BAN::RefPtr<FramebufferDevice>> FramebufferDevice::create_from_boot_framebuffer()
|
||||
BAN::ErrorOr<BAN::RefPtr<FramebufferDevice>> FramebufferDevice::create(paddr_t paddr, uint32_t width, uint32_t height, uint32_t pitch, uint8_t bpp)
|
||||
{
|
||||
ASSERT(g_boot_info.framebuffer.type == FramebufferInfo::Type::RGB);
|
||||
if (g_boot_info.framebuffer.bpp != 24 && g_boot_info.framebuffer.bpp != 32)
|
||||
if (bpp != 24 && bpp != 32)
|
||||
return BAN::Error::from_errno(ENOTSUP);
|
||||
auto* device_ptr = new FramebufferDevice(
|
||||
0660, 0, 900,
|
||||
makedev(DeviceNumber::Framebuffer, get_framebuffer_device_index()),
|
||||
g_boot_info.framebuffer.address,
|
||||
g_boot_info.framebuffer.width,
|
||||
g_boot_info.framebuffer.height,
|
||||
g_boot_info.framebuffer.pitch,
|
||||
g_boot_info.framebuffer.bpp
|
||||
paddr, width, height, pitch, bpp
|
||||
);
|
||||
if (device_ptr == nullptr)
|
||||
return BAN::Error::from_errno(ENOMEM);
|
||||
@@ -49,6 +45,33 @@ namespace Kernel
|
||||
return device;
|
||||
}
|
||||
|
||||
BAN::ErrorOr<BAN::RefPtr<FramebufferDevice>> FramebufferDevice::create(BAN::RefPtr<BGAController> bga_controller)
|
||||
{
|
||||
const auto fix_info = bga_controller->get_fb_fix_info();
|
||||
const auto var_info = bga_controller->get_fb_var_info();
|
||||
auto controller = TRY(create(
|
||||
fix_info.mem_start,
|
||||
var_info.xres,
|
||||
var_info.yres,
|
||||
fix_info.pitch,
|
||||
var_info.bpp
|
||||
));
|
||||
controller->m_bga_controller = bga_controller;
|
||||
return controller;
|
||||
}
|
||||
|
||||
BAN::ErrorOr<BAN::RefPtr<FramebufferDevice>> FramebufferDevice::create_from_boot_framebuffer()
|
||||
{
|
||||
s_boot_framebuffer = TRY(create(
|
||||
g_boot_info.framebuffer.address,
|
||||
g_boot_info.framebuffer.width,
|
||||
g_boot_info.framebuffer.height,
|
||||
g_boot_info.framebuffer.pitch,
|
||||
g_boot_info.framebuffer.bpp
|
||||
));
|
||||
return s_boot_framebuffer;
|
||||
}
|
||||
|
||||
FramebufferDevice::FramebufferDevice(mode_t mode, uid_t uid, gid_t gid, dev_t rdev, paddr_t paddr, uint32_t width, uint32_t height, uint32_t pitch, uint8_t bpp)
|
||||
: CharacterDevice(mode, uid, gid)
|
||||
, m_name(MUST(BAN::String::formatted("fb{}", minor(rdev))))
|
||||
@@ -65,16 +88,20 @@ namespace Kernel
|
||||
{
|
||||
if (m_video_memory_vaddr == 0)
|
||||
return;
|
||||
size_t video_memory_pages = range_page_count(m_video_memory_paddr, m_height * m_pitch);
|
||||
const size_t video_memory_bytes = m_bga_controller ? m_bga_controller->get_fb_fix_info().mem_size : m_height * m_pitch;
|
||||
const size_t video_memory_pages = range_page_count(m_video_memory_paddr, video_memory_bytes);
|
||||
PageTable::kernel().unmap_range(m_video_memory_vaddr, video_memory_pages * PAGE_SIZE);
|
||||
}
|
||||
|
||||
BAN::ErrorOr<void> FramebufferDevice::initialize()
|
||||
{
|
||||
size_t video_memory_pages = range_page_count(m_video_memory_paddr, m_height * m_pitch);
|
||||
const size_t video_memory_bytes = m_bga_controller ? m_bga_controller->get_fb_fix_info().mem_size : m_height * m_pitch;
|
||||
const size_t video_memory_pages = range_page_count(m_video_memory_paddr, video_memory_bytes);
|
||||
|
||||
m_video_memory_vaddr = PageTable::kernel().reserve_free_contiguous_pages(video_memory_pages, KERNEL_OFFSET);
|
||||
if (m_video_memory_vaddr == 0)
|
||||
return BAN::Error::from_errno(ENOMEM);
|
||||
|
||||
PageTable::kernel().map_range_at(
|
||||
m_video_memory_paddr & PAGE_ADDR_MASK,
|
||||
m_video_memory_vaddr,
|
||||
@@ -86,7 +113,7 @@ namespace Kernel
|
||||
m_video_buffer = TRY(VirtualRange::create_to_vaddr_range(
|
||||
PageTable::kernel(),
|
||||
{ KERNEL_OFFSET, UINTPTR_MAX },
|
||||
BAN::Math::div_round_up<size_t>(m_width * m_height * (BANAN_FB_BPP / 8), PAGE_SIZE) * PAGE_SIZE,
|
||||
video_memory_pages * PAGE_SIZE,
|
||||
PageTable::Flags::ReadWrite | PageTable::Flags::Present,
|
||||
false
|
||||
));
|
||||
@@ -94,6 +121,37 @@ namespace Kernel
|
||||
return {};
|
||||
}
|
||||
|
||||
BAN::ErrorOr<void> FramebufferDevice::set_bga_controller(BAN::RefPtr<BGAController> bga_controller)
|
||||
{
|
||||
ASSERT(!m_bga_controller);
|
||||
|
||||
if (auto var_info = bga_controller->get_fb_var_info(); var_info.bpp != 32)
|
||||
{
|
||||
var_info.bpp = 32;
|
||||
TRY(bga_controller->set_fb_var_info(var_info));
|
||||
}
|
||||
|
||||
const auto fix_info = bga_controller->get_fb_fix_info();
|
||||
const auto var_info = bga_controller->get_fb_var_info();
|
||||
|
||||
ASSERT(m_video_memory_vaddr);
|
||||
PageTable::kernel().unmap_range(m_video_memory_vaddr, m_height * m_pitch);
|
||||
|
||||
m_video_memory_vaddr = 0;
|
||||
m_video_memory_paddr = fix_info.mem_start;
|
||||
|
||||
m_width = var_info.xres;
|
||||
m_height = var_info.yres;
|
||||
m_pitch = fix_info.pitch;
|
||||
m_bpp = var_info.bpp;
|
||||
|
||||
m_bga_controller = bga_controller;
|
||||
|
||||
TRY(initialize());
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
BAN::ErrorOr<size_t> FramebufferDevice::read_impl(off_t offset, BAN::ByteSpan buffer)
|
||||
{
|
||||
// Reading from negative offset will fill buffer with framebuffer info
|
||||
|
||||
@@ -63,7 +63,7 @@ namespace Kernel
|
||||
}
|
||||
}, s_instance
|
||||
));
|
||||
MUST(Processor::scheduler().add_thread(updater_thread));
|
||||
Processor::scheduler().add_thread(updater_thread);
|
||||
|
||||
auto* disk_cache_drop_thread = MUST(Thread::create_kernel(
|
||||
[](void* _devfs)
|
||||
@@ -93,7 +93,7 @@ namespace Kernel
|
||||
}
|
||||
}, s_instance
|
||||
));
|
||||
MUST(Processor::scheduler().add_thread(disk_cache_drop_thread));
|
||||
Processor::scheduler().add_thread(disk_cache_drop_thread);
|
||||
|
||||
auto* disk_sync_thread = MUST(Thread::create_kernel(
|
||||
[](void* _devfs)
|
||||
@@ -129,7 +129,7 @@ namespace Kernel
|
||||
}
|
||||
}, s_instance
|
||||
));
|
||||
MUST(Processor::scheduler().add_thread(disk_sync_thread));
|
||||
Processor::scheduler().add_thread(disk_sync_thread);
|
||||
}
|
||||
|
||||
void DevFileSystem::initiate_disk_cache_drop()
|
||||
|
||||
@@ -0,0 +1,242 @@
|
||||
#include <kernel/Device/FramebufferDevice.h>
|
||||
#include <kernel/Graphics/BGA.h>
|
||||
#include <kernel/IO.h>
|
||||
#include <kernel/Terminal/FramebufferTerminal.h>
|
||||
#include <kernel/Terminal/VirtualTTY.h>
|
||||
|
||||
namespace Kernel
|
||||
{
|
||||
|
||||
enum BGA_IO_PORT : uint16_t
|
||||
{
|
||||
BGA_IO_PORT_INDEX = 0x1CE,
|
||||
BGA_IO_PORT_DATA = 0x1CF,
|
||||
};
|
||||
|
||||
enum BGA_REG : uint16_t
|
||||
{
|
||||
BGA_REG_ID = 0,
|
||||
BGA_REG_XRES = 1,
|
||||
BGA_REG_YRES = 2,
|
||||
BGA_REG_BPP = 3,
|
||||
BGA_REG_ENABLE = 4,
|
||||
BGA_REG_BANK = 5,
|
||||
BGA_REG_XRES_VIRT = 6,
|
||||
BGA_REG_YRES_VIRT = 7,
|
||||
BGA_REG_XOFF = 8,
|
||||
BGA_REG_YOFF = 9,
|
||||
};
|
||||
|
||||
enum BGA_ID : uint16_t
|
||||
{
|
||||
BGA_ID_0 = 0xB0C0,
|
||||
BGA_ID_1 = 0xB0C1,
|
||||
BGA_ID_2 = 0xB0C2,
|
||||
BGA_ID_3 = 0xB0C3,
|
||||
BGA_ID_4 = 0xB0C4,
|
||||
BGA_ID_5 = 0xB0C5,
|
||||
};
|
||||
|
||||
enum BGA_ENABLE : uint16_t
|
||||
{
|
||||
BGA_ENABLE_ENABLE = 0x01,
|
||||
BGA_ENABLE_LFB_ENABLE = 0x40,
|
||||
BGA_ENABLE_NOCLEARMEM = 0x80,
|
||||
};
|
||||
|
||||
BAN::ErrorOr<BAN::RefPtr<BGAController>> BGAController::create(PCI::Device& pci_device)
|
||||
{
|
||||
auto* bga_controller_ptr = new BGAController(pci_device);
|
||||
if (bga_controller_ptr == nullptr)
|
||||
return BAN::Error::from_errno(ENOMEM);
|
||||
auto bga_controller = BAN::RefPtr<BGAController>::adopt(bga_controller_ptr);
|
||||
TRY(bga_controller->initialize());
|
||||
return bga_controller;
|
||||
}
|
||||
|
||||
BGAController::BGAController(PCI::Device& pci_device)
|
||||
: m_pci_device(pci_device)
|
||||
{ }
|
||||
|
||||
BAN::ErrorOr<void> BGAController::initialize()
|
||||
{
|
||||
auto boot_framebuffer = FramebufferDevice::boot_framebuffer();
|
||||
|
||||
m_lfb_bar = TRY(m_pci_device.allocate_bar_region(0));
|
||||
if (m_lfb_bar->type() != PCI::BarType::MEM)
|
||||
{
|
||||
dwarnln("BGA LFB is not memory bar");
|
||||
return BAN::Error::from_errno(EINVAL);
|
||||
}
|
||||
|
||||
m_fix_info = {
|
||||
.xpanstep = 1,
|
||||
.ypanstep = 1,
|
||||
.pitch = 0,
|
||||
.mem_start = static_cast<uint64_t>(m_lfb_bar->paddr()),
|
||||
.mem_size = static_cast<uint32_t>(m_lfb_bar->size()),
|
||||
};
|
||||
|
||||
const auto ready_to_use_flags = BGA_ENABLE_LFB_ENABLE | BGA_ENABLE_ENABLE;
|
||||
if ((read_reg(BGA_REG_ENABLE) & ready_to_use_flags) == ready_to_use_flags)
|
||||
{
|
||||
m_var_info = {
|
||||
.xres = read_reg(BGA_REG_XRES),
|
||||
.yres = read_reg(BGA_REG_YRES),
|
||||
.xres_virt = read_reg(BGA_REG_XRES_VIRT),
|
||||
.yres_virt = read_reg(BGA_REG_XRES_VIRT),
|
||||
.xoff = read_reg(BGA_REG_XOFF),
|
||||
.yoff = read_reg(BGA_REG_YOFF),
|
||||
.bpp = read_reg(BGA_REG_BPP),
|
||||
};
|
||||
|
||||
m_fix_info.pitch = m_var_info.xres_virt * m_var_info.bpp / 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
const uint32_t xres = boot_framebuffer ? boot_framebuffer->width() : 1280;
|
||||
const uint32_t yres = boot_framebuffer ? boot_framebuffer->height() : 800;
|
||||
const uint32_t bpp = boot_framebuffer ? boot_framebuffer->bpp() : 32;
|
||||
|
||||
TRY(set_fb_var_info({
|
||||
.xres = xres,
|
||||
.yres = yres,
|
||||
.xres_virt = xres,
|
||||
.yres_virt = yres * 2,
|
||||
.xoff = 0,
|
||||
.yoff = 0,
|
||||
.bpp = bpp,
|
||||
}));
|
||||
}
|
||||
|
||||
if (boot_framebuffer)
|
||||
{
|
||||
// FIXME: check that this is actually the boot framebuffer
|
||||
TRY(boot_framebuffer->set_bga_controller(this));
|
||||
}
|
||||
else
|
||||
{
|
||||
auto framebuffer_device = TRY(FramebufferDevice::create(this));
|
||||
auto fb_terminal_driver = TRY(FramebufferTerminalDriver::create(framebuffer_device));
|
||||
|
||||
// FIXME: query vtty instead of checking the current tty
|
||||
if (auto tty = TTY::current(); tty && tty->is_vtty())
|
||||
TRY(static_cast<VirtualTTY*>(tty.ptr())->set_terminal_driver(fb_terminal_driver));
|
||||
else
|
||||
TRY(VirtualTTY::create(fb_terminal_driver));
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
BAN::ErrorOr<void> BGAController::set_fb_var_info(const fb_var_info& var_info)
|
||||
{
|
||||
const auto validate_u16 = [](auto value) -> BAN::ErrorOr<void> {
|
||||
if (value > BAN::numeric_limits<uint16_t>::max())
|
||||
return BAN::Error::from_errno(EINVAL);
|
||||
return {};
|
||||
};
|
||||
TRY(validate_u16(var_info.xres));
|
||||
TRY(validate_u16(var_info.xres));
|
||||
TRY(validate_u16(var_info.xres_virt));
|
||||
TRY(validate_u16(var_info.yres_virt));
|
||||
TRY(validate_u16(var_info.xoff));
|
||||
TRY(validate_u16(var_info.yoff));
|
||||
TRY(validate_u16(var_info.bpp));
|
||||
|
||||
if (var_info.xres + var_info.xoff > var_info.xres_virt)
|
||||
return BAN::Error::from_errno(EINVAL);
|
||||
if (var_info.yres + var_info.yoff > var_info.yres_virt)
|
||||
return BAN::Error::from_errno(EINVAL);
|
||||
if (static_cast<uint64_t>(var_info.xres_virt) * var_info.yres_virt * var_info.bpp / 8 > m_lfb_bar->size())
|
||||
return BAN::Error::from_errno(EINVAL);
|
||||
|
||||
SpinLockGuard _(m_lock);
|
||||
|
||||
const bool needs_reconf =
|
||||
(m_var_info.xres != var_info.xres) ||
|
||||
(m_var_info.yres != var_info.yres) ||
|
||||
(m_var_info.xres_virt != var_info.xres_virt) ||
|
||||
(m_var_info.yres_virt != var_info.yres_virt) ||
|
||||
(m_var_info.bpp != var_info.bpp);
|
||||
|
||||
if (!needs_reconf)
|
||||
{
|
||||
write_reg(BGA_REG_XOFF, var_info.xoff);
|
||||
write_reg(BGA_REG_YOFF, var_info.yoff);
|
||||
m_var_info.xoff = var_info.xoff;
|
||||
m_var_info.yoff = var_info.yoff;
|
||||
return {};
|
||||
}
|
||||
|
||||
const auto old_enable = read_reg(BGA_REG_ENABLE);
|
||||
write_reg(BGA_REG_ENABLE, 0);
|
||||
|
||||
write_reg(BGA_REG_BPP, var_info.bpp);
|
||||
write_reg(BGA_REG_XRES, var_info.xres);
|
||||
write_reg(BGA_REG_YRES, var_info.yres);
|
||||
write_reg(BGA_REG_XRES_VIRT, var_info.xres_virt);
|
||||
write_reg(BGA_REG_YRES_VIRT, var_info.yres_virt);
|
||||
|
||||
const bool valid_config =
|
||||
read_reg(BGA_REG_BPP) == var_info.bpp &&
|
||||
read_reg(BGA_REG_XRES) == var_info.xres &&
|
||||
read_reg(BGA_REG_YRES) == var_info.yres &&
|
||||
read_reg(BGA_REG_XRES_VIRT) == var_info.xres_virt;
|
||||
|
||||
if (!valid_config)
|
||||
{
|
||||
write_reg(BGA_REG_BPP, m_var_info.bpp);
|
||||
write_reg(BGA_REG_XRES, m_var_info.xres);
|
||||
write_reg(BGA_REG_YRES, m_var_info.yres);
|
||||
write_reg(BGA_REG_XRES_VIRT, m_var_info.xres_virt);
|
||||
write_reg(BGA_REG_YRES_VIRT, m_var_info.yres_virt);
|
||||
|
||||
write_reg(BGA_REG_ENABLE, BGA_ENABLE_NOCLEARMEM | old_enable);
|
||||
|
||||
return BAN::Error::from_errno(EINVAL);
|
||||
}
|
||||
|
||||
write_reg(BGA_REG_ENABLE, BGA_ENABLE_LFB_ENABLE | BGA_ENABLE_ENABLE);
|
||||
|
||||
// NOTE: At least qemu only sets virtual yres on enable and it will be
|
||||
// maximum that fits within vram. Our initial bounds check should
|
||||
// make sure this always succeeds
|
||||
ASSERT(read_reg(BGA_REG_YRES_VIRT) >= var_info.yres_virt);
|
||||
|
||||
write_reg(BGA_REG_XOFF, var_info.xoff);
|
||||
write_reg(BGA_REG_YOFF, var_info.yoff);
|
||||
|
||||
m_var_info = var_info;
|
||||
m_fix_info.pitch = m_var_info.xres_virt * m_var_info.bpp / 8;
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
void BGAController::write_reg(uint16_t reg, uint16_t value)
|
||||
{
|
||||
SpinLockGuard _(m_lock);
|
||||
IO::outw(BGA_IO_PORT_INDEX, reg);
|
||||
IO::outw(BGA_IO_PORT_DATA, value);
|
||||
}
|
||||
|
||||
uint16_t BGAController::read_reg(uint16_t reg)
|
||||
{
|
||||
SpinLockGuard _(m_lock);
|
||||
IO::outw(BGA_IO_PORT_INDEX, reg);
|
||||
return IO::inw(BGA_IO_PORT_DATA);
|
||||
}
|
||||
|
||||
fb_fix_info BGAController::get_fb_fix_info() const
|
||||
{
|
||||
SpinLockGuard _(m_lock);
|
||||
return m_fix_info;
|
||||
}
|
||||
|
||||
fb_var_info BGAController::get_fb_var_info() const
|
||||
{
|
||||
SpinLockGuard _(m_lock);
|
||||
return m_var_info;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -307,8 +307,7 @@ namespace Kernel
|
||||
BAN::ErrorOr<void> KeyboardDevice::initialize_tty_thread()
|
||||
{
|
||||
auto* thread = TRY(Thread::create_kernel(tty_keyboard_thread, nullptr));
|
||||
ASSERT(thread);
|
||||
TRY(Processor::scheduler().add_thread(thread));
|
||||
Processor::scheduler().add_thread(thread);
|
||||
return {};
|
||||
}
|
||||
|
||||
|
||||
@@ -319,11 +319,18 @@ namespace Kernel::Input
|
||||
if (crs_obj == nullptr)
|
||||
return PS2ResourceSetting {};
|
||||
|
||||
const auto crs = TRY(ACPI::AML::evaluate_node(crs_path, crs_obj->node));
|
||||
if (crs.type != ACPI::AML::Node::Type::Buffer)
|
||||
{
|
||||
dwarnln("PS/2 _CRS is not a buffer, but {}", crs);
|
||||
return BAN::Error::from_errno(EINVAL);
|
||||
}
|
||||
|
||||
PS2ResourceSetting result;
|
||||
result.type = type;
|
||||
|
||||
BAN::Optional<ACPI::ResourceData> data;
|
||||
ACPI::ResourceParser parser({ crs_obj->node.as.str_buf->bytes, static_cast<size_t>(crs_obj->node.as.str_buf->size) });
|
||||
ACPI::ResourceParser parser({ crs.as.str_buf->bytes, static_cast<size_t>(crs.as.str_buf->size) });
|
||||
while ((data = parser.get_next()).has_value())
|
||||
{
|
||||
switch (data->type)
|
||||
@@ -551,7 +558,7 @@ namespace Kernel::Input
|
||||
static_cast<PS2DeviceInitInfo*>(info)->controller->device_initialize_task(info);
|
||||
}, &info
|
||||
));
|
||||
TRY(Processor::scheduler().add_thread(init_thread));
|
||||
Processor::scheduler().add_thread(init_thread);
|
||||
|
||||
while (!info.thread_started)
|
||||
Processor::pause();
|
||||
|
||||
@@ -87,6 +87,9 @@ namespace Kernel
|
||||
return BAN::Error::from_errno(ENOENT);
|
||||
}
|
||||
|
||||
if (size == 0)
|
||||
return BAN::Error::from_errno(EINVAL);
|
||||
|
||||
const auto& process = Process::current();
|
||||
const uid_t uid = process.credentials().euid();
|
||||
const gid_t gid = process.credentials().egid();
|
||||
|
||||
@@ -95,11 +95,8 @@ namespace Kernel
|
||||
auto* thread = TRY(Thread::create_kernel([](void* e1000_ptr) {
|
||||
static_cast<E1000*>(e1000_ptr)->receive_thread();
|
||||
}, this));
|
||||
if (auto ret = Processor::scheduler().add_thread(thread); ret.is_error())
|
||||
{
|
||||
delete thread;
|
||||
return ret.release_error();
|
||||
}
|
||||
|
||||
Processor::scheduler().add_thread(thread);
|
||||
m_thread_is_dead = false;
|
||||
|
||||
return {};
|
||||
|
||||
@@ -25,11 +25,8 @@ namespace Kernel
|
||||
auto* thread = TRY(Thread::create_kernel([](void* loopback_ptr) {
|
||||
static_cast<LoopbackInterface*>(loopback_ptr)->receive_thread();
|
||||
}, loopback_ptr));
|
||||
if (auto ret = Processor::scheduler().add_thread(thread); ret.is_error())
|
||||
{
|
||||
delete thread;
|
||||
return ret.release_error();
|
||||
}
|
||||
|
||||
Processor::scheduler().add_thread(thread);
|
||||
loopback->m_thread_is_dead = false;
|
||||
|
||||
loopback->set_ipv4_address({ 127, 0, 0, 1 });
|
||||
|
||||
@@ -75,11 +75,8 @@ namespace Kernel
|
||||
auto* thread = TRY(Thread::create_kernel([](void* rtl8169_ptr) {
|
||||
static_cast<RTL8169*>(rtl8169_ptr)->receive_thread();
|
||||
}, this));
|
||||
if (auto ret = Processor::scheduler().add_thread(thread); ret.is_error())
|
||||
{
|
||||
delete thread;
|
||||
return ret.release_error();
|
||||
}
|
||||
|
||||
Processor::scheduler().add_thread(thread);
|
||||
m_rx_thread_is_dead = false;
|
||||
|
||||
return {};
|
||||
|
||||
@@ -45,7 +45,7 @@ namespace Kernel
|
||||
reinterpret_cast<TCPSocket*>(socket_ptr)->process_task();
|
||||
}, socket.ptr()
|
||||
));
|
||||
TRY(Processor::scheduler().add_thread(socket->m_thread));
|
||||
Processor::scheduler().add_thread(socket->m_thread);
|
||||
// hack to keep socket alive until its process starts
|
||||
socket->ref();
|
||||
return socket;
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace Kernel
|
||||
|
||||
static BAN::ErrorOr<BAN::StringView> validate_sockaddr_un(const sockaddr* address, socklen_t address_len)
|
||||
{
|
||||
if (address_len < static_cast<socklen_t>(sizeof(sa_family_t)))
|
||||
if (address_len <= static_cast<socklen_t>(sizeof(sa_family_t)))
|
||||
return BAN::Error::from_errno(EINVAL);
|
||||
if (address_len > static_cast<socklen_t>(sizeof(sockaddr_un)))
|
||||
address_len = sizeof(sockaddr_un);
|
||||
@@ -30,13 +30,12 @@ namespace Kernel
|
||||
if (sockaddr_un.sun_family != AF_UNIX)
|
||||
return BAN::Error::from_errno(EINVAL);
|
||||
|
||||
size_t length = 0;
|
||||
while (length < sizeof(sockaddr_un::sun_path) && sockaddr_un.sun_path[length])
|
||||
length++;
|
||||
if (length >= sizeof(sockaddr_un::sun_path))
|
||||
return BAN::Error::from_errno(ENAMETOOLONG);
|
||||
|
||||
return BAN::StringView { sockaddr_un.sun_path, length };
|
||||
auto sun_path = BAN::StringView { sockaddr_un.sun_path, address_len - sizeof(sa_family_t) };
|
||||
if (const auto null_idx = sun_path.find('\0'); null_idx.has_value())
|
||||
sun_path = sun_path.substring(0, null_idx.value());
|
||||
if (sun_path.empty())
|
||||
return BAN::Error::from_errno(EINVAL);
|
||||
return sun_path;
|
||||
}
|
||||
|
||||
BAN::ErrorOr<BAN::RefPtr<UnixDomainSocket>> UnixDomainSocket::create(Socket::Type socket_type, const Socket::Info& info)
|
||||
@@ -264,14 +263,15 @@ namespace Kernel
|
||||
BAN::ErrorOr<void> UnixDomainSocket::bind_impl(const sockaddr* address, socklen_t address_len)
|
||||
{
|
||||
const auto sun_path = TRY(validate_sockaddr_un(address, address_len));
|
||||
if (sun_path.empty())
|
||||
return BAN::Error::from_errno(EINVAL);
|
||||
|
||||
BAN::String sun_path_nul;
|
||||
TRY(sun_path_nul.append(sun_path));
|
||||
|
||||
// FIXME: This feels sketchy
|
||||
auto parent_file = sun_path.front() == '/'
|
||||
? TRY(Process::current().root_file().clone())
|
||||
: TRY(Process::current().working_directory().clone());
|
||||
if (auto ret = Process::current().create_file(AT_FDCWD, sun_path.data(), 0755 | Inode::Mode::IFSOCK); ret.is_error())
|
||||
if (auto ret = Process::current().create_file(AT_FDCWD, sun_path_nul.data(), 0755 | Inode::Mode::IFSOCK); ret.is_error())
|
||||
{
|
||||
if (ret.error().get_error_code() == EEXIST)
|
||||
return BAN::Error::from_errno(EADDRINUSE);
|
||||
|
||||
+19
-5
@@ -3,6 +3,7 @@
|
||||
#include <kernel/ACPI/ACPI.h>
|
||||
#include <kernel/APIC.h>
|
||||
#include <kernel/Audio/Controller.h>
|
||||
#include <kernel/Graphics/BGA.h>
|
||||
#include <kernel/IDT.h>
|
||||
#include <kernel/IO.h>
|
||||
#include <kernel/Memory/PageTable.h>
|
||||
@@ -258,6 +259,13 @@ namespace Kernel::PCI
|
||||
for_each_device(
|
||||
[&](PCI::Device& pci_device)
|
||||
{
|
||||
if (pci_device.vendor_id() == 0x1234 && pci_device.device_id() == 0x1111)
|
||||
{
|
||||
if (auto ret = BGAController::create(pci_device); ret.is_error())
|
||||
dprintln("BGA: {}", ret.error());
|
||||
return;
|
||||
}
|
||||
|
||||
switch (pci_device.class_code())
|
||||
{
|
||||
case 0x01:
|
||||
@@ -912,10 +920,10 @@ namespace Kernel::PCI
|
||||
}
|
||||
|
||||
// disable io/mem space while reading bar
|
||||
uint16_t command = device.read_word(PCI_REG_COMMAND);
|
||||
const uint16_t command = device.read_word(PCI_REG_COMMAND);
|
||||
device.write_word(PCI_REG_COMMAND, command & ~(PCI_CMD_IO_SPACE | PCI_CMD_MEM_SPACE));
|
||||
|
||||
uint8_t offset = 0x10 + bar_num * 4;
|
||||
const uint8_t offset = 0x10 + bar_num * 4;
|
||||
|
||||
uint64_t addr = device.read_dword(offset);
|
||||
|
||||
@@ -924,6 +932,13 @@ namespace Kernel::PCI
|
||||
size = ~size + 1;
|
||||
device.write_dword(offset, addr);
|
||||
|
||||
if (size == 0)
|
||||
{
|
||||
device.write_word(PCI_REG_COMMAND, command);
|
||||
dwarnln("BAR{} has size 0", bar_num);
|
||||
return BAN::Error::from_errno(EINVAL);
|
||||
}
|
||||
|
||||
// determine bar type
|
||||
BarType type = BarType::INVALID;
|
||||
if (addr & 1)
|
||||
@@ -956,8 +971,7 @@ namespace Kernel::PCI
|
||||
TRY(region->initialize());
|
||||
|
||||
// restore old command register and enable correct IO/MEM space
|
||||
command |= (type == BarType::IO) ? PCI_CMD_IO_SPACE : PCI_CMD_MEM_SPACE;
|
||||
device.write_word(PCI_REG_COMMAND, command);
|
||||
device.write_word(PCI_REG_COMMAND, command | ((type == BarType::IO) ? PCI_CMD_IO_SPACE : PCI_CMD_MEM_SPACE));
|
||||
|
||||
#if DEBUG_PCI
|
||||
dprintln("created BAR region for PCI {2H}:{2H}.{2H}",
|
||||
@@ -997,7 +1011,7 @@ namespace Kernel::PCI
|
||||
if (m_type == BarType::IO)
|
||||
return {};
|
||||
|
||||
size_t needed_pages = BAN::Math::div_round_up<size_t>(m_size, PAGE_SIZE);
|
||||
const size_t needed_pages = BAN::Math::div_round_up<size_t>(m_size, PAGE_SIZE);
|
||||
m_vaddr = PageTable::kernel().reserve_free_contiguous_pages(needed_pages, KERNEL_OFFSET);
|
||||
if (m_vaddr == 0)
|
||||
return BAN::Error::from_errno(ENOMEM);
|
||||
|
||||
+96
-111
@@ -237,9 +237,8 @@ namespace Kernel
|
||||
#endif
|
||||
}
|
||||
|
||||
// NOTE: make sure the last two `MUST`s don't fail
|
||||
// NOTE: make sure the last `MUST` doesn't fail
|
||||
TRY(process->m_threads.reserve(1));
|
||||
TRY(Processor::scheduler().bind_thread_to_processor(thread, Processor::current_id()));
|
||||
|
||||
{
|
||||
SpinLockGuard _(s_process_lock);
|
||||
@@ -247,7 +246,7 @@ namespace Kernel
|
||||
}
|
||||
|
||||
MUST(process->m_threads.push_back(thread));
|
||||
MUST(Processor::scheduler().add_thread(thread));
|
||||
Processor::scheduler().add_thread(thread);
|
||||
|
||||
process_deleter.disable();
|
||||
thread_deleter.disable();
|
||||
@@ -877,9 +876,8 @@ namespace Kernel
|
||||
Thread* thread = TRY(Thread::current().clone(forked, sp, ip));
|
||||
BAN::ScopeGuard thread_deleter([thread] { delete thread; });
|
||||
|
||||
// NOTE: make sure the last two `MUST`s don't fail
|
||||
// NOTE: make sure the last `MUST` doesn't fail
|
||||
TRY(forked->m_threads.reserve(1));
|
||||
TRY(Processor::scheduler().bind_thread_to_processor(thread, Processor::current_id()));
|
||||
|
||||
{
|
||||
SpinLockGuard _(s_process_lock);
|
||||
@@ -905,7 +903,7 @@ namespace Kernel
|
||||
ASSERT(this == &Process::current());
|
||||
|
||||
MUST(forked->m_threads.push_back(thread));
|
||||
MUST(Processor::scheduler().add_thread(thread));
|
||||
Processor::scheduler().add_thread(thread);
|
||||
|
||||
process_deleter.disable();
|
||||
thread_deleter.disable();
|
||||
@@ -1072,14 +1070,6 @@ namespace Kernel
|
||||
#endif
|
||||
}
|
||||
|
||||
// NOTE: bind new thread to this processor so it wont be rescheduled before end of this function
|
||||
// and so that adding the thread to the scheduler cannot fail
|
||||
if (auto ret = Scheduler::bind_thread_to_processor(new_thread, Processor::current_id()); ret.is_error())
|
||||
{
|
||||
Processor::set_interrupt_state(InterruptState::Enabled);
|
||||
delete new_thread;
|
||||
return ret.release_error();
|
||||
}
|
||||
|
||||
RWLockWRGuard wr_guard(m_memory_region_lock);
|
||||
|
||||
@@ -1103,7 +1093,9 @@ namespace Kernel
|
||||
m_threads.front()->m_process = nullptr;
|
||||
m_threads.front()->give_keep_alive_page_table(BAN::move(m_page_table));
|
||||
|
||||
MUST(Processor::scheduler().add_thread(new_thread));
|
||||
// NOTE: bind new thread to this processor so it wont be rescheduled before end of this function
|
||||
Scheduler::bind_thread_to_processor(new_thread, Processor::current_id());
|
||||
Processor::scheduler().add_thread(new_thread);
|
||||
m_threads.front() = new_thread;
|
||||
|
||||
for (size_t i = 0; i < sizeof(m_signal_handlers) / sizeof(*m_signal_handlers); i++)
|
||||
@@ -1270,18 +1262,12 @@ namespace Kernel
|
||||
return BAN::Error::from_errno(EINVAL);
|
||||
}
|
||||
|
||||
MemoryRegion* value_region = nullptr;
|
||||
MemoryRegion* ovalue_region = nullptr;
|
||||
BAN::ScopeGuard _([&] {
|
||||
if (value_region)
|
||||
value_region->unpin();
|
||||
if (ovalue_region)
|
||||
ovalue_region->unpin();
|
||||
});
|
||||
BAN::Vector<MemoryRegion*> regions;
|
||||
BAN::ScopeGuard _([&] { for (auto* region : regions) region->unpin(); });
|
||||
|
||||
value_region = TRY(validate_and_pin_pointer_access(value, sizeof(itimerval), false));
|
||||
TRY(validate_and_pin_pointer_access(value, sizeof(itimerval), false, regions));
|
||||
if (ovalue != nullptr)
|
||||
ovalue_region = TRY(validate_and_pin_pointer_access(ovalue, sizeof(itimerval), true));
|
||||
TRY(validate_and_pin_pointer_access(ovalue, sizeof(itimerval), true, regions));
|
||||
|
||||
{
|
||||
SpinLockGuard _(s_process_lock);
|
||||
@@ -1475,8 +1461,10 @@ namespace Kernel
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto* buffer_region = TRY(validate_and_pin_pointer_access(buffer, count, true));
|
||||
BAN::ScopeGuard _([buffer_region] { buffer_region->unpin(); });
|
||||
BAN::Vector<MemoryRegion*> regions;
|
||||
BAN::ScopeGuard _([&] { for (auto* region : regions) region->unpin(); });
|
||||
TRY(validate_and_pin_pointer_access(buffer, count, true, regions));
|
||||
|
||||
return TRY(m_open_file_descriptors.read(fd, BAN::ByteSpan(static_cast<uint8_t*>(buffer), count)));
|
||||
}
|
||||
|
||||
@@ -1488,8 +1476,10 @@ namespace Kernel
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto* buffer_region = TRY(validate_and_pin_pointer_access(buffer, count, false));
|
||||
BAN::ScopeGuard _([buffer_region] { buffer_region->unpin(); });
|
||||
BAN::Vector<MemoryRegion*> regions;
|
||||
BAN::ScopeGuard _([&] { for (auto* region : regions) region->unpin(); });
|
||||
TRY(validate_and_pin_pointer_access(buffer, count, false, regions));
|
||||
|
||||
return TRY(m_open_file_descriptors.write(fd, BAN::ConstByteSpan(static_cast<const uint8_t*>(buffer), count)));
|
||||
}
|
||||
|
||||
@@ -1679,8 +1669,9 @@ namespace Kernel
|
||||
{
|
||||
auto inode = TRY(m_open_file_descriptors.inode_of(fd));
|
||||
|
||||
auto* buffer_region = TRY(validate_and_pin_pointer_access(buffer, count, true));
|
||||
BAN::ScopeGuard _([buffer_region] { buffer_region->unpin(); });
|
||||
BAN::Vector<MemoryRegion*> regions;
|
||||
BAN::ScopeGuard _([&] { for (auto* region : regions) region->unpin(); });
|
||||
TRY(validate_and_pin_pointer_access(buffer, count, true, regions));
|
||||
|
||||
return TRY(inode->read(offset, { reinterpret_cast<uint8_t*>(buffer), count }));
|
||||
}
|
||||
@@ -1689,8 +1680,9 @@ namespace Kernel
|
||||
{
|
||||
auto inode = TRY(m_open_file_descriptors.inode_of(fd));
|
||||
|
||||
auto* buffer_region = TRY(validate_and_pin_pointer_access(buffer, count, false));
|
||||
BAN::ScopeGuard _([buffer_region] { buffer_region->unpin(); });
|
||||
BAN::Vector<MemoryRegion*> regions;
|
||||
BAN::ScopeGuard _([&] { for (auto* region : regions) region->unpin(); });
|
||||
TRY(validate_and_pin_pointer_access(buffer, count, false, regions));
|
||||
|
||||
return TRY(inode->write(offset, { reinterpret_cast<const uint8_t*>(buffer), count })); }
|
||||
|
||||
@@ -1710,11 +1702,8 @@ namespace Kernel
|
||||
{
|
||||
LockGuard _(m_process_lock);
|
||||
if (!m_credentials.is_superuser() && inode->uid() != m_credentials.euid())
|
||||
{
|
||||
dwarnln("cannot chmod uid {} vs {}", inode->uid(), m_credentials.euid());
|
||||
return BAN::Error::from_errno(EPERM);
|
||||
}
|
||||
}
|
||||
|
||||
TRY(inode->chmod(mode & ~S_IFMASK));
|
||||
|
||||
@@ -1885,8 +1874,9 @@ namespace Kernel
|
||||
if (!inode->mode().ifsock())
|
||||
return BAN::Error::from_errno(ENOTSOCK);
|
||||
|
||||
auto* buffer = TRY(validate_and_pin_pointer_access(user_option_value, option_len, true));
|
||||
BAN::ScopeGuard _([buffer] { buffer->unpin(); });
|
||||
BAN::Vector<MemoryRegion*> regions;
|
||||
BAN::ScopeGuard _([&] { for (auto* region : regions) region->unpin(); });
|
||||
TRY(validate_and_pin_pointer_access(user_option_value, option_len, true, regions));
|
||||
|
||||
TRY(inode->getsockopt(level, option_name, user_option_value, &option_len));
|
||||
TRY(write_to_user(user_option_len, &option_len, sizeof(socklen_t)));
|
||||
@@ -1903,8 +1893,9 @@ namespace Kernel
|
||||
if (!inode->mode().ifsock())
|
||||
return BAN::Error::from_errno(ENOTSOCK);
|
||||
|
||||
auto* buffer = TRY(validate_and_pin_pointer_access(user_option_value, option_len, false));
|
||||
BAN::ScopeGuard _([buffer] { buffer->unpin(); });
|
||||
BAN::Vector<MemoryRegion*> regions;
|
||||
BAN::ScopeGuard _([&] { for (auto* region : regions) region->unpin(); });
|
||||
TRY(validate_and_pin_pointer_access(user_option_value, option_len, false, regions));
|
||||
|
||||
TRY(inode->setsockopt(level, option_name, user_option_value, option_len));
|
||||
|
||||
@@ -1918,20 +1909,13 @@ namespace Kernel
|
||||
if (flags & ~(SOCK_NONBLOCK | SOCK_CLOEXEC))
|
||||
return BAN::Error::from_errno(EINVAL);
|
||||
|
||||
MemoryRegion* address_region1 = nullptr;
|
||||
MemoryRegion* address_region2 = nullptr;
|
||||
|
||||
BAN::ScopeGuard _([&] {
|
||||
if (address_region1)
|
||||
address_region1->unpin();
|
||||
if (address_region2)
|
||||
address_region2->unpin();
|
||||
});
|
||||
BAN::Vector<MemoryRegion*> regions;
|
||||
BAN::ScopeGuard _([&] { for (auto* region : regions) region->unpin(); });
|
||||
|
||||
if (address_len)
|
||||
{
|
||||
address_region1 = TRY(validate_and_pin_pointer_access(address_len, sizeof(address_len), true));
|
||||
address_region2 = TRY(validate_and_pin_pointer_access(address, *address_len, true));
|
||||
TRY(validate_and_pin_pointer_access(address_len, sizeof(address_len), true, regions));
|
||||
TRY(validate_and_pin_pointer_access(address, *address_len, true, regions));
|
||||
}
|
||||
|
||||
auto inode = TRY(m_open_file_descriptors.inode_of(socket));
|
||||
@@ -1998,23 +1982,17 @@ namespace Kernel
|
||||
TRY(read_from_user(user_message, &message, sizeof(msghdr)));
|
||||
|
||||
BAN::Vector<MemoryRegion*> regions;
|
||||
TRY(regions.reserve(!!message.msg_name + !!message.msg_control + !!message.msg_iov));
|
||||
|
||||
BAN::ScopeGuard _([®ions] {
|
||||
for (auto* region : regions)
|
||||
region->unpin();
|
||||
});
|
||||
BAN::ScopeGuard _([&] { for (auto* region : regions) region->unpin(); });
|
||||
|
||||
if (message.msg_name)
|
||||
TRY(regions.push_back(TRY(validate_and_pin_pointer_access(message.msg_name, message.msg_namelen, true))));
|
||||
TRY(validate_and_pin_pointer_access(message.msg_name, message.msg_namelen, true, regions));
|
||||
if (message.msg_control)
|
||||
TRY(regions.push_back(TRY(validate_and_pin_pointer_access(message.msg_control, message.msg_controllen, true))));
|
||||
TRY(validate_and_pin_pointer_access(message.msg_control, message.msg_controllen, true, regions));
|
||||
if (message.msg_iov)
|
||||
{
|
||||
TRY(regions.push_back(TRY(validate_and_pin_pointer_access(message.msg_iov, message.msg_iovlen * sizeof(iovec), true))));
|
||||
TRY(regions.reserve(regions.size() + message.msg_iovlen));
|
||||
TRY(validate_and_pin_pointer_access(message.msg_iov, message.msg_iovlen * sizeof(iovec), true, regions));
|
||||
for (int i = 0; i < message.msg_iovlen; i++)
|
||||
TRY(regions.push_back(TRY(validate_and_pin_pointer_access(message.msg_iov[i].iov_base, message.msg_iov[i].iov_len, true))));
|
||||
TRY(validate_and_pin_pointer_access(message.msg_iov[i].iov_base, message.msg_iov[i].iov_len, true, regions));
|
||||
}
|
||||
|
||||
const auto ret = TRY(m_open_file_descriptors.recvmsg(socket, message, flags));
|
||||
@@ -2030,23 +2008,18 @@ namespace Kernel
|
||||
TRY(read_from_user(user_message, &message, sizeof(msghdr)));
|
||||
|
||||
BAN::Vector<MemoryRegion*> regions;
|
||||
TRY(regions.reserve(!!message.msg_name + !!message.msg_control + !!message.msg_iov));
|
||||
|
||||
BAN::ScopeGuard _([®ions] {
|
||||
for (auto* region : regions)
|
||||
region->unpin();
|
||||
});
|
||||
BAN::ScopeGuard _([®ions] { for (auto* region : regions) region->unpin(); });
|
||||
|
||||
if (message.msg_name)
|
||||
TRY(regions.push_back(TRY(validate_and_pin_pointer_access(message.msg_name, message.msg_namelen, false))));
|
||||
TRY(validate_and_pin_pointer_access(message.msg_name, message.msg_namelen, false, regions));
|
||||
if (message.msg_control)
|
||||
TRY(regions.push_back(TRY(validate_and_pin_pointer_access(message.msg_control, message.msg_controllen, false))));
|
||||
TRY(validate_and_pin_pointer_access(message.msg_control, message.msg_controllen, false, regions));
|
||||
if (message.msg_iov)
|
||||
{
|
||||
TRY(regions.push_back(TRY(validate_and_pin_pointer_access(message.msg_iov, message.msg_iovlen * sizeof(iovec), false))));
|
||||
TRY(validate_and_pin_pointer_access(message.msg_iov, message.msg_iovlen * sizeof(iovec), false, regions));
|
||||
TRY(regions.reserve(regions.size() + message.msg_iovlen));
|
||||
for (int i = 0; i < message.msg_iovlen; i++)
|
||||
TRY(regions.push_back(TRY(validate_and_pin_pointer_access(message.msg_iov[i].iov_base, message.msg_iov[i].iov_len, false))));
|
||||
TRY(validate_and_pin_pointer_access(message.msg_iov[i].iov_base, message.msg_iov[i].iov_len, false, regions));
|
||||
}
|
||||
|
||||
return TRY(m_open_file_descriptors.sendmsg(socket, message, flags));
|
||||
@@ -2181,8 +2154,9 @@ namespace Kernel
|
||||
|
||||
BAN::ErrorOr<long> Process::sys_ppoll(pollfd* fds, nfds_t nfds, const timespec* user_timeout, const sigset_t* user_sigmask)
|
||||
{
|
||||
auto* fds_region = TRY(validate_and_pin_pointer_access(fds, nfds * sizeof(pollfd), true));
|
||||
BAN::ScopeGuard _([fds_region] { fds_region->unpin(); });
|
||||
BAN::Vector<MemoryRegion*> regions;
|
||||
BAN::ScopeGuard _([&] { for (auto* region : regions) region->unpin(); });
|
||||
TRY(validate_and_pin_pointer_access(fds, nfds * sizeof(pollfd), true, regions));
|
||||
|
||||
const auto old_sigmask = Thread::current().m_signal_block_mask;
|
||||
if (user_sigmask != nullptr)
|
||||
@@ -2364,8 +2338,9 @@ namespace Kernel
|
||||
timeout.tv_nsec;
|
||||
}
|
||||
|
||||
auto* events_region = TRY(validate_and_pin_pointer_access(events, maxevents * sizeof(epoll_event), true));
|
||||
BAN::ScopeGuard _([events_region] { events_region->unpin(); });
|
||||
BAN::Vector<MemoryRegion*> regions;
|
||||
BAN::ScopeGuard _([&] { for (auto* region : regions) region->unpin(); });
|
||||
TRY(validate_and_pin_pointer_access(events, maxevents * sizeof(epoll_event), true, regions));
|
||||
|
||||
const auto old_sigmask = Thread::current().m_signal_block_mask;
|
||||
if (user_sigmask)
|
||||
@@ -2578,8 +2553,10 @@ namespace Kernel
|
||||
if (BAN::Math::will_multiplication_overflow(list_len, sizeof(struct dirent)))
|
||||
return BAN::Error::from_errno(EOVERFLOW);
|
||||
|
||||
auto* list_region = TRY(validate_and_pin_pointer_access(list, list_len * sizeof(struct dirent), true));
|
||||
BAN::ScopeGuard _([list_region] { list_region->unpin(); });
|
||||
BAN::Vector<MemoryRegion*> regions;
|
||||
BAN::ScopeGuard _([&] { for (auto* region : regions) region->unpin(); });
|
||||
TRY(validate_and_pin_pointer_access(list, list_len * sizeof(struct dirent), true, regions));
|
||||
|
||||
return TRY(m_open_file_descriptors.read_dir_entries(fd, list, list_len));
|
||||
}
|
||||
|
||||
@@ -3416,8 +3393,9 @@ namespace Kernel
|
||||
const bool is_private = (op & FUTEX_PRIVATE);
|
||||
op &= ~(FUTEX_PRIVATE | FUTEX_REALTIME);
|
||||
|
||||
auto* buffer_region = TRY(validate_and_pin_pointer_access(addr, sizeof(uint32_t), false));
|
||||
BAN::ScopeGuard pin_guard([buffer_region] { buffer_region->unpin(); });
|
||||
BAN::Vector<MemoryRegion*> regions;
|
||||
BAN::ScopeGuard _0([&] { for (auto* region : regions) region->unpin(); });
|
||||
TRY(validate_and_pin_pointer_access(addr, sizeof(uint32_t), false, regions));
|
||||
|
||||
const paddr_t paddr = m_page_table->physical_address_of(vaddr & PAGE_ADDR_MASK) | (vaddr & ~PAGE_ADDR_MASK);
|
||||
ASSERT(paddr != 0);
|
||||
@@ -3478,7 +3456,7 @@ namespace Kernel
|
||||
}
|
||||
}
|
||||
|
||||
LockGuard _(futex->mutex);
|
||||
LockGuard _1(futex->mutex);
|
||||
|
||||
switch (op)
|
||||
{
|
||||
@@ -3561,8 +3539,9 @@ namespace Kernel
|
||||
if (stack_vaddr % PAGE_SIZE || stack_size % PAGE_SIZE)
|
||||
return BAN::Error::from_errno(EINVAL);
|
||||
|
||||
auto* memory_region = TRY(validate_and_pin_pointer_access(stack_base, stack_size, true));
|
||||
BAN::ScopeGuard _0([memory_region] { if (memory_region) memory_region->unpin(); });
|
||||
BAN::Vector<MemoryRegion*> regions;
|
||||
BAN::ScopeGuard _0([&] { for (auto* region : regions) region->unpin(); });
|
||||
TRY(validate_and_pin_pointer_access(stack_base, stack_size, true, regions));
|
||||
|
||||
const vaddr_t initial_stack_pointer = stack_vaddr + stack_size - sizeof(void*);
|
||||
*reinterpret_cast<void**>(initial_stack_pointer) = arg;
|
||||
@@ -3580,12 +3559,7 @@ namespace Kernel
|
||||
LockGuard _1(m_process_lock);
|
||||
|
||||
TRY(m_threads.push_back(thread));
|
||||
if (auto ret = Processor::scheduler().add_thread(thread); ret.is_error())
|
||||
{
|
||||
m_threads.pop_back();
|
||||
delete thread;
|
||||
return ret.release_error();
|
||||
}
|
||||
Processor::scheduler().add_thread(thread);
|
||||
|
||||
return thread->tid();
|
||||
}
|
||||
@@ -4035,13 +4009,14 @@ namespace Kernel
|
||||
if (BAN::Math::will_multiplication_overflow(count, sizeof(gid_t)))
|
||||
return BAN::Error::from_errno(EOVERFLOW);
|
||||
|
||||
LockGuard _(m_process_lock);
|
||||
LockGuard _0(m_process_lock);
|
||||
|
||||
if (!m_credentials.is_superuser())
|
||||
return BAN::Error::from_errno(EPERM);
|
||||
|
||||
auto* region = TRY(validate_and_pin_pointer_access(groups, count * sizeof(gid_t), false));
|
||||
BAN::ScopeGuard pin_guard([region] { region->unpin(); });
|
||||
BAN::Vector<MemoryRegion*> regions;
|
||||
BAN::ScopeGuard _1([&] { for (auto* region : regions) region->unpin(); });
|
||||
TRY(validate_and_pin_pointer_access(groups, count * sizeof(gid_t), false, regions));
|
||||
|
||||
TRY(m_credentials.set_groups({ groups, count }));
|
||||
|
||||
@@ -4106,26 +4081,23 @@ namespace Kernel
|
||||
return region->allocate_page_containing(address, wants_write);
|
||||
}
|
||||
|
||||
BAN::ErrorOr<MemoryRegion*> Process::validate_and_pin_pointer_access(const void* ptr, size_t size, bool needs_write)
|
||||
BAN::ErrorOr<void> Process::validate_and_pin_pointer_access(const void* ptr, size_t size, bool needs_write, BAN::Vector<MemoryRegion*>& regions)
|
||||
{
|
||||
// TODO: allow pinning multiple regions?
|
||||
|
||||
const vaddr_t user_vaddr = reinterpret_cast<vaddr_t>(ptr);
|
||||
vaddr_t vaddr = reinterpret_cast<vaddr_t>(ptr);
|
||||
|
||||
{
|
||||
RWLockRDGuard _(m_memory_region_lock);
|
||||
|
||||
const size_t first_index = find_mapped_region(user_vaddr);
|
||||
const size_t first_index = find_mapped_region(vaddr);
|
||||
for (size_t i = first_index; i < m_mapped_regions.size(); i++)
|
||||
{
|
||||
auto& region = m_mapped_regions[i];
|
||||
if (user_vaddr >= region->vaddr() + region->size())
|
||||
const auto& region = m_mapped_regions[i];
|
||||
if (vaddr < region->vaddr())
|
||||
break;
|
||||
if (!region->contains_fully(user_vaddr, size))
|
||||
continue;
|
||||
|
||||
const size_t page_count = range_page_count(user_vaddr, size);
|
||||
const vaddr_t page_base = user_vaddr & PAGE_ADDR_MASK;
|
||||
const vaddr_t min_vaddr_end = BAN::Math::min(vaddr + size, region->vaddr() + region->size());
|
||||
const size_t page_count = range_page_count(vaddr, min_vaddr_end - vaddr);
|
||||
const vaddr_t page_base = vaddr & PAGE_ADDR_MASK;
|
||||
for (size_t p = 0; p < page_count; p++)
|
||||
{
|
||||
const auto flags = PageTable::UserSupervisor | (needs_write ? PageTable::ReadWrite : 0) | PageTable::Present;
|
||||
@@ -4133,8 +4105,15 @@ namespace Kernel
|
||||
goto validate_and_pin_pointer_access_with_allocation;
|
||||
}
|
||||
|
||||
TRY(regions.push_back(region.ptr()));
|
||||
region->pin();
|
||||
return region.ptr();
|
||||
|
||||
if (region->contains(vaddr + size - 1))
|
||||
return {};
|
||||
|
||||
const vaddr_t next_vaddr = region->vaddr() + region->size();
|
||||
size -= next_vaddr - vaddr;
|
||||
vaddr = next_vaddr;
|
||||
}
|
||||
|
||||
return BAN::Error::from_errno(EFAULT);
|
||||
@@ -4143,17 +4122,16 @@ namespace Kernel
|
||||
validate_and_pin_pointer_access_with_allocation:
|
||||
RWLockWRGuard _(m_memory_region_lock);
|
||||
|
||||
const size_t first_index = find_mapped_region(user_vaddr);
|
||||
const size_t first_index = find_mapped_region(vaddr);
|
||||
for (size_t i = first_index; i < m_mapped_regions.size(); i++)
|
||||
{
|
||||
auto& region = m_mapped_regions[i];
|
||||
if (user_vaddr >= region->vaddr() + region->size())
|
||||
if (vaddr < region->vaddr())
|
||||
break;
|
||||
if (!region->contains_fully(user_vaddr, size))
|
||||
continue;
|
||||
|
||||
const size_t page_count = range_page_count(user_vaddr, size);
|
||||
const vaddr_t page_base = user_vaddr & PAGE_ADDR_MASK;
|
||||
const vaddr_t min_vaddr_end = BAN::Math::min(vaddr + size, region->vaddr() + region->size());
|
||||
const size_t page_count = range_page_count(vaddr, min_vaddr_end - vaddr);
|
||||
const vaddr_t page_base = vaddr & PAGE_ADDR_MASK;
|
||||
for (size_t p = 0; p < page_count; p++)
|
||||
{
|
||||
const auto flags = PageTable::UserSupervisor | (needs_write ? PageTable::ReadWrite : 0) | PageTable::Present;
|
||||
@@ -4163,8 +4141,15 @@ namespace Kernel
|
||||
return BAN::Error::from_errno(EFAULT);
|
||||
}
|
||||
|
||||
TRY(regions.push_back(region.ptr()));
|
||||
region->pin();
|
||||
return region.ptr();
|
||||
|
||||
if (region->contains(vaddr + size - 1))
|
||||
return {};
|
||||
|
||||
const vaddr_t next_vaddr = region->vaddr() + region->size();
|
||||
size -= next_vaddr - vaddr;
|
||||
vaddr = next_vaddr;
|
||||
}
|
||||
|
||||
return BAN::Error::from_errno(EFAULT);
|
||||
|
||||
+68
-84
@@ -33,9 +33,6 @@ namespace Kernel
|
||||
static SpinLock s_processor_info_time_lock;
|
||||
static BAN::Array<ProcessorInfo, 0xFF> s_processor_infos;
|
||||
|
||||
|
||||
static BAN::Atomic<size_t> s_next_processor_index { 0 };
|
||||
|
||||
BAN::ErrorOr<Scheduler*> Scheduler::create()
|
||||
{
|
||||
auto* scheduler = new Scheduler();
|
||||
@@ -151,7 +148,6 @@ namespace Kernel
|
||||
if (&PageTable::current() != &PageTable::kernel())
|
||||
PageTable::kernel().load();
|
||||
delete m_current->thread;
|
||||
delete m_current;
|
||||
m_thread_count--;
|
||||
break;
|
||||
case Thread::State::Executing:
|
||||
@@ -185,7 +181,6 @@ namespace Kernel
|
||||
if (&PageTable::current() != &PageTable::kernel())
|
||||
PageTable::kernel().load();
|
||||
delete m_current->thread;
|
||||
delete m_current;
|
||||
m_thread_count--;
|
||||
}
|
||||
|
||||
@@ -236,7 +231,7 @@ namespace Kernel
|
||||
|
||||
const uint64_t current_ns = SystemTimer::get().ns_since_boot();
|
||||
while (!m_block_list.empty() && current_ns >= m_block_list.front()->wake_time_ns)
|
||||
unblock_thread(m_block_list.front());
|
||||
unblock_thread(m_block_list.front()->thread);
|
||||
}
|
||||
|
||||
void Scheduler::update_wake_up_deadline()
|
||||
@@ -300,60 +295,6 @@ namespace Kernel
|
||||
update_wake_up_deadline();
|
||||
}
|
||||
|
||||
void Scheduler::unblock_thread(SchedulerThreadNode* node)
|
||||
{
|
||||
auto state = Processor::get_interrupt_state();
|
||||
Processor::set_interrupt_state(InterruptState::Disabled);
|
||||
|
||||
if (node->processor_id == Processor::current_id())
|
||||
{
|
||||
if (!node->blocked)
|
||||
return;
|
||||
ASSERT(node != m_current);
|
||||
Processor::set_disable_smp_messages(true);
|
||||
m_block_list.pop(node);
|
||||
if (auto* blocker = node->blocker.load())
|
||||
blocker->remove_thread_from_block_queue(node);
|
||||
node->blocked = false;
|
||||
m_run_list.push(node);
|
||||
update_most_loaded_node_list(node, &m_run_list);
|
||||
Processor::set_disable_smp_messages(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
Processor::send_smp_message(node->processor_id, {
|
||||
.type = Processor::SMPMessage::Type::UnblockThread,
|
||||
.unblock_thread = node
|
||||
});
|
||||
}
|
||||
|
||||
Processor::set_interrupt_state(state);
|
||||
}
|
||||
|
||||
void Scheduler::add_thread(SchedulerThreadNode* node)
|
||||
{
|
||||
auto state = Processor::get_interrupt_state();
|
||||
Processor::set_interrupt_state(InterruptState::Disabled);
|
||||
|
||||
ASSERT(node->processor_id == Processor::current_id());
|
||||
|
||||
if (!node->blocked)
|
||||
m_run_list.push(node);
|
||||
else
|
||||
{
|
||||
m_block_list.push(node);
|
||||
if (m_block_list.front() == node)
|
||||
update_wake_up_deadline();
|
||||
}
|
||||
|
||||
if (auto* thread = node->thread; thread->is_userspace() && thread->has_process())
|
||||
thread->update_processor_index_address();
|
||||
|
||||
m_thread_count++;
|
||||
|
||||
Processor::set_interrupt_state(state);
|
||||
}
|
||||
|
||||
ProcessorID Scheduler::find_least_loaded_processor() const
|
||||
{
|
||||
ProcessorID least_loaded_id = Processor::current_id();
|
||||
@@ -535,7 +476,7 @@ namespace Kernel
|
||||
thread_info.node->processor_id = least_loaded_id;
|
||||
Processor::send_smp_message(least_loaded_id, {
|
||||
.type = Processor::SMPMessage::Type::NewThread,
|
||||
.new_thread = thread_info.node
|
||||
.new_thread = thread_info.node->thread
|
||||
});
|
||||
|
||||
thread_info = {
|
||||
@@ -563,41 +504,52 @@ namespace Kernel
|
||||
m_last_load_balance_ns += s_load_balance_interval_ns;
|
||||
}
|
||||
|
||||
BAN::ErrorOr<void> Scheduler::bind_thread_to_processor(Thread* thread, ProcessorID processor_id)
|
||||
void Scheduler::bind_thread_to_processor(Thread* thread, ProcessorID processor_id)
|
||||
{
|
||||
ASSERT(thread->m_scheduler_node == nullptr);
|
||||
auto* new_node = new SchedulerThreadNode(thread);
|
||||
if (new_node == nullptr)
|
||||
return BAN::Error::from_errno(ENOMEM);
|
||||
|
||||
ASSERT(processor_id != PROCESSOR_NONE);
|
||||
new_node->processor_id = processor_id;
|
||||
thread->m_scheduler_node = new_node;
|
||||
|
||||
return {};
|
||||
ASSERT(thread->m_scheduler_node.processor_id == PROCESSOR_NONE);
|
||||
thread->m_scheduler_node.processor_id = processor_id;
|
||||
}
|
||||
|
||||
BAN::ErrorOr<void> Scheduler::add_thread(Thread* thread)
|
||||
void Scheduler::add_thread(Thread* thread)
|
||||
{
|
||||
if (thread->m_scheduler_node == nullptr)
|
||||
ASSERT(thread);
|
||||
|
||||
if (thread->m_scheduler_node.processor_id == PROCESSOR_NONE)
|
||||
{
|
||||
static BAN::Atomic<size_t> s_next_processor_index { 0 };
|
||||
const size_t processor_index = s_next_processor_index++ % Processor::count();
|
||||
const auto processor_id = Processor::id_from_index(processor_index);
|
||||
TRY(bind_thread_to_processor(thread, processor_id));
|
||||
bind_thread_to_processor(thread, processor_id);
|
||||
}
|
||||
|
||||
auto* node = thread->m_scheduler_node;
|
||||
if (node->processor_id == Processor::current_id())
|
||||
add_thread(node);
|
||||
if (const auto proc_id = thread->m_scheduler_node.processor_id; proc_id != Processor::current_id())
|
||||
{
|
||||
Processor::send_smp_message(proc_id, {
|
||||
.type = Processor::SMPMessage::Type::NewThread,
|
||||
.new_thread = thread
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const auto state = Processor::get_interrupt_state();
|
||||
Processor::set_interrupt_state(InterruptState::Disabled);
|
||||
|
||||
if (!thread->m_scheduler_node.blocked)
|
||||
m_run_list.push(&thread->m_scheduler_node);
|
||||
else
|
||||
{
|
||||
Processor::send_smp_message(node->processor_id, {
|
||||
.type = Processor::SMPMessage::Type::NewThread,
|
||||
.new_thread = node
|
||||
});
|
||||
m_block_list.push(&thread->m_scheduler_node);
|
||||
if (m_block_list.front() == &thread->m_scheduler_node)
|
||||
update_wake_up_deadline();
|
||||
}
|
||||
|
||||
return {};
|
||||
if (thread->is_userspace() && thread->has_process())
|
||||
thread->update_processor_index_address();
|
||||
|
||||
m_thread_count++;
|
||||
|
||||
Processor::set_interrupt_state(state);
|
||||
}
|
||||
|
||||
void Scheduler::block_current_thread(ThreadBlocker* blocker, uint64_t wake_time_ns, BaseMutex* mutex)
|
||||
@@ -605,7 +557,7 @@ namespace Kernel
|
||||
if (SystemTimer::get().ns_since_boot() >= wake_time_ns)
|
||||
return;
|
||||
|
||||
auto state = Processor::get_interrupt_state();
|
||||
const auto state = Processor::get_interrupt_state();
|
||||
Processor::set_interrupt_state(InterruptState::Disabled);
|
||||
|
||||
ASSERT(m_current->processor_id == Processor::current_id());
|
||||
@@ -639,7 +591,39 @@ namespace Kernel
|
||||
|
||||
void Scheduler::unblock_thread(Thread* thread)
|
||||
{
|
||||
unblock_thread(thread->m_scheduler_node);
|
||||
if (const auto proc_id = thread->m_scheduler_node.processor_id; proc_id != Processor::current_id())
|
||||
{
|
||||
Processor::send_smp_message(proc_id, {
|
||||
.type = Processor::SMPMessage::Type::UnblockThread,
|
||||
.unblock_thread = thread
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const auto state = Processor::get_interrupt_state();
|
||||
Processor::set_interrupt_state(InterruptState::Disabled);
|
||||
|
||||
if (!thread->m_scheduler_node.blocked)
|
||||
{
|
||||
Processor::set_interrupt_state(state);
|
||||
return;
|
||||
}
|
||||
|
||||
ASSERT(&thread->m_scheduler_node != m_current);
|
||||
|
||||
Processor::set_disable_smp_messages(true);
|
||||
|
||||
m_block_list.pop(&thread->m_scheduler_node);
|
||||
if (auto* blocker = thread->m_scheduler_node.blocker.load())
|
||||
blocker->remove_thread_from_block_queue(&thread->m_scheduler_node);
|
||||
thread->m_scheduler_node.blocked = false;
|
||||
|
||||
m_run_list.push(&thread->m_scheduler_node);
|
||||
update_most_loaded_node_list(&thread->m_scheduler_node, &m_run_list);
|
||||
|
||||
Processor::set_disable_smp_messages(false);
|
||||
|
||||
Processor::set_interrupt_state(state);
|
||||
}
|
||||
|
||||
Thread& Scheduler::current_thread()
|
||||
|
||||
@@ -102,10 +102,9 @@ namespace Kernel
|
||||
|
||||
void FramebufferTerminalDriver::show_cursor(bool use_data)
|
||||
{
|
||||
// NOTE: cursor is allowed to be on width as scrolling only
|
||||
// happens after character gets printed to next line
|
||||
if (m_cursor_x == width())
|
||||
if (m_cursor_x == width() || m_cursor_y == height())
|
||||
return;
|
||||
ASSERT(m_cursor_x < width() && m_cursor_y < height());
|
||||
|
||||
if (!use_data)
|
||||
read_cursor();
|
||||
|
||||
@@ -146,7 +146,7 @@ namespace Kernel
|
||||
auto slave = m_slave.lock();
|
||||
if (!slave)
|
||||
return BAN::Error::from_errno(EIO);
|
||||
LockGuard _(slave->m_mutex);
|
||||
LockGuard _(slave->m_input_mutex);
|
||||
for (size_t i = 0; i < buffer.size(); i++)
|
||||
slave->handle_input_byte(buffer[i]);
|
||||
return buffer.size();
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <kernel/FS/DevFS/FileSystem.h>
|
||||
#include <kernel/FS/VirtualFileSystem.h>
|
||||
#include <kernel/Input/InputDevice.h>
|
||||
#include <kernel/Lock/BlockableSpinLock.h>
|
||||
#include <kernel/Lock/LockGuard.h>
|
||||
#include <kernel/Process.h>
|
||||
#include <kernel/Terminal/TTY.h>
|
||||
@@ -81,7 +82,6 @@ namespace Kernel
|
||||
|
||||
BAN::RefPtr<TTY> TTY::current()
|
||||
{
|
||||
ASSERT(s_tty);
|
||||
return s_tty;
|
||||
}
|
||||
|
||||
@@ -220,7 +220,7 @@ namespace Kernel
|
||||
if (ansi_c_str == nullptr)
|
||||
return;
|
||||
|
||||
LockGuard _(m_mutex);
|
||||
LockGuard _(m_input_mutex);
|
||||
while (*ansi_c_str)
|
||||
handle_input_byte(*ansi_c_str++);
|
||||
after_write();
|
||||
@@ -269,7 +269,7 @@ namespace Kernel
|
||||
bool should_flush = false;
|
||||
bool force_echo = false;
|
||||
|
||||
LockGuard _(m_mutex);
|
||||
LockGuard _(m_input_mutex);
|
||||
|
||||
if (!(termios.c_lflag & ICANON))
|
||||
should_flush = true;
|
||||
@@ -377,7 +377,8 @@ namespace Kernel
|
||||
|
||||
const auto termios = get_termios();
|
||||
|
||||
LockGuard _(m_write_lock);
|
||||
SpinLockGuard _(m_write_lock);
|
||||
|
||||
if (termios.c_oflag & OPOST)
|
||||
{
|
||||
if ((termios.c_oflag & ONLCR) && ch == NL)
|
||||
@@ -385,14 +386,16 @@ namespace Kernel
|
||||
if ((termios.c_oflag & OCRNL) && ch == CR)
|
||||
return putchar_impl(NL);
|
||||
}
|
||||
|
||||
return putchar_impl(ch);
|
||||
}
|
||||
|
||||
BAN::ErrorOr<size_t> TTY::read_impl(off_t, BAN::ByteSpan buffer)
|
||||
{
|
||||
LockGuard _(m_mutex);
|
||||
LockGuard _(m_input_mutex);
|
||||
|
||||
while (!m_output.flush)
|
||||
TRY(Thread::current().block_or_eintr_indefinite(m_output.thread_blocker, &m_mutex));
|
||||
TRY(Thread::current().block_or_eintr_indefinite(m_output.thread_blocker, &m_input_mutex));
|
||||
|
||||
if (m_output.buffer->empty())
|
||||
{
|
||||
@@ -424,13 +427,14 @@ namespace Kernel
|
||||
|
||||
BAN::ErrorOr<size_t> TTY::write_impl(off_t, BAN::ConstByteSpan buffer)
|
||||
{
|
||||
LockGuard write_guard(m_write_lock);
|
||||
SpinLockGuard _(m_write_lock);
|
||||
|
||||
while (!can_write())
|
||||
{
|
||||
if (master_has_closed())
|
||||
return BAN::Error::from_errno(EIO);
|
||||
TRY(Thread::current().block_or_eintr_indefinite(m_write_blocker, &m_write_lock));
|
||||
BlockableSpinLock block(m_write_lock);
|
||||
TRY(Thread::current().block_or_eintr_indefinite(m_write_blocker, &block));
|
||||
}
|
||||
|
||||
size_t written = 0;
|
||||
@@ -447,15 +451,12 @@ namespace Kernel
|
||||
|
||||
void TTY::putchar_current(uint8_t ch)
|
||||
{
|
||||
ASSERT(s_tty);
|
||||
auto tty = s_tty;
|
||||
ASSERT(tty);
|
||||
|
||||
while (!s_tty->m_write_lock.try_lock())
|
||||
Processor::pause();
|
||||
|
||||
s_tty->putchar(ch);
|
||||
s_tty->after_write();
|
||||
|
||||
s_tty->m_write_lock.unlock();
|
||||
SpinLockGuard _(tty->m_write_lock);
|
||||
tty->putchar(ch);
|
||||
tty->after_write();
|
||||
}
|
||||
|
||||
bool TTY::is_initialized()
|
||||
|
||||
@@ -50,34 +50,15 @@ namespace Kernel
|
||||
, m_foreground(driver->palette()[15])
|
||||
, m_background(driver->palette()[0])
|
||||
{
|
||||
m_width = m_terminal_driver->width();
|
||||
m_height = m_terminal_driver->height();
|
||||
update_winsize(m_width, m_height);
|
||||
|
||||
m_buffer = new Cell[m_width * m_height];
|
||||
ASSERT(m_buffer);
|
||||
MUST(set_terminal_driver(driver));
|
||||
}
|
||||
|
||||
void VirtualTTY::clear()
|
||||
BAN::ErrorOr<void> VirtualTTY::set_terminal_driver(BAN::RefPtr<TerminalDriver> terminal_driver)
|
||||
{
|
||||
LockGuard _(m_write_lock);
|
||||
for (uint32_t i = 0; i < m_width * m_height; i++)
|
||||
m_buffer[i] = { .foreground = m_foreground, .background = m_background, .codepoint = ' ' };
|
||||
m_terminal_driver->clear(m_background);
|
||||
}
|
||||
const uint32_t new_width = terminal_driver->width();
|
||||
const uint32_t new_height = terminal_driver->height();
|
||||
|
||||
BAN::ErrorOr<void> VirtualTTY::set_font(LibFont::Font&& font)
|
||||
{
|
||||
if (!m_terminal_driver->has_font())
|
||||
return BAN::Error::from_errno(EINVAL);
|
||||
|
||||
{
|
||||
LockGuard _(m_write_lock);
|
||||
|
||||
TRY(m_terminal_driver->set_font(BAN::move(font)));
|
||||
|
||||
uint32_t new_width = m_terminal_driver->width();
|
||||
uint32_t new_height = m_terminal_driver->height();
|
||||
SpinLockGuard _(m_write_lock);
|
||||
|
||||
if (m_width != new_width || m_height != new_height)
|
||||
{
|
||||
@@ -97,19 +78,37 @@ namespace Kernel
|
||||
m_height = new_height;
|
||||
}
|
||||
|
||||
m_terminal_driver = terminal_driver;
|
||||
|
||||
for (uint32_t y = 0; y < m_height; y++)
|
||||
for (uint32_t x = 0; x < m_width; x++)
|
||||
render_from_buffer(x, y);
|
||||
|
||||
update_winsize(new_width, new_height);
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
update_winsize(m_width, m_height);
|
||||
void VirtualTTY::clear()
|
||||
{
|
||||
SpinLockGuard _(m_write_lock);
|
||||
for (uint32_t i = 0; i < m_width * m_height; i++)
|
||||
m_buffer[i] = { .foreground = m_foreground, .background = m_background, .codepoint = ' ' };
|
||||
m_terminal_driver->clear(m_background);
|
||||
}
|
||||
|
||||
BAN::ErrorOr<void> VirtualTTY::set_font(LibFont::Font&& font)
|
||||
{
|
||||
if (!m_terminal_driver->has_font())
|
||||
return BAN::Error::from_errno(EINVAL);
|
||||
TRY(m_terminal_driver->set_font(BAN::move(font)));
|
||||
MUST(set_terminal_driver(m_terminal_driver));
|
||||
return {};
|
||||
}
|
||||
|
||||
void VirtualTTY::reset_ansi()
|
||||
{
|
||||
ASSERT(m_write_lock.is_locked_by_current_thread());
|
||||
ASSERT(m_write_lock.current_processor_has_lock());
|
||||
m_ansi_state = {
|
||||
.nums = { -1, -1, -1, -1, -1 },
|
||||
.index = 0,
|
||||
@@ -120,7 +119,7 @@ namespace Kernel
|
||||
|
||||
void VirtualTTY::handle_ansi_csi_color(uint8_t value)
|
||||
{
|
||||
ASSERT(m_write_lock.is_locked_by_current_thread());
|
||||
ASSERT(m_write_lock.current_processor_has_lock());
|
||||
|
||||
auto& palette = m_terminal_driver->palette();
|
||||
|
||||
@@ -203,7 +202,8 @@ namespace Kernel
|
||||
|
||||
void VirtualTTY::handle_ansi_csi(uint8_t ch)
|
||||
{
|
||||
ASSERT(m_write_lock.is_locked_by_current_thread());
|
||||
ASSERT(m_write_lock.current_processor_has_lock());
|
||||
|
||||
switch (ch)
|
||||
{
|
||||
case '0' ... '9':
|
||||
@@ -427,10 +427,15 @@ namespace Kernel
|
||||
case 'n':
|
||||
if (m_ansi_state.nums[0] == 6)
|
||||
{
|
||||
// NOTE: this is very hacky but should be fine as long
|
||||
// as kernel doesn't use this
|
||||
while (!m_input_mutex.try_lock())
|
||||
Processor::pause();
|
||||
BAN::Formatter::print(
|
||||
[this](char ch) { handle_input_byte(ch); },
|
||||
"\e[{};{}R", m_row + 1, m_column + 1
|
||||
);
|
||||
m_input_mutex.unlock();
|
||||
return reset_ansi();
|
||||
};
|
||||
reset_ansi();
|
||||
@@ -445,7 +450,7 @@ namespace Kernel
|
||||
|
||||
void VirtualTTY::render_from_buffer(uint32_t x, uint32_t y)
|
||||
{
|
||||
ASSERT(m_write_lock.is_locked_by_current_thread());
|
||||
ASSERT(m_write_lock.current_processor_has_lock());
|
||||
ASSERT(x < m_width && y < m_height);
|
||||
const auto& cell = m_buffer[y * m_width + x];
|
||||
m_terminal_driver->putchar_at(cell.codepoint, x, y, cell.foreground, cell.background);
|
||||
@@ -453,7 +458,7 @@ namespace Kernel
|
||||
|
||||
void VirtualTTY::putchar_at(uint32_t codepoint, uint32_t x, uint32_t y)
|
||||
{
|
||||
ASSERT(m_write_lock.is_locked_by_current_thread());
|
||||
ASSERT(m_write_lock.current_processor_has_lock());
|
||||
ASSERT(x < m_width && y < m_height);
|
||||
auto& cell = m_buffer[y * m_width + x];
|
||||
cell.codepoint = codepoint;
|
||||
@@ -464,6 +469,8 @@ namespace Kernel
|
||||
|
||||
void VirtualTTY::scroll_if_needed()
|
||||
{
|
||||
ASSERT(m_write_lock.current_processor_has_lock());
|
||||
|
||||
while (m_row >= m_height)
|
||||
{
|
||||
memmove(m_buffer, m_buffer + m_width, m_width * (m_height - 1) * sizeof(Cell));
|
||||
@@ -487,7 +494,7 @@ namespace Kernel
|
||||
|
||||
void VirtualTTY::putcodepoint(uint32_t codepoint)
|
||||
{
|
||||
ASSERT(m_write_lock.is_locked_by_current_thread());
|
||||
ASSERT(m_write_lock.current_processor_has_lock());
|
||||
|
||||
switch (codepoint)
|
||||
{
|
||||
@@ -533,7 +540,7 @@ namespace Kernel
|
||||
|
||||
bool VirtualTTY::putchar_impl(uint8_t ch)
|
||||
{
|
||||
ASSERT(m_write_lock.is_locked_by_current_thread());
|
||||
ASSERT(m_write_lock.current_processor_has_lock());
|
||||
|
||||
uint32_t codepoint = ch;
|
||||
|
||||
|
||||
@@ -240,6 +240,7 @@ namespace Kernel
|
||||
|
||||
Thread::Thread(pid_t tid, Process* process)
|
||||
: m_tid(tid), m_process(process)
|
||||
, m_scheduler_node(this)
|
||||
{
|
||||
if (!s_default_sse_storage_initialized)
|
||||
initialize_default_sse_storage();
|
||||
|
||||
@@ -37,7 +37,7 @@ namespace Kernel
|
||||
node->block_chain_prev = nullptr;
|
||||
node->block_chain_next = nullptr;
|
||||
|
||||
Processor::scheduler().unblock_thread(node);
|
||||
Processor::scheduler().unblock_thread(node->thread);
|
||||
|
||||
node = next;
|
||||
}
|
||||
|
||||
@@ -134,6 +134,9 @@ namespace Kernel
|
||||
case USB::DeviceBaseClass::DiagnosticDevice:
|
||||
dprintln_if(DEBUG_USB, "Found DiagnosticDevice device");
|
||||
return BAN::Error::from_errno(ENOTSUP);
|
||||
case USB::DeviceBaseClass::WirelessController:
|
||||
dprintln_if(DEBUG_USB, "Found WirelessController device");
|
||||
return BAN::Error::from_errno(ENOTSUP);
|
||||
case USB::DeviceBaseClass::Miscellaneous:
|
||||
dprintln_if(DEBUG_USB, "Found Miscellaneous device");
|
||||
return BAN::Error::from_errno(ENOTSUP);
|
||||
|
||||
@@ -218,7 +218,7 @@ namespace Kernel
|
||||
}
|
||||
|
||||
m_port_updater = TRY(Thread::create_kernel([](void* data) { reinterpret_cast<USBHubDriver*>(data)->port_updater_task(); }, this));
|
||||
TRY(Processor::scheduler().add_thread(m_port_updater));
|
||||
Processor::scheduler().add_thread(m_port_updater);
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
@@ -149,7 +149,7 @@ namespace Kernel
|
||||
continue;
|
||||
|
||||
m_port_updater = TRY(Thread::create_kernel([](void* data) { reinterpret_cast<XHCIController*>(data)->port_updater_task(); }, this));
|
||||
TRY(Processor::scheduler().add_thread(m_port_updater));
|
||||
Processor::scheduler().add_thread(m_port_updater);
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
+49
-20
@@ -68,6 +68,8 @@ static bool should_disable_serial(BAN::StringView full_command_line)
|
||||
extern bool g_disable_debug;
|
||||
static ParsedCommandLine cmdline;
|
||||
|
||||
static bool s_has_early_console { false };
|
||||
|
||||
static void parse_command_line()
|
||||
{
|
||||
auto full_command_line = Kernel::g_boot_info.command_line.sv();
|
||||
@@ -160,7 +162,24 @@ extern "C" void kernel_main(uint32_t boot_magic, uint32_t boot_info)
|
||||
if (auto ret = TerminalDriver::initialize_from_boot_info(); ret.is_error())
|
||||
dprintln("failed to initialize terminal driver: {}", ret.error());
|
||||
else
|
||||
dprintln("terminal driver initialized");
|
||||
{
|
||||
MUST(VirtualTTY::create(g_terminal_driver));
|
||||
dprintln("Virtual TTY initialized");
|
||||
}
|
||||
|
||||
if (Serial::has_devices())
|
||||
{
|
||||
Serial::initialize_devices();
|
||||
dprintln("Serial devices initialized");
|
||||
}
|
||||
|
||||
if (auto ret = DevFileSystem::get().root_inode()->find_inode(cmdline.console); !ret.is_error())
|
||||
{
|
||||
auto console = ret.release_value();
|
||||
ASSERT(console->is_tty());
|
||||
static_cast<Kernel::TTY*>(console.ptr())->set_as_current();
|
||||
s_has_early_console = true;
|
||||
}
|
||||
|
||||
if (!cmdline.disable_smp)
|
||||
InterruptController::get().initialize_multiprocessor();
|
||||
@@ -171,18 +190,6 @@ extern "C" void kernel_main(uint32_t boot_magic, uint32_t boot_info)
|
||||
MUST(SharedMemoryObjectManager::initialize());
|
||||
dprintln("Shared memory object system initialized");
|
||||
|
||||
if (Serial::has_devices())
|
||||
{
|
||||
Serial::initialize_devices();
|
||||
dprintln("Serial devices initialized");
|
||||
}
|
||||
|
||||
if (g_terminal_driver)
|
||||
{
|
||||
auto vtty = MUST(VirtualTTY::create(g_terminal_driver));
|
||||
dprintln("Virtual TTY initialized");
|
||||
}
|
||||
|
||||
Random::initialize();
|
||||
dprintln("RNG initialized");
|
||||
|
||||
@@ -196,7 +203,7 @@ extern "C" void kernel_main(uint32_t boot_magic, uint32_t boot_info)
|
||||
MUST(Processor::scheduler().initialize());
|
||||
|
||||
auto* init_thread = MUST(Thread::create_kernel(init2, nullptr));
|
||||
MUST(Processor::scheduler().add_thread(init_thread));
|
||||
Processor::scheduler().add_thread(init_thread);
|
||||
Processor::yield();
|
||||
|
||||
ASSERT_NOT_REACHED();
|
||||
@@ -213,10 +220,6 @@ static void init2(void*)
|
||||
|
||||
ProcFileSystem::get().post_scheduler_initialize();
|
||||
|
||||
auto console = MUST(DevFileSystem::get().root_inode()->find_inode(cmdline.console));
|
||||
ASSERT(console->is_tty());
|
||||
static_cast<Kernel::TTY*>(console.ptr())->set_as_current();
|
||||
|
||||
// This only initializes PCIManager by enumerating available devices and choosing PCIe/legacy
|
||||
// ACPI might require PCI access during its namespace initialization
|
||||
PCI::PCIManager::initialize();
|
||||
@@ -256,6 +259,32 @@ static void init2(void*)
|
||||
PCI::PCIManager::get().initialize_devices(cmdline.disable_usb);
|
||||
dprintln("PCI devices initialized");
|
||||
|
||||
if (!s_has_early_console)
|
||||
{
|
||||
auto console_or_error = DevFileSystem::get().root_inode()->find_inode(cmdline.console);
|
||||
if (!console_or_error.is_error())
|
||||
{
|
||||
auto console = console_or_error.release_value();
|
||||
ASSERT(console->is_tty());
|
||||
static_cast<TTY*>(console.ptr())->set_as_current();
|
||||
}
|
||||
else
|
||||
{
|
||||
BAN::RefPtr<TTY> tty;
|
||||
DevFileSystem::get().for_each_inode([&](BAN::RefPtr<Inode> inode) -> BAN::Iteration {
|
||||
if (!inode->is_tty())
|
||||
return BAN::Iteration::Continue;
|
||||
tty = static_cast<TTY*>(inode.ptr());
|
||||
return BAN::Iteration::Break;
|
||||
});
|
||||
|
||||
ASSERT(tty);
|
||||
|
||||
dwarnln("Could not find /dev/{}, falling back to /dev/{}", cmdline.console, tty->name());
|
||||
tty->set_as_current();
|
||||
}
|
||||
}
|
||||
|
||||
VirtualFileSystem::initialize(cmdline.root);
|
||||
dprintln("VFS initialized");
|
||||
|
||||
@@ -266,9 +295,9 @@ static void init2(void*)
|
||||
|
||||
Banos::initialize_initial_drivers();
|
||||
|
||||
auto console_path = MUST(BAN::String::formatted("/dev/{}", cmdline.console));
|
||||
auto console_path = MUST(BAN::String::formatted("/dev/{}", TTY::current()->name()));
|
||||
auto console_path_sv = console_path.sv();
|
||||
MUST(Process::create_userspace({ 0, 0, 0, 0 }, "/usr/bin/init"_sv, BAN::Span<BAN::StringView>(&console_path_sv, 1)));
|
||||
MUST(Process::create_userspace({ 0, 0, 0, 0 }, "/usr/bin/init"_sv, { &console_path_sv, 1 }));
|
||||
}
|
||||
|
||||
extern "C" void ap_main()
|
||||
|
||||
Executable
+31
@@ -0,0 +1,31 @@
|
||||
#!/bin/bash ../install.sh
|
||||
|
||||
NAME='AppStream'
|
||||
VERSION='1.1.2'
|
||||
DOWNLOAD_URL="https://www.freedesktop.org/software/appstream/releases/AppStream-$VERSION.tar.xz#46b4257100e25a6468ceed7b3ab82441f47b119da3398d30aea6d7b91174b586"
|
||||
DEPENDENCIES=('glib' 'curl' 'libxml2' 'libfyaml')
|
||||
CONFIGURE_OPTIONS=(
|
||||
'-Dprefix=/usr'
|
||||
'-Dbuildtype=release'
|
||||
'-Dbash-completion=false'
|
||||
'-Dgir=false'
|
||||
'-Dman=false'
|
||||
'-Dstemming=false'
|
||||
'-Dsystemd=false'
|
||||
)
|
||||
|
||||
configure() {
|
||||
meson setup \
|
||||
--reconfigure \
|
||||
--cross-file "$MESON_CROSS_FILE" \
|
||||
"${CONFIGURE_OPTIONS[@]}" \
|
||||
build || exit 1
|
||||
}
|
||||
|
||||
build() {
|
||||
meson compile -C build || exit 1
|
||||
}
|
||||
|
||||
install() {
|
||||
meson install --destdir="$DESTDIR" -C build || exit 1
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
diff -ruN AppStream-1.1.2/data/meson.build AppStream-1.1.2-banan_os/data/meson.build
|
||||
--- AppStream-1.1.2/data/meson.build 2026-01-28 22:15:58.000000000 +0200
|
||||
+++ AppStream-1.1.2-banan_os/data/meson.build 2026-03-25 04:09:17.550968139 +0200
|
||||
@@ -9,8 +9,6 @@
|
||||
|
||||
# Do not rely on an exe wrapper for rel-info, use the system one in that case
|
||||
if meson.is_cross_build()
|
||||
- dependency('appstream', version: '>=' + as_version, native: true,
|
||||
- not_found_message: 'Native appstream required for cross-building')
|
||||
ascli_exe = find_program('appstreamcli', native: true)
|
||||
endif
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
diff -ruN AppStream-1.1.2/src/as-system-info.c AppStream-1.1.2-banan_os/src/as-system-info.c
|
||||
--- AppStream-1.1.2/src/as-system-info.c 2026-01-28 22:15:58.000000000 +0200
|
||||
+++ AppStream-1.1.2-banan_os/src/as-system-info.c 2026-03-25 04:08:32.249321186 +0200
|
||||
@@ -513,7 +513,7 @@
|
||||
return 0;
|
||||
}
|
||||
return hbi.memory_size / MB_IN_BYTES;
|
||||
-#elif defined(__sun)
|
||||
+#elif defined(__sun) || defined(__banan_os__)
|
||||
long physpages = sysconf (_SC_PHYS_PAGES);
|
||||
long pagesize = sysconf (_SC_PAGESIZE);
|
||||
if (physpages > 0 && pagesize > 0)
|
||||
@@ -19,5 +19,6 @@ build() {
|
||||
}
|
||||
|
||||
install() {
|
||||
mkdir -p "$DESTDIR/usr/bin"
|
||||
cp -v bin/gcc/$specseek_arch/specseek_$specseek_arch "$DESTDIR/usr/bin/specseek" || exit 1
|
||||
}
|
||||
|
||||
Executable
+35
@@ -0,0 +1,35 @@
|
||||
#!/bin/bash ../install.sh
|
||||
|
||||
NAME='babl'
|
||||
VERSION='0.1.124'
|
||||
DOWNLOAD_URL="https://download.gimp.org/pub/babl/0.1/babl-$VERSION.tar.xz#1b0d544ab6f409f2b1b5f677226272d1e8c6d373f2f453ee870bfc7e5dd4f1b1"
|
||||
DEPENDENCIES=('lcms2')
|
||||
CONFIGURE_OPTIONS=(
|
||||
'-Dprefix=/usr'
|
||||
'-Dbuildtype=release'
|
||||
'-Dwith-docs=false'
|
||||
'-Denable-gir=false'
|
||||
'-Denable-vapi=false'
|
||||
'-Dgi-docgen=disabled'
|
||||
'-Denable-avx2=false'
|
||||
)
|
||||
|
||||
configure() {
|
||||
meson setup \
|
||||
--reconfigure \
|
||||
--cross-file "$MESON_CROSS_FILE" \
|
||||
"${CONFIGURE_OPTIONS[@]}" \
|
||||
build || exit 1
|
||||
}
|
||||
|
||||
post_configure() {
|
||||
grep -q '<alloca.h>' build/config.h || echo '#include <alloca.h>' >> build/config.h
|
||||
}
|
||||
|
||||
build() {
|
||||
meson compile -C build || exit 1
|
||||
}
|
||||
|
||||
install() {
|
||||
meson install --destdir="$DESTDIR" -C build || exit 1
|
||||
}
|
||||
+2
-2
@@ -16,7 +16,7 @@ CONFIGURE_OPTIONS=(
|
||||
)
|
||||
|
||||
post_install() {
|
||||
if [ ! -L $DESTDIR/usr/bin/sh ]; then
|
||||
ln -s bash $DESTDIR/usr/bin/sh
|
||||
if [ ! -L "$DESTDIR/usr/bin/sh" ]; then
|
||||
ln -sv "bash $DESTDIR/usr/bin/sh"
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -17,9 +17,11 @@ configure() {
|
||||
}
|
||||
|
||||
build() {
|
||||
./b2 --user-config=user-config.jam toolset=gcc target-os=banan_os || exit 1
|
||||
./b2 --user-config=user-config.jam \
|
||||
toolset=gcc target-os=banan_os || exit 1
|
||||
}
|
||||
|
||||
install() {
|
||||
./b2 --user-config=user-config.jam toolset=gcc target-os=banan_os install || exit 1
|
||||
./b2 --user-config=user-config.jam --prefix="$DESTDIR/usr" \
|
||||
toolset=gcc target-os=banan_os install || exit 1
|
||||
}
|
||||
|
||||
@@ -22,7 +22,8 @@ install() {
|
||||
mkdir -p "$DESTDIR/usr/include"
|
||||
cp -v bzlib.h "$DESTDIR/usr/include/" || exit 1
|
||||
|
||||
cat > $DESTDIR/usr/lib/pkgconfig/bzip2.pc << EOF
|
||||
mkdir -p "$DESTDIR/usr/lib/pkgconfig"
|
||||
cat > "$DESTDIR/usr/lib/pkgconfig/bzip2.pc" << EOF
|
||||
prefix=/usr
|
||||
exec_prefix=\${prefix}
|
||||
bindir=\${exec_prefix}/bin
|
||||
|
||||
+1
-1
@@ -11,7 +11,7 @@ configure() {
|
||||
|
||||
build() {
|
||||
if [ ! -f ../doom1.wad ]; then
|
||||
wget https://distro.ibiblio.org/slitaz/sources/packages/d/doom1.wad -O ../doom1.wad || exit 1
|
||||
wget 'https://bananymous.com/files/doom1.wad' -O ../doom1.wad || exit 1
|
||||
fi
|
||||
|
||||
make -C doomgeneric -f Makefile.sdl CC="$CC" SDL_PATH="$BANAN_SYSROOT/usr/bin/" || exit 1
|
||||
|
||||
Executable
+26
@@ -0,0 +1,26 @@
|
||||
#!/bin/bash ../install.sh
|
||||
|
||||
NAME='exiv2'
|
||||
VERSION='0.28.8'
|
||||
DOWNLOAD_URL="https://github.com/Exiv2/exiv2/archive/refs/tags/v$VERSION.tar.gz#ea51b0609f58a9afa063b60daa1539948b62247721e154f4fff0ad3aec9f9756"
|
||||
DEPENDENCIES=('zlib' 'expat')
|
||||
|
||||
configure() {
|
||||
cmake --fresh -B build -S . -G Ninja \
|
||||
--toolchain="$BANAN_TOOLCHAIN_DIR/Toolchain.txt" \
|
||||
-DCMAKE_INSTALL_PREFIX=/usr \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DEXIV2_ENABLE_NLS=OFF \
|
||||
-DEXIV2_ENABLE_BROTLI=OFF \
|
||||
-DEXIV2_ENABLE_INIH=OFF \
|
||||
-DBUILD_WITH_STACK_PROTECTOR=OFF \
|
||||
|| exit 1
|
||||
}
|
||||
|
||||
build() {
|
||||
cmake --build build || exit 1
|
||||
}
|
||||
|
||||
install() {
|
||||
DESTDIR="$DESTDIR" cmake --install build || exit 1
|
||||
}
|
||||
@@ -12,11 +12,13 @@ CONFIGURE_OPTIONS=(
|
||||
"--cxx=$CXX"
|
||||
'--enable-cross-compile'
|
||||
'--enable-shared'
|
||||
'--disable-static'
|
||||
'--disable-doc'
|
||||
'--enable-gpl'
|
||||
'--enable-version3'
|
||||
'--enable-openssl'
|
||||
)
|
||||
|
||||
configure() {
|
||||
./configure "${CONFIGURE_OPTIONS[@]}"
|
||||
./configure "${CONFIGURE_OPTIONS[@]}" || exit 1
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
NAME='fontconfig'
|
||||
VERSION='2.17.1'
|
||||
DOWNLOAD_URL="https://gitlab.freedesktop.org/fontconfig/fontconfig/-/archive/$VERSION/fontconfig-$VERSION.tar.gz#82e73b26adad651b236e5f5d4b3074daf8ff0910188808496326bd3449e5261d"
|
||||
DEPENDENCIES=('harfbuzz' 'freetype' 'expat' 'libiconv' 'dejavu-fonts-ttf')
|
||||
DEPENDENCIES=('freetype' 'expat' 'libiconv' 'dejavu-fonts-ttf')
|
||||
CONFIGURE_OPTIONS=(
|
||||
'-Dprefix=/usr'
|
||||
'-Dbuildtype=release'
|
||||
|
||||
+20
-2
@@ -5,6 +5,24 @@ VERSION='2.14.3'
|
||||
DOWNLOAD_URL="https://download.savannah.gnu.org/releases/freetype/freetype-$VERSION.tar.xz#36bc4f1cc413335368ee656c42afca65c5a3987e8768cc28cf11ba775e785a5f"
|
||||
DEPENDENCIES=('zlib' 'libpng')
|
||||
CONFIGURE_OPTIONS=(
|
||||
'--disable-static'
|
||||
'lt_cv_deplibs_check_method=pass_all'
|
||||
'-Dprefix=/usr'
|
||||
'-Dbuildtype=release'
|
||||
'-Dharfbuzz=dynamic'
|
||||
'-Dc_link_args=-lgcc_s' # something is messed up with my toolchain
|
||||
)
|
||||
|
||||
configure() {
|
||||
meson setup \
|
||||
--reconfigure \
|
||||
--cross-file "$MESON_CROSS_FILE" \
|
||||
"${CONFIGURE_OPTIONS[@]}" \
|
||||
build || exit 1
|
||||
}
|
||||
|
||||
build() {
|
||||
meson compile -C build || exit 1
|
||||
}
|
||||
|
||||
install() {
|
||||
meson install --destdir="$DESTDIR" -C build || exit 1
|
||||
}
|
||||
|
||||
@@ -26,3 +26,12 @@ build() {
|
||||
install() {
|
||||
meson install --destdir="$DESTDIR" -C build || exit 1
|
||||
}
|
||||
|
||||
post_install() {
|
||||
mkdir -p "$DESTDIR/etc/init.d"
|
||||
cat > "$DESTDIR/etc/init.d/gdk-pixbuf-update-loaders" << EOF
|
||||
#!/bin/Shell
|
||||
exec gdk-pixbuf-query-loaders --update-cache
|
||||
EOF
|
||||
chmod +x "$DESTDIR/etc/init.d/gdk-pixbuf-update-loaders"
|
||||
}
|
||||
|
||||
Executable
+26
@@ -0,0 +1,26 @@
|
||||
#!/bin/bash ../install.sh
|
||||
|
||||
NAME='gegl'
|
||||
VERSION='0.4.70'
|
||||
DOWNLOAD_URL="https://download.gimp.org/gegl/0.4/gegl-$VERSION.tar.xz#47f50d9c3aecd375deb48c11ebfead52d162e4fc162a4b3d44618277f1faec02"
|
||||
DEPENDENCIES=('json-glib' 'babl' 'libjpeg-turbo' 'libpng')
|
||||
CONFIGURE_OPTIONS=(
|
||||
'-Dprefix=/usr'
|
||||
'-Dbuildtype=release'
|
||||
)
|
||||
|
||||
configure() {
|
||||
meson setup \
|
||||
--reconfigure \
|
||||
--cross-file "$MESON_CROSS_FILE" \
|
||||
"${CONFIGURE_OPTIONS[@]}" \
|
||||
build || exit 1
|
||||
}
|
||||
|
||||
build() {
|
||||
meson compile -C build || exit 1
|
||||
}
|
||||
|
||||
install() {
|
||||
meson install --destdir="$DESTDIR" -C build || exit 1
|
||||
}
|
||||
Executable
+9
@@ -0,0 +1,9 @@
|
||||
#!/bin/bash
|
||||
|
||||
REVISION=1
|
||||
|
||||
source 'build.sh'
|
||||
|
||||
[[ "$VERSION" == 'git' ]] && VERSION=0.0
|
||||
|
||||
echo "${NAME}-${VERSION//[_-]/.}_${REVISION}.${BANAN_ARCH}"
|
||||
Executable
+31
@@ -0,0 +1,31 @@
|
||||
#!/bin/bash ../install.sh
|
||||
|
||||
NAME='gexiv2'
|
||||
VERSION='0.14.6' # gimp requires 0.14.x
|
||||
DOWNLOAD_URL="https://github.com/GNOME/gexiv2/archive/refs/tags/gexiv2-$VERSION.tar.gz#9083050df329b630f71f6f71aafc193c26e46548854ae21037d0a679ef62ae50"
|
||||
TAR_CONTENT="gexiv2-gexiv2-$VERSION"
|
||||
DEPENDENCIES=('exiv2' 'glib')
|
||||
CONFIGURE_OPTIONS=(
|
||||
'-Dprefix=/usr'
|
||||
'-Dbuildtype=release'
|
||||
'-Dintrospection=false'
|
||||
'-Dvapi=false'
|
||||
'-Dpython3=false'
|
||||
'-Dtests=false'
|
||||
)
|
||||
|
||||
configure() {
|
||||
meson setup \
|
||||
--reconfigure \
|
||||
--cross-file "$MESON_CROSS_FILE" \
|
||||
"${CONFIGURE_OPTIONS[@]}" \
|
||||
build || exit 1
|
||||
}
|
||||
|
||||
build() {
|
||||
meson compile -C build || exit 1
|
||||
}
|
||||
|
||||
install() {
|
||||
meson install --destdir="$DESTDIR" -C build || exit 1
|
||||
}
|
||||
Executable
+33
@@ -0,0 +1,33 @@
|
||||
#!/bin/bash ../install.sh
|
||||
|
||||
NAME='gimp'
|
||||
VERSION='3.2.4'
|
||||
DOWNLOAD_URL="https://download.gimp.org/gimp/v3.2/gimp-$VERSION.tar.xz#7312bc53e9c6d2d0056ca7b93f1c6b98707946dd934f714c21b8746ecb601588"
|
||||
DEPENDENCIES=('gtk3' 'gegl' 'gexiv2' 'glib-networking' 'librsvg' 'lcms2' 'libmypaint' 'mypaint-brushes' 'AppStream' 'libarchive' 'libXmu' 'poppler')
|
||||
CONFIGURE_OPTIONS=(
|
||||
'-Dprefix=/usr'
|
||||
'-Dbuildtype=release'
|
||||
'-Dshmem-type=sysv'
|
||||
'-Dgi-docgen=disabled'
|
||||
)
|
||||
|
||||
pre_configure() {
|
||||
# allow native pkgconfig lookup
|
||||
unset PKG_CONFIG_DIR PKG_CONFIG_SYSROOT_DIR PKG_CONFIG_LIBDIR PKG_CONFIG_PATH
|
||||
}
|
||||
|
||||
configure() {
|
||||
meson setup \
|
||||
--reconfigure \
|
||||
--cross-file "$MESON_CROSS_FILE" \
|
||||
"${CONFIGURE_OPTIONS[@]}" \
|
||||
_build || exit 1
|
||||
}
|
||||
|
||||
build() {
|
||||
meson compile -C _build || exit 1
|
||||
}
|
||||
|
||||
install() {
|
||||
meson install --destdir="$DESTDIR" -C _build || exit 1
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
diff -ruN gimp-3.2.4/meson.build gimp-3.2.4-banan_os/meson.build
|
||||
--- gimp-3.2.4/meson.build 2026-04-17 11:37:38.000000000 +0300
|
||||
+++ gimp-3.2.4-banan_os/meson.build 2026-08-24 21:47:23.319981280 +0300
|
||||
@@ -573,7 +573,7 @@
|
||||
pangoft2 = dependency('pangoft2', version: '>='+pango_minver)
|
||||
endif
|
||||
|
||||
-if cc.run('''
|
||||
+if meson.can_run_host_binaries() and cc.run('''
|
||||
#include <pango/pango.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
@@ -1580,7 +1580,7 @@
|
||||
endif
|
||||
|
||||
if shmem_choice == 'sysv'
|
||||
- check_ip_rmid_deferred_release = cc.run('''
|
||||
+ check_ip_rmid_deferred_release = host_os.contains('banan_os') or cc.run('''
|
||||
#include <sys/types.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
@@ -0,0 +1,13 @@
|
||||
diff -ruN gimp-3.2.4/libgimp/gimpplugin.c gimp-3.2.4-banan_os/libgimp/gimpplugin.c
|
||||
--- gimp-3.2.4/libgimp/gimpplugin.c 2026-04-17 11:37:38.000000000 +0300
|
||||
+++ gimp-3.2.4-banan_os/libgimp/gimpplugin.c 2026-08-24 21:47:23.319160010 +0300
|
||||
@@ -24,6 +24,9 @@
|
||||
#include <errno.h>
|
||||
#include <libintl.h>
|
||||
#include <string.h>
|
||||
+#ifdef __banan_os__
|
||||
+#include <sys/select.h>
|
||||
+#endif
|
||||
|
||||
#include "gimp.h"
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
diff -ruN gimp-3.2.4/meson.build gimp-3.2.4-banan_os/meson.build
|
||||
--- gimp-3.2.4/meson.build 2026-04-17 11:37:38.000000000 +0300
|
||||
+++ gimp-3.2.4-banan_os/meson.build 2026-08-24 21:47:23.319981280 +0300
|
||||
@@ -486,7 +486,7 @@
|
||||
# minimum requirement.
|
||||
add_project_arguments('-DGLIB_VERSION_MAX_ALLOWED=GLIB_VERSION_2_76', language: 'c')
|
||||
|
||||
-gi = dependency('gobject-introspection-1.0')
|
||||
+gi = dependency('gobject-introspection-1.0', required: false)
|
||||
|
||||
gobject = dependency('gobject-2.0', version: '>='+glib_minver)
|
||||
gmodule = dependency('gmodule-no-export-2.0')
|
||||
diff -ruN gimp-3.2.4/plug-ins/meson.build gimp-3.2.4-banan_os/plug-ins/meson.build
|
||||
--- gimp-3.2.4/plug-ins/meson.build 2026-04-17 11:37:38.000000000 +0300
|
||||
+++ gimp-3.2.4-banan_os/plug-ins/meson.build 2026-08-24 21:47:23.320319594 +0300
|
||||
@@ -35,10 +35,15 @@
|
||||
{ 'name': 'pagecurl', },
|
||||
{ 'name': 'print', },
|
||||
{ 'name': 'screenshot', },
|
||||
- { 'name': 'script-fu', },
|
||||
{ 'name': 'selection-to-path', }
|
||||
]
|
||||
|
||||
+if gi.found()
|
||||
+ comples_plugins_list += {
|
||||
+ 'name': 'script-fu',
|
||||
+ }
|
||||
+endif
|
||||
+
|
||||
if openexr.found()
|
||||
complex_plugins_list += {
|
||||
'name': 'file-exr',
|
||||
Executable
+31
@@ -0,0 +1,31 @@
|
||||
#!/bin/bash ../install.sh
|
||||
|
||||
NAME='glib-networking'
|
||||
VERSION='2.80.1'
|
||||
DOWNLOAD_URL="https://download.gnome.org/sources/glib-networking/${VERSION%.*}/glib-networking-$VERSION.tar.xz#b80e2874157cd55071f1b6710fa0b911d5ac5de106a9ee2a4c9c7bee61782f8e"
|
||||
DEPENDENCIES=('glib' 'openssl')
|
||||
CONFIGURE_OPTIONS=(
|
||||
'-Dprefix=/usr'
|
||||
'-Dbuildtype=release'
|
||||
'-Dlibproxy=disabled'
|
||||
'-Dgnome_proxy=disabled'
|
||||
'-Dgnutls=disabled'
|
||||
'-Dopenssl=enabled'
|
||||
'-Dc_link_args=-lgcc_s' # something is messed up with my toolchain
|
||||
)
|
||||
|
||||
configure() {
|
||||
meson setup \
|
||||
--reconfigure \
|
||||
--cross-file "$MESON_CROSS_FILE" \
|
||||
"${CONFIGURE_OPTIONS[@]}" \
|
||||
build || exit 1
|
||||
}
|
||||
|
||||
build() {
|
||||
meson compile -C build || exit 1
|
||||
}
|
||||
|
||||
install() {
|
||||
meson install --destdir="$DESTDIR" -C build || exit 1
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
diff -ruN glib-networking-2.80.1/meson.build glib-networking-2.80.1-banan_os/meson.build
|
||||
--- glib-networking-2.80.1/meson.build 2025-01-08 23:51:06.000000000 +0200
|
||||
+++ glib-networking-2.80.1-banan_os/meson.build 2026-08-24 21:00:58.043148228 +0300
|
||||
@@ -63,8 +63,7 @@
|
||||
gobject_dep = dependency('gobject-2.0')
|
||||
gmodule_dep = dependency('gmodule-2.0')
|
||||
|
||||
-gio_module_dir = gio_dep.get_variable('giomoduledir',
|
||||
- pkgconfig_define: ['libdir', join_paths(prefix, libdir)])
|
||||
+gio_module_dir = join_paths(prefix, libdir, 'gio', 'modules')
|
||||
assert(gio_module_dir != '', 'GIO_MODULE_DIR is missing from gio-2.0.pc')
|
||||
|
||||
# *** Checks for LibProxy ***
|
||||
@@ -25,3 +25,12 @@ build() {
|
||||
install() {
|
||||
meson install --destdir="$DESTDIR" -C build || exit 1
|
||||
}
|
||||
|
||||
post_install() {
|
||||
mkdir -p "$DESTDIR/etc/init.d"
|
||||
cat > "$DESTDIR/etc/init.d/glib-compile-schemas" << EOF
|
||||
#!/bin/Shell
|
||||
exec glib-compile-schemas /usr/share/glib-2.0/schemas
|
||||
EOF
|
||||
chmod +x "$DESTDIR/etc/init.d/glib-compile-schemas"
|
||||
}
|
||||
|
||||
+2
-1
@@ -1,8 +1,9 @@
|
||||
#!/bin/bash ../install.sh
|
||||
|
||||
NAME='gtk'
|
||||
NAME='gtk3'
|
||||
VERSION='3.24.49'
|
||||
DOWNLOAD_URL="https://gitlab.gnome.org/GNOME/gtk/-/archive/$VERSION/gtk-$VERSION.tar.gz#a2958d82986c81794e953a3762335fa7c78948706d23cced421f7245ca544cbc"
|
||||
TAR_CONTENT="gtk-$VERSION"
|
||||
DEPENDENCIES=('glib' 'gdk-pixbuf' 'pango' 'libatk' 'libepoxy' 'libXrandr' 'libXcursor' 'libXinerama')
|
||||
CONFIGURE_OPTIONS=(
|
||||
'-Dprefix=/usr'
|
||||
|
||||
+2
-17
@@ -1,8 +1,8 @@
|
||||
#!/bin/bash ../install.sh
|
||||
|
||||
NAME='harfbuzz'
|
||||
VERSION='12.2.0'
|
||||
DOWNLOAD_URL="https://github.com/harfbuzz/harfbuzz/releases/download/$VERSION/harfbuzz-$VERSION.tar.xz#ecb603aa426a8b24665718667bda64a84c1504db7454ee4cadbd362eea64e545"
|
||||
VERSION='14.3.1'
|
||||
DOWNLOAD_URL="https://github.com/harfbuzz/harfbuzz/releases/download/$VERSION/harfbuzz-$VERSION.tar.xz#9dae9538aae2ffdf70cec31f2c27bf68e2aaeeae3112688467697d5faf6194f7"
|
||||
DEPENDENCIES=('glib' 'freetype' 'icu')
|
||||
CONFIGURE_OPTIONS=(
|
||||
'-Dprefix=/usr'
|
||||
@@ -26,18 +26,3 @@ build() {
|
||||
install() {
|
||||
meson install --destdir="$DESTDIR" -C build || exit 1
|
||||
}
|
||||
|
||||
post_install() {
|
||||
if [ -n "$HARFBUZZ_CIRCULAR" ]; then
|
||||
return
|
||||
fi
|
||||
|
||||
export HARFBUZZ_CIRCULAR=1
|
||||
|
||||
for circular in freetype cairo; do
|
||||
pushd "$BANAN_PORT_DIR/$circular" >/dev/null || exit 1
|
||||
rm -f .compile_hash
|
||||
./build.sh || exit 1
|
||||
popd >/dev/null
|
||||
done
|
||||
}
|
||||
|
||||
+55
-4
@@ -15,8 +15,12 @@ installed_file="$BANAN_PORT_DIR/.installed_ports"
|
||||
if [ -z $DONT_REMOVE_INSTALLED ]; then
|
||||
export DONT_REMOVE_INSTALLED=1
|
||||
rm -f "$installed_file"
|
||||
rm -rf "$BANAN_SYSROOT/var/db/xbps"
|
||||
fi
|
||||
|
||||
PACKAGE_ROOT="$BANAN_PORT_DIR/package"
|
||||
PACKAGE_REPO="$PACKAGE_ROOT/repo"
|
||||
|
||||
export PATH="$BANAN_TOOLCHAIN_PREFIX/bin:$PATH"
|
||||
|
||||
export PKG_CONFIG_DIR=''
|
||||
@@ -54,6 +58,8 @@ MAKE_INSTALL_TARGETS=('install')
|
||||
|
||||
CONFIG_SUB=()
|
||||
|
||||
REVISION=1
|
||||
|
||||
clean() {
|
||||
find . -mindepth 1 -maxdepth 1 -not -name 'patches' -not -name 'build.sh' -exec rm -rf {} +
|
||||
}
|
||||
@@ -111,11 +117,15 @@ post_install() {
|
||||
|
||||
install() {
|
||||
for target in "${MAKE_INSTALL_TARGETS[@]}"; do
|
||||
make $target "DESTDIR=$BANAN_SYSROOT" || exit 1
|
||||
make $target "DESTDIR=$DESTDIR" || exit 1
|
||||
done
|
||||
}
|
||||
|
||||
source $1
|
||||
source "$1"
|
||||
|
||||
if [ -z $DESCRIPTION ]; then
|
||||
DESCRIPTION="TODO description for $NAME"
|
||||
fi
|
||||
|
||||
if [ -z $NAME ] || [ -z $VERSION ] || [ -z $DOWNLOAD_URL ]; then
|
||||
echo "Port does not set needed environment variables" >&2
|
||||
@@ -148,7 +158,16 @@ for dependency in "${DEPENDENCIES[@]}"; do
|
||||
|
||||
pushd "../$dependency" >/dev/null
|
||||
pwd
|
||||
if ! ./build.sh; then
|
||||
|
||||
version_string="$(../get-version-string.sh)"
|
||||
if [ -f "$PACKAGE_REPO/$version_string.xbps" ]; then
|
||||
run_xbps xbps-install \
|
||||
-r "$BANAN_SYSROOT" \
|
||||
-R "$PACKAGE_REPO" \
|
||||
-y "$dependency" \
|
||||
|| exit 1
|
||||
echo "${version_string%%_*}" >> "$installed_file"
|
||||
elif ! ./build.sh; then
|
||||
echo "Failed to install dependency '$dependency' of port '$NAME'"
|
||||
exit 1
|
||||
fi
|
||||
@@ -255,6 +274,38 @@ fi
|
||||
DESTDIR="$BANAN_SYSROOT"
|
||||
pre_install
|
||||
install
|
||||
grep -qsxF "$NAME-$VERSION" "$installed_file" || echo "$NAME-$VERSION" >> "$installed_file"
|
||||
post_install
|
||||
|
||||
find "$BANAN_SYSROOT/usr/lib" -name '*.la' -delete
|
||||
rm -f "$BANAN_SYSROOT/usr/share/info/dir"
|
||||
|
||||
grep -qsxF "$NAME-$VERSION" "$installed_file" || echo "$NAME-$VERSION" >> "$installed_file"
|
||||
|
||||
if (( $PACKAGE )); then
|
||||
mkdir -p "$PACKAGE_ROOT"
|
||||
|
||||
version_string=$(cd .. && ../get-version-string.sh)
|
||||
|
||||
package_dir="$PACKAGE_ROOT/$version_string"
|
||||
|
||||
rm -rf "$package_dir"
|
||||
mkdir "$package_dir"
|
||||
|
||||
dependencies=''
|
||||
for dep in "${DEPENDENCIES[@]}"; do
|
||||
dependencies+="$dep>=0 "
|
||||
done
|
||||
|
||||
DESTDIR="$package_dir"
|
||||
pre_install
|
||||
install
|
||||
post_install
|
||||
|
||||
find "$DESTDIR/usr/lib" -name '*.la' -delete
|
||||
rm -f "$DESTDIR/usr/share/info/dir"
|
||||
|
||||
mkdir -p "$PACKAGE_REPO"
|
||||
cd "$PACKAGE_REPO"
|
||||
run_xbps xbps-create -A "$BANAN_ARCH" -n "${version_string%.*}" -s "$DESCRIPTION" -D "$dependencies" "$package_dir"
|
||||
run_xbps xbps-rindex -af "$version_string.xbps"
|
||||
fi
|
||||
|
||||
Executable
+23
@@ -0,0 +1,23 @@
|
||||
#!/bin/bash ../install.sh
|
||||
|
||||
NAME='json-c'
|
||||
VERSION='0.18-20240915'
|
||||
DOWNLOAD_URL="https://github.com/json-c/json-c/archive/refs/tags/json-c-$VERSION.tar.gz#3112c1f25d39eca661fe3fc663431e130cc6e2f900c081738317fba49d29e298"
|
||||
TAR_CONTENT="json-c-json-c-$VERSION"
|
||||
|
||||
configure() {
|
||||
cmake --fresh -B build -S . -G Ninja \
|
||||
--toolchain="$BANAN_TOOLCHAIN_DIR/Toolchain.txt" \
|
||||
-DCMAKE_INSTALL_PREFIX=/usr \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DBUILD_STATIC_LIBS=OFF \
|
||||
|| exit 1
|
||||
}
|
||||
|
||||
build() {
|
||||
cmake --build build || exit 1
|
||||
}
|
||||
|
||||
install() {
|
||||
DESTDIR="$DESTDIR" cmake --install build || exit 1
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
diff -ruN json-c-0.18-20240915/CMakeLists.txt json-c-0.18-20240915-banan_os/CMakeLists.txt
|
||||
--- json-c-0.18-20240915/CMakeLists.txt 2024-09-15 19:22:45.000000000 +0300
|
||||
+++ json-c-0.18-20240915-banan_os/CMakeLists.txt 2026-03-25 02:59:13.104155305 +0200
|
||||
@@ -571,7 +571,7 @@
|
||||
set(INSTALL_PKGCONFIG_DIR "${CMAKE_INSTALL_LIBDIR}/pkgconfig" CACHE PATH "Installation directory for pkgconfig (.pc) files")
|
||||
install(FILES ${PROJECT_BINARY_DIR}/json-c.pc DESTINATION "${INSTALL_PKGCONFIG_DIR}")
|
||||
|
||||
-install(FILES ${JSON_C_PUBLIC_HEADERS} DESTINATION ${CMAKE_INSTALL_FULL_INCLUDEDIR}/json-c)
|
||||
+install(FILES ${JSON_C_PUBLIC_HEADERS} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/json-c)
|
||||
|
||||
if (CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME AND BUILD_TESTING AND
|
||||
(NOT MSVC OR NOT (MSVC_VERSION LESS 1800)) # Tests need at least VS2013
|
||||
Executable
+29
@@ -0,0 +1,29 @@
|
||||
#!/bin/bash ../install.sh
|
||||
|
||||
NAME='json-glib'
|
||||
VERSION='1.10.8'
|
||||
DOWNLOAD_URL="https://github.com/GNOME/json-glib/archive/refs/tags/$VERSION.tar.gz#7a114bdac0b2611a7207e981c37fa9b1e70d9cb642470cd9e967b135428cec52"
|
||||
DEPENDENCIES=('glib' 'json-c')
|
||||
CONFIGURE_OPTIONS=(
|
||||
'-Dprefix=/usr'
|
||||
'-Dbuildtype=release'
|
||||
'-Dintrospection=disabled'
|
||||
'-Dnls=disabled'
|
||||
'-Dtests=false'
|
||||
)
|
||||
|
||||
configure() {
|
||||
meson setup \
|
||||
--reconfigure \
|
||||
--cross-file "$MESON_CROSS_FILE" \
|
||||
"${CONFIGURE_OPTIONS[@]}" \
|
||||
build || exit 1
|
||||
}
|
||||
|
||||
build() {
|
||||
meson compile -C build || exit 1
|
||||
}
|
||||
|
||||
install() {
|
||||
meson install --destdir="$DESTDIR" -C build || exit 1
|
||||
}
|
||||
Executable
+28
@@ -0,0 +1,28 @@
|
||||
#!/bin/bash ../install.sh
|
||||
|
||||
NAME='lcms2'
|
||||
VERSION='2.18'
|
||||
DOWNLOAD_URL="https://github.com/mm2/Little-CMS/archive/refs/tags/lcms$VERSION.tar.gz#4f52a4459a93ac02b88e49b04dc0679e52fc92d36d3b722e5a1a44dbe8118236"
|
||||
TAR_CONTENT="Little-CMS-lcms$VERSION"
|
||||
DEPENDENCIES=('libtiff' 'libjpeg-turbo')
|
||||
CONFIGURE_OPTIONS=(
|
||||
'-Dprefix=/usr'
|
||||
'-Dbuildtype=release'
|
||||
'-Dtests=disabled'
|
||||
)
|
||||
|
||||
configure() {
|
||||
meson setup \
|
||||
--reconfigure \
|
||||
--cross-file "$MESON_CROSS_FILE" \
|
||||
"${CONFIGURE_OPTIONS[@]}" \
|
||||
build || exit 1
|
||||
}
|
||||
|
||||
build() {
|
||||
meson compile -C build || exit 1
|
||||
}
|
||||
|
||||
install() {
|
||||
meson install --destdir="$DESTDIR" -C build || exit 1
|
||||
}
|
||||
@@ -4,7 +4,7 @@ NAME='libXdamage'
|
||||
VERSION='1.1.7'
|
||||
DOWNLOAD_URL="https://www.x.org/releases/individual/lib/libXdamage-$VERSION.tar.xz#127067f521d3ee467b97bcb145aeba1078e2454d448e8748eb984d5b397bde24"
|
||||
CONFIG_SUB=('config.sub')
|
||||
DEPENDENCIES=('libX11') # FIXME: check deps
|
||||
DEPENDENCIES=('libX11' 'libXfixes')
|
||||
CONFIGURE_OPTIONS=(
|
||||
'--enable-shared=yes'
|
||||
'--enable-static=no'
|
||||
|
||||
Executable
+11
@@ -0,0 +1,11 @@
|
||||
#!/bin/bash ../install.sh
|
||||
|
||||
NAME='libXxf86vm'
|
||||
VERSION='1.1.7'
|
||||
DOWNLOAD_URL="https://xorg.freedesktop.org/archive/individual/lib/libXxf86vm-$VERSION.tar.xz#ae50c0f669e0af5a67cc4cd0f54f21d64a64d2660af883e80e95d3fe51b945d8"
|
||||
CONFIG_SUB=('config.sub')
|
||||
DEPENDENCIES=('libX11' 'libXext')
|
||||
CONFIGURE_OPTIONS=(
|
||||
'--enable-shared=yes'
|
||||
'--enable-static=no'
|
||||
)
|
||||
@@ -0,0 +1,31 @@
|
||||
diff -ruN libXxf86vm-1.1.7/configure libXxf86vm-1.1.7-banan_os/configure
|
||||
--- libXxf86vm-1.1.7/configure 2026-01-26 03:22:56.000000000 +0200
|
||||
+++ libXxf86vm-1.1.7-banan_os/configure 2026-07-05 09:42:42.300455316 +0300
|
||||
@@ -6162,6 +6162,10 @@
|
||||
lt_cv_deplibs_check_method=pass_all
|
||||
;;
|
||||
|
||||
+banan_os*)
|
||||
+ lt_cv_deplibs_check_method=pass_all
|
||||
+ ;;
|
||||
+
|
||||
beos*)
|
||||
lt_cv_deplibs_check_method=pass_all
|
||||
;;
|
||||
@@ -11696,6 +11700,16 @@
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
+
|
||||
+banan_os*)
|
||||
+ version_type=linux # correct to gnu/linux during the next big refactor
|
||||
+ need_lib_prefix=no
|
||||
+ need_version=no
|
||||
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
|
||||
+ soname_spec='$libname$release$shared_ext$major'
|
||||
+ dynamic_linker="$host_os DynamicLoader.so"
|
||||
+ shlibpath_var=LD_LIBRARY_PATH
|
||||
+ ;;
|
||||
|
||||
beos*)
|
||||
library_names_spec='$libname$shared_ext'
|
||||
Executable
+11
@@ -0,0 +1,11 @@
|
||||
#!/bin/bash ../install.sh
|
||||
|
||||
NAME='libcroco'
|
||||
VERSION='0.6.13'
|
||||
DOWNLOAD_URL="https://download.gnome.org/sources/libcroco/${VERSION%.*}/libcroco-$VERSION.tar.xz#767ec234ae7aa684695b3a735548224888132e063f92db585759b422570621d4"
|
||||
DEPENDENCIES=('glib' 'libxml2')
|
||||
CONFIG_SUB=('config.sub')
|
||||
CONFIGURE_OPTIONS=(
|
||||
'--disable-static'
|
||||
'--enable-shared'
|
||||
)
|
||||
+5
-5
@@ -1,7 +1,7 @@
|
||||
diff -ruN freetype-2.14.3/builds/unix/configure freetype-2.14.3-banan_os/builds/unix/configure
|
||||
--- freetype-2.14.3/builds/unix/configure 2026-03-22 17:10:53.000000000 +0200
|
||||
+++ freetype-2.14.3-banan_os/builds/unix/configure 2026-07-05 13:40:58.479544155 +0300
|
||||
@@ -5417,6 +5417,10 @@
|
||||
diff -ruN libcroco-0.6.13/configure libcroco-0.6.13-banan_os/configure
|
||||
--- libcroco-0.6.13/configure 2019-04-06 20:28:06.000000000 +0300
|
||||
+++ libcroco-0.6.13-banan_os/configure 2026-08-24 18:29:35.868215552 +0300
|
||||
@@ -5609,6 +5609,10 @@
|
||||
lt_cv_deplibs_check_method=pass_all
|
||||
;;
|
||||
|
||||
@@ -12,7 +12,7 @@ diff -ruN freetype-2.14.3/builds/unix/configure freetype-2.14.3-banan_os/builds/
|
||||
beos*)
|
||||
lt_cv_deplibs_check_method=pass_all
|
||||
;;
|
||||
@@ -11327,6 +11331,16 @@
|
||||
@@ -10822,6 +10826,16 @@
|
||||
esac
|
||||
;;
|
||||
|
||||
Executable
+21
@@ -0,0 +1,21 @@
|
||||
#!/bin/bash ../install.sh
|
||||
|
||||
NAME='libfyaml'
|
||||
VERSION='0.9.6'
|
||||
DOWNLOAD_URL="https://github.com/pantoniou/libfyaml/releases/download/v$VERSION/libfyaml-$VERSION.tar.gz#a59cc3331e2eb903ec36933ad52a45888041cac31e44f553a00511131242c483"
|
||||
|
||||
configure() {
|
||||
cmake --fresh -B build -S . -G Ninja \
|
||||
--toolchain="$BANAN_TOOLCHAIN_DIR/Toolchain.txt" \
|
||||
-DCMAKE_INSTALL_PREFIX=/usr \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
|| exit 1
|
||||
}
|
||||
|
||||
build() {
|
||||
cmake --build build || exit 1
|
||||
}
|
||||
|
||||
install() {
|
||||
DESTDIR="$DESTDIR" cmake --install build || exit 1
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
diff -ruN libfyaml-0.9.6/CMakeLists.txt libfyaml-0.9.6-banan_os/CMakeLists.txt
|
||||
--- libfyaml-0.9.6/CMakeLists.txt 2026-03-15 15:48:50.000000000 +0200
|
||||
+++ libfyaml-0.9.6-banan_os/CMakeLists.txt 2026-03-25 03:53:58.967967134 +0200
|
||||
@@ -1271,8 +1271,8 @@
|
||||
endif()
|
||||
|
||||
add_executable(fy-tool ${FY_TOOL_SOURCES})
|
||||
-target_include_directories(fy-tool PRIVATE ${FY_TOOL_INCLUDE_DIRS})
|
||||
-target_compile_definitions(fy-tool PRIVATE ${COMMON_C_DEFINITIONS})
|
||||
+target_include_directories(fy-tool PRIVATE ${FY_TOOL_INCLUDE_DIRS} ${CMAKE_CURRENT_BINARY_DIR})
|
||||
+target_compile_definitions(fy-tool PRIVATE ${COMMON_C_DEFINITIONS} HAVE_CONFIG_H)
|
||||
|
||||
target_link_libraries(fy-tool PRIVATE fyaml)
|
||||
|
||||
@@ -1340,9 +1340,10 @@
|
||||
src/internal/fy-thread.c
|
||||
${GETOPT_SOURCES}
|
||||
)
|
||||
-target_include_directories(fy-thread PRIVATE ${INTERNAL_TOOL_INCLUDES})
|
||||
+target_include_directories(fy-thread PRIVATE ${INTERNAL_TOOL_INCLUDES} ${CMAKE_CURRENT_BINARY_DIR})
|
||||
target_compile_definitions(fy-thread PRIVATE
|
||||
${COMMON_C_DEFINITIONS}
|
||||
+ HAVE_CONFIG_H
|
||||
FY_STATIC)
|
||||
if(NOT MSVC)
|
||||
if(APPLE)
|
||||
@@ -1373,10 +1374,12 @@
|
||||
)
|
||||
target_include_directories(fy-b3sum PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/blake3
|
||||
+ ${CMAKE_CURRENT_BINARY_DIR}
|
||||
${INTERNAL_TOOL_INCLUDES}
|
||||
)
|
||||
target_compile_definitions(fy-b3sum PRIVATE
|
||||
${COMMON_C_DEFINITIONS}
|
||||
+ HAVE_CONFIG_H
|
||||
FY_STATIC)
|
||||
if(NOT MSVC)
|
||||
if(APPLE)
|
||||
@@ -0,0 +1,12 @@
|
||||
diff -ruN libfyaml-0.9.6/include/libfyaml/libfyaml-endian.h libfyaml-0.9.6-banan_os/include/libfyaml/libfyaml-endian.h
|
||||
--- libfyaml-0.9.6/include/libfyaml/libfyaml-endian.h 2026-03-15 15:48:50.000000000 +0200
|
||||
+++ libfyaml-0.9.6-banan_os/include/libfyaml/libfyaml-endian.h 2026-03-25 03:35:29.164450940 +0200
|
||||
@@ -42,7 +42,7 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
-#if defined(__linux__) || defined(__CYGWIN__) || defined(__OpenBSD__) || defined(__GNU__) || defined(__EMSCRIPTEN__)
|
||||
+#if defined(__linux__) || defined(__CYGWIN__) || defined(__OpenBSD__) || defined(__GNU__) || defined(__EMSCRIPTEN__) || defined(__banan_os__)
|
||||
# include <endian.h>
|
||||
#elif defined(__APPLE__)
|
||||
# include <libkern/OSByteOrder.h>
|
||||
@@ -0,0 +1,17 @@
|
||||
diff -ruN libfyaml-0.9.6/src/util/fy-utils.c libfyaml-0.9.6-banan_os/src/util/fy-utils.c
|
||||
--- libfyaml-0.9.6/src/util/fy-utils.c 2026-03-15 15:48:50.000000000 +0200
|
||||
+++ libfyaml-0.9.6-banan_os/src/util/fy-utils.c 2026-03-25 03:41:24.070062486 +0200
|
||||
@@ -434,7 +434,13 @@
|
||||
|
||||
newt = t;
|
||||
|
||||
+#ifdef __banan_os__
|
||||
+ newt.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
|
||||
+ newt.c_oflag &= ~(OPOST);
|
||||
+ newt.c_lflag &= ~(ECHO | ECHONL | ISIG | ICANON | IEXTEN);
|
||||
+#else
|
||||
cfmakeraw(&newt);
|
||||
+#endif
|
||||
|
||||
ret = tcsetattr(fd, TCSANOW, &newt);
|
||||
if (ret != 0)
|
||||
Executable
+12
@@ -0,0 +1,12 @@
|
||||
#!/bin/bash ../install.sh
|
||||
|
||||
NAME='libmypaint'
|
||||
VERSION='1.6.1'
|
||||
DOWNLOAD_URL="https://github.com/mypaint/libmypaint/releases/download/v$VERSION/libmypaint-$VERSION.tar.xz#741754f293f6b7668f941506da07cd7725629a793108bb31633fb6c3eae5315f"
|
||||
DEPENDENCIES=('glib' 'json-c')
|
||||
CONFIG_SUB=('config.sub')
|
||||
CONFIGURE_OPTIONS=(
|
||||
'--disable-introspection'
|
||||
'--disable-i18n'
|
||||
'--disable-nls'
|
||||
)
|
||||
@@ -0,0 +1,31 @@
|
||||
diff -ruN libmypaint-1.6.1/configure libmypaint-1.6.1-banan_os/configure
|
||||
--- libmypaint-1.6.1/configure 2020-05-11 19:38:35.000000000 +0300
|
||||
+++ libmypaint-1.6.1-banan_os/configure 2026-03-25 03:05:53.901886496 +0200
|
||||
@@ -5608,6 +5608,10 @@
|
||||
lt_cv_deplibs_check_method=pass_all
|
||||
;;
|
||||
|
||||
+banan_os*)
|
||||
+ lt_cv_deplibs_check_method=pass_all
|
||||
+ ;;
|
||||
+
|
||||
beos*)
|
||||
lt_cv_deplibs_check_method=pass_all
|
||||
;;
|
||||
@@ -11347,6 +11351,16 @@
|
||||
esac
|
||||
;;
|
||||
|
||||
+banan_os*)
|
||||
+ version_type=linux # correct to gnu/linux during the next big refactor
|
||||
+ need_lib_prefix=no
|
||||
+ need_version=no
|
||||
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
|
||||
+ soname_spec='$libname$release$shared_ext$major'
|
||||
+ dynamic_linker="$host_os DynamicLoader.so"
|
||||
+ shlibpath_var=LD_LIBRARY_PATH
|
||||
+ ;;
|
||||
+
|
||||
beos*)
|
||||
library_names_spec='$libname$shared_ext'
|
||||
dynamic_linker="$host_os ld.so"
|
||||
Executable
+15
@@ -0,0 +1,15 @@
|
||||
#!/bin/bash ../install.sh
|
||||
|
||||
NAME='librsvg' # last pre-rust version
|
||||
VERSION='2.40.21'
|
||||
DOWNLOAD_URL="https://download.gnome.org/sources/librsvg/${VERSION%.*}/librsvg-$VERSION.tar.xz#f7628905f1cada84e87e2b14883ed57d8094dca3281d5bcb24ece4279e9a92ba"
|
||||
DEPENDENCIES=('gdk-pixbuf' 'glib' 'libxml2' 'libcroco' 'cairo' 'pango')
|
||||
CONFIG_SUB=('config.sub')
|
||||
CONFIGURE_OPTIONS=(
|
||||
'--disable-static'
|
||||
'--enable-shared'
|
||||
'--enable-pixbuf-loader'
|
||||
'--disable-introspection'
|
||||
'--disable-installed-tests'
|
||||
'--disable-always-build-tests'
|
||||
)
|
||||
@@ -0,0 +1,31 @@
|
||||
diff -ruN librsvg-2.40.21/configure librsvg-2.40.21-banan_os/configure
|
||||
--- librsvg-2.40.21/configure 2020-02-26 19:45:16.000000000 +0200
|
||||
+++ librsvg-2.40.21-banan_os/configure 2026-08-24 18:34:52.949804530 +0300
|
||||
@@ -6802,6 +6802,10 @@
|
||||
lt_cv_deplibs_check_method=pass_all
|
||||
;;
|
||||
|
||||
+banan_os*)
|
||||
+ lt_cv_deplibs_check_method=pass_all
|
||||
+ ;;
|
||||
+
|
||||
beos*)
|
||||
lt_cv_deplibs_check_method=pass_all
|
||||
;;
|
||||
@@ -12275,6 +12279,16 @@
|
||||
esac
|
||||
;;
|
||||
|
||||
+banan_os*)
|
||||
+ version_type=linux # correct to gnu/linux during the next big refactor
|
||||
+ need_lib_prefix=no
|
||||
+ need_version=no
|
||||
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
|
||||
+ soname_spec='$libname$release$shared_ext$major'
|
||||
+ dynamic_linker="$host_os DynamicLoader.so"
|
||||
+ shlibpath_var=LD_LIBRARY_PATH
|
||||
+ ;;
|
||||
+
|
||||
beos*)
|
||||
library_names_spec='$libname$shared_ext'
|
||||
dynamic_linker="$host_os ld.so"
|
||||
@@ -0,0 +1,13 @@
|
||||
diff -ruN librsvg-2.40.21/configure librsvg-2.40.21-banan_os/configure
|
||||
--- librsvg-2.40.21/configure 2020-02-26 19:45:16.000000000 +0200
|
||||
+++ librsvg-2.40.21-banan_os/configure 2026-08-24 19:52:43.388200018 +0300
|
||||
@@ -14745,6 +14745,9 @@
|
||||
gdk_pixbuf_binarydir="`$PKG_CONFIG --variable=gdk_pixbuf_binarydir gdk-pixbuf-2.0`"
|
||||
gdk_pixbuf_moduledir=`$PKG_CONFIG --variable gdk_pixbuf_moduledir gdk-pixbuf-2.0`
|
||||
gdk_pixbuf_cache_file=`$PKG_CONFIG --variable gdk_pixbuf_cache_file gdk-pixbuf-2.0`
|
||||
+ gdk_pixbuf_binarydir="${gdk_pixbuf_binarydir#$PKG_CONFIG_SYSROOT_DIR}"
|
||||
+ gdk_pixbuf_moduledir="${gdk_pixbuf_moduledir#$PKG_CONFIG_SYSROOT_DIR}"
|
||||
+ gdk_pixbuf_cache_file="${gdk_pixbuf_cache_file#$PKG_CONFIG_SYSROOT_DIR}"
|
||||
fi
|
||||
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
diff -ruN librsvg-2.40.21/rsvg-css.c librsvg-2.40.21-banan_os/rsvg-css.c
|
||||
--- librsvg-2.40.21/rsvg-css.c 2018-10-02 01:50:22.000000000 +0300
|
||||
+++ librsvg-2.40.21-banan_os/rsvg-css.c 2026-08-24 18:45:05.745087552 +0300
|
||||
@@ -839,7 +839,7 @@
|
||||
}
|
||||
|
||||
static void
|
||||
-rsvg_xml_noerror (void *data, xmlErrorPtr error)
|
||||
+rsvg_xml_noerror (void *data, const xmlError* error)
|
||||
{
|
||||
}
|
||||
|
||||
diff -ruN librsvg-2.40.21/rsvg-private.h librsvg-2.40.21-banan_os/rsvg-private.h
|
||||
--- librsvg-2.40.21/rsvg-private.h 2020-02-26 19:40:25.000000000 +0200
|
||||
+++ librsvg-2.40.21-banan_os/rsvg-private.h 2026-08-24 18:45:12.583727389 +0300
|
||||
@@ -31,7 +31,7 @@
|
||||
|
||||
#include "rsvg.h"
|
||||
|
||||
-#include <libxml/SAX.h>
|
||||
+#include <libxml/tree.h>
|
||||
#include <libxml/xmlmemory.h>
|
||||
#include <pango/pango.h>
|
||||
#include <glib.h>
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/bin/bash
|
||||
#!/bin/bash ../install.sh
|
||||
|
||||
export MESA_VARIANT='glx'
|
||||
exec ../mesa/build.sh
|
||||
MESA_VARIANT='glx'
|
||||
source ../mesa/build.sh
|
||||
|
||||
Executable
+5
@@ -0,0 +1,5 @@
|
||||
#!/bin/bash ../install.sh
|
||||
|
||||
NAME='mypaint-brushes'
|
||||
VERSION='2.0.2'
|
||||
DOWNLOAD_URL="https://github.com/mypaint/mypaint-brushes/releases/download/v$VERSION/mypaint-brushes-$VERSION.tar.xz#7984a74edef94571d872d0629b224abaa956a36f632f5c5516b33d22e49eb566"
|
||||
@@ -7,6 +7,7 @@ DEPENDENCIES=('ncurses')
|
||||
CONFIG_SUB=('config.sub')
|
||||
CONFIGURE_OPTIONS=(
|
||||
'ac_cv_header_glob_h=no'
|
||||
'CFLAGS=-Dpthread_self=pthread_self'
|
||||
)
|
||||
|
||||
pre_configure() {
|
||||
|
||||
+10
-6
@@ -6,7 +6,7 @@ DOWNLOAD_URL="https://ftpmirror.gnu.org/gnu/ncurses/ncurses-$VERSION.tar.gz#355b
|
||||
CONFIG_SUB=('config.sub')
|
||||
CONFIGURE_OPTIONS=(
|
||||
"--with-pkg-config='$PKG_CONFIG'"
|
||||
"--with-pkg-config-libdir=/usr/lib/pkgconfig"
|
||||
'--with-pkg-config-libdir=/usr/lib/pkgconfig'
|
||||
'--enable-pc-files'
|
||||
'--enable-sigwinch'
|
||||
'--with-shared'
|
||||
@@ -16,13 +16,17 @@ CONFIGURE_OPTIONS=(
|
||||
CFLAGS='-std=c17'
|
||||
)
|
||||
|
||||
pre_configure() {
|
||||
unset TERMINFO TERMINFO_DIRS
|
||||
}
|
||||
|
||||
post_install() {
|
||||
for lib in ncurses ncurses++ form panel menu; do
|
||||
ln -sv ${lib}w.pc "$DESTDIR/usr/lib/pkgconfig/$lib.pc"
|
||||
for lib in ncurses form panel menu; do
|
||||
ln -svf ${lib}w.pc "$DESTDIR/usr/lib/pkgconfig/$lib.pc"
|
||||
done
|
||||
|
||||
ln -sv libncursesw.so "$DESTDIR/usr/lib/libncurses.so"
|
||||
ln -svf libncursesw.so "$DESTDIR/usr/lib/libncurses.so"
|
||||
|
||||
shellrc="$BANAN_SYSROOT/home/user/.shellrc"
|
||||
grep -q 'export NCURSES_NO_UTF8_ACS=' "$shellrc" || echo 'export NCURSES_NO_UTF8_ACS=1' >> "$shellrc"
|
||||
mkdir -p "$DESTDIR/etc/profile.d"
|
||||
echo 'export NCURSES_NO_UTF8_ACS=1' > "$DESTDIR/etc/profile.d/ncurses.sh"
|
||||
}
|
||||
|
||||
@@ -10,5 +10,5 @@ configure() {
|
||||
|
||||
install() {
|
||||
mkdir -p "$DESTDIR/usr/bin"
|
||||
cp src/nyancat "$DESTDIR/usr/bin/"
|
||||
cp -v src/nyancat "$DESTDIR/usr/bin/" || exit 1
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ post_install() {
|
||||
openssl rehash "$BANAN_SYSROOT/etc/cacert/extracted"
|
||||
find "$BANAN_SYSROOT/etc/cacert/extracted" -type l -print0 |
|
||||
while IFS= read -r -d '' link; do
|
||||
ln -s "../../cacert/extracted/$(readlink "$link")" "$DESTDIR/etc/ssl/certs/${link##*/}"
|
||||
ln -sf "../../cacert/extracted/$(readlink "$link")" "$DESTDIR/etc/ssl/certs/${link##*/}"
|
||||
rm "$link"
|
||||
done
|
||||
}
|
||||
|
||||
Executable
+33
@@ -0,0 +1,33 @@
|
||||
#!/bin/bash
|
||||
|
||||
if [[ -z $BANAN_ROOT_DIR ]]; then
|
||||
export BANAN_ROOT_DIR="$(realpath $(dirname $(realpath "$0"))/..)"
|
||||
fi
|
||||
|
||||
source "$BANAN_ROOT_DIR/script/config.sh"
|
||||
|
||||
package_standalone() {
|
||||
pushd "$BANAN_PORT_DIR/$1" >/dev/null
|
||||
|
||||
local version_string="$(../get-version-string.sh)"
|
||||
if [ ! -f "$BANAN_PORT_DIR/package/repo/${version_string}.xbps" ]; then
|
||||
local dependency
|
||||
for dependency in $(source build.sh; echo ${DEPENDENCIES[*]}); do
|
||||
package_standalone "$dependency"
|
||||
done
|
||||
|
||||
find "$BANAN_SYSROOT/usr/lib" \( -type f -o -type l \) -delete
|
||||
PACKAGE=1 ./build.sh || echo "$port_name" >> ../failed-ports
|
||||
fi
|
||||
|
||||
popd >/dev/null
|
||||
}
|
||||
|
||||
cd "$BANAN_PORT_DIR"
|
||||
for build_script in */build.sh; do
|
||||
port_name="${build_script%/*}"
|
||||
|
||||
[[ "$port_name" == 'llvm' ]] && continue
|
||||
|
||||
package_standalone "$port_name"
|
||||
done
|
||||
@@ -3,7 +3,7 @@
|
||||
NAME='pango'
|
||||
VERSION='1.57.0'
|
||||
DOWNLOAD_URL="https://gitlab.gnome.org/GNOME/pango/-/archive/$VERSION/pango-$VERSION.tar.gz#1b2e2f683dfb5adec3faf17087ade8c648f10a5d3d0e17e421e0ac1a39e6740e"
|
||||
DEPENDENCIES=('glib' 'fontconfig' 'cairo' 'fribidi' 'libXft')
|
||||
DEPENDENCIES=('glib' 'harfbuzz' 'fontconfig' 'cairo' 'fribidi' 'libXft')
|
||||
CONFIGURE_OPTIONS=(
|
||||
'-Dprefix=/usr'
|
||||
'-Dbuildtype=release'
|
||||
|
||||
Executable
+21
@@ -0,0 +1,21 @@
|
||||
#!/bin/bash ../install.sh
|
||||
|
||||
NAME='poppler-data'
|
||||
VERSION='0.4.12'
|
||||
DOWNLOAD_URL="https://poppler.freedesktop.org/poppler-data-$VERSION.tar.gz#c835b640a40ce357e1b83666aabd95edffa24ddddd49b8daff63adb851cdab74"
|
||||
|
||||
configure() {
|
||||
cmake --fresh -B build -S . -G Ninja \
|
||||
--toolchain="$BANAN_TOOLCHAIN_DIR/Toolchain.txt" \
|
||||
-DCMAKE_INSTALL_PREFIX='/usr' \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
|| exit 1
|
||||
}
|
||||
|
||||
build() {
|
||||
cmake --build build ||exit 1
|
||||
}
|
||||
|
||||
install() {
|
||||
DESTDIR="$DESTDIR" cmake --install build ||exit 1
|
||||
}
|
||||
Executable
+28
@@ -0,0 +1,28 @@
|
||||
#!/bin/bash ../install.sh
|
||||
|
||||
NAME='poppler'
|
||||
VERSION='26.03.0'
|
||||
DOWNLOAD_URL="https://poppler.freedesktop.org/poppler-$VERSION.tar.xz#8b3c5e2a9f2ab4c3ec5029f28af1b433c6b71f0d1e7b3997aa561cf1c0ca4ebe"
|
||||
DEPENDENCIES=('gtk3' 'cairo' 'boost' 'curl' 'lcms2' 'libtiff' 'poppler-data')
|
||||
|
||||
configure() {
|
||||
cmake --fresh -B build -S . -G Ninja \
|
||||
--toolchain="$BANAN_TOOLCHAIN_DIR/Toolchain.txt" \
|
||||
-DCMAKE_INSTALL_PREFIX=/usr \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DBUILD_SHARED_LIBS=ON \
|
||||
-DENABLE_NSS3=OFF \
|
||||
-DENABLE_GPGME=OFF \
|
||||
-DENABLE_QT5=OFF \
|
||||
-DENABLE_QT6=OFF \
|
||||
-DENABLE_LIBOPENJPEG=none \
|
||||
|| exit 1
|
||||
}
|
||||
|
||||
build() {
|
||||
cmake --build build ||exit 1
|
||||
}
|
||||
|
||||
install() {
|
||||
DESTDIR="$DESTDIR" cmake --install build ||exit 1
|
||||
}
|
||||
+8
-11
@@ -1,25 +1,22 @@
|
||||
#!/bin/bash ../install.sh
|
||||
|
||||
NAME='python'
|
||||
VERSION='3.13.3'
|
||||
DOWNLOAD_URL="https://www.python.org/ftp/python/$VERSION/Python-$VERSION.tar.xz#40f868bcbdeb8149a3149580bb9bfd407b3321cd48f0be631af955ac92c0e041"
|
||||
VERSION='3.14.7'
|
||||
DOWNLOAD_URL="https://www.python.org/ftp/python/$VERSION/Python-$VERSION.tar.xz#3b48dac8fb59f62eaa67ac83c1eb12bda1b7a08406dd286e252c11a66be27f81"
|
||||
TAR_CONTENT="Python-$VERSION"
|
||||
DEPENDENCIES=('ncurses' 'zlib' 'openssl')
|
||||
DEPENDENCIES=('ncurses' 'openssl' 'libffi' 'zlib' 'zstd' 'bzip2')
|
||||
CONFIG_SUB=('config.sub')
|
||||
CONFIGURE_OPTIONS=(
|
||||
"--build=$(uname -m)-pc-linux-gnu"
|
||||
"--with-build-python=python3.13"
|
||||
'--without-ensurepip'
|
||||
'--with-build-python=python3.14'
|
||||
'--disable-ipv6'
|
||||
'--disable-test-modules'
|
||||
'--enable-shared'
|
||||
'--disable-test-modules'
|
||||
'ac_cv_file__dev_ptmx=no'
|
||||
'ac_cv_file__dev_ptc=no'
|
||||
)
|
||||
|
||||
pre_configure() {
|
||||
if ! command -v python3.13 &>/dev/null ; then
|
||||
echo "You need to have python3.13 installed on your host machine" >&2
|
||||
exit 1
|
||||
fi
|
||||
post_install() {
|
||||
mkdir -p "$DESTDIR/usr/bin"
|
||||
ln -svf python3 "$DESTDIR/usr/bin/python" || exit 1
|
||||
}
|
||||
|
||||
+11
-18
@@ -1,7 +1,7 @@
|
||||
diff -ruN Python-3.13.3/configure Python-3.13.3-banan_os/configure
|
||||
--- Python-3.13.3/configure 2025-04-08 16:54:08.000000000 +0300
|
||||
+++ Python-3.13.3-banan_os/configure 2025-04-19 04:25:20.860260051 +0300
|
||||
@@ -4052,6 +4052,9 @@
|
||||
diff -ru python-3.14.7/configure python-3.14.7-banan_os/configure
|
||||
--- python-3.14.7/configure 2026-08-05 13:29:49.000000000 +0300
|
||||
+++ python-3.14.7-banan_os/configure 2026-08-25 12:39:57.212768646 +0300
|
||||
@@ -4112,6 +4112,9 @@
|
||||
*-*-linux*)
|
||||
ac_sys_system=Linux
|
||||
;;
|
||||
@@ -11,7 +11,7 @@ diff -ruN Python-3.13.3/configure Python-3.13.3-banan_os/configure
|
||||
*-*-cygwin*)
|
||||
ac_sys_system=Cygwin
|
||||
;;
|
||||
@@ -4500,6 +4503,9 @@
|
||||
@@ -4591,6 +4594,9 @@
|
||||
_host_ident=$host_cpu
|
||||
esac
|
||||
;;
|
||||
@@ -21,7 +21,7 @@ diff -ruN Python-3.13.3/configure Python-3.13.3-banan_os/configure
|
||||
*-*-cygwin*)
|
||||
_host_ident=
|
||||
;;
|
||||
@@ -7603,6 +7609,11 @@
|
||||
@@ -7751,6 +7757,11 @@
|
||||
PY3LIBRARY=libpython3.so
|
||||
fi
|
||||
;;
|
||||
@@ -33,7 +33,7 @@ diff -ruN Python-3.13.3/configure Python-3.13.3-banan_os/configure
|
||||
hp*|HP*)
|
||||
case `uname -m` in
|
||||
ia64)
|
||||
@@ -12983,7 +12994,7 @@
|
||||
@@ -13750,7 +13761,7 @@
|
||||
Emscripten*|WASI*)
|
||||
LDSHARED='$(CC) -shared'
|
||||
LDCXXSHARED='$(CXX) -shared';;
|
||||
@@ -42,19 +42,12 @@ diff -ruN Python-3.13.3/configure Python-3.13.3-banan_os/configure
|
||||
LDSHARED='$(CC) -shared'
|
||||
LDCXXSHARED='$(CXX) -shared';;
|
||||
FreeBSD*)
|
||||
@@ -13069,6 +13080,7 @@
|
||||
@@ -13835,7 +13846,7 @@
|
||||
then CCSHARED="-fPIC";
|
||||
else CCSHARED="+z";
|
||||
fi;;
|
||||
Linux*|GNU*) CCSHARED="-fPIC";;
|
||||
+ banan_os*) CCSHARED="-fPIC";;
|
||||
- Linux*|GNU*) CCSHARED="-fPIC";;
|
||||
+ Linux*|GNU*|banan_os*) CCSHARED="-fPIC";;
|
||||
Emscripten*|WASI*)
|
||||
if test "x$enable_wasm_dynamic_linking" = xyes
|
||||
then :
|
||||
@@ -23609,6 +23621,7 @@
|
||||
|
||||
case $ac_sys_system in
|
||||
Darwin) ;;
|
||||
+banan_os) ;;
|
||||
*) LIBM=-lm
|
||||
esac
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-libm=STRING" >&5
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user