summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Kling <awesomekling@gmail.com>2019-01-09 02:29:11 +0100
committerAndreas Kling <awesomekling@gmail.com>2019-01-09 02:29:11 +0100
commit659c54e32b859b5a1f748e613543d52e17c4c2c3 (patch)
tree12d6f61aaaf868f0176e7f42b694b1eef3f9f104
parent9963da900583dc54f46c649978aa8a574a0bd508 (diff)
downloadserenity-659c54e32b859b5a1f748e613543d52e17c4c2c3.zip
Switch into 1024x768x32bpp VESA LFB mode at boot.
This is going to be pretty cool once I can hook up the Widgets/ code to it.
-rwxr-xr-xKernel/Boot/boot.asm37
-rw-r--r--Kernel/Makefile9
-rw-r--r--Kernel/MemoryManager.cpp18
-rw-r--r--Kernel/MemoryManager.h3
-rw-r--r--Kernel/Process.cpp73
-rw-r--r--Kernel/Process.h12
-rw-r--r--Kernel/WindowComposer.cpp12
-rw-r--r--Kernel/WindowComposer.h7
-rw-r--r--Kernel/init.cpp3
9 files changed, 172 insertions, 2 deletions
diff --git a/Kernel/Boot/boot.asm b/Kernel/Boot/boot.asm
index fdd0027e94..77caf40398 100755
--- a/Kernel/Boot/boot.asm
+++ b/Kernel/Boot/boot.asm
@@ -9,6 +9,43 @@ boot:
mov ss, ax
mov sp, 0xffff
+ ; get vesa modes
+ mov ax, 0x4f00
+ xor dx, dx
+ mov es, dx
+ mov di, 0xc000
+ mov [es:di], byte 'V'
+ mov [es:di+1], byte 'B'
+ mov [es:di+2], byte 'E'
+ mov [es:di+3], byte '2'
+ int 0x10
+ cmp ax, 0x004f
+ jne fug
+ cmp [es:di], byte 'V'
+ jne fug
+ cmp [es:di+1], byte 'E'
+ jne fug
+ cmp [es:di+2], byte 'S'
+ jne fug
+ cmp [es:di+3], byte 'A'
+ jne fug
+
+ ; get vesa info
+ mov ax, 0x4f01
+ mov cx, 0x144
+ xor dx, dx
+ mov es, dx
+ mov di, 0x2000
+ int 0x10
+ cmp ax, 0x004f
+ jne fug
+
+ mov ax, 0x4f02
+ mov bx, 0x4144
+ int 0x10
+ cmp ax, 0x004f
+ jne fug
+
push cs
pop ds
xor bx, bx
diff --git a/Kernel/Makefile b/Kernel/Makefile
index 8ed28871b4..590a12d51b 100644
--- a/Kernel/Makefile
+++ b/Kernel/Makefile
@@ -24,7 +24,8 @@ KERNEL_OBJS = \
DoubleBuffer.o \
ELFImage.o \
ELFLoader.o \
- KSyms.o
+ KSyms.o \
+ WindowComposer.o
VFS_OBJS = \
../VirtualFileSystem/DiskDevice.o \
@@ -40,13 +41,17 @@ VFS_OBJS = \
../VirtualFileSystem/FileDescriptor.o \
../VirtualFileSystem/SyntheticFileSystem.o
+WIDGETS_OBJS = \
+ ../Widgets/Window.o \
+ ../Widgets/Painter.o
+
AK_OBJS = \
../AK/String.o \
../AK/StringImpl.o \
../AK/StringBuilder.o \
../AK/FileSystemPath.o
-OBJS = $(KERNEL_OBJS) $(VFS_OBJS) $(AK_OBJS) $(ELFLOADER_OBJS)
+OBJS = $(KERNEL_OBJS) $(VFS_OBJS) $(AK_OBJS) $(WIDGETS_OBJS)
NASM = nasm
KERNEL = kernel
diff --git a/Kernel/MemoryManager.cpp b/Kernel/MemoryManager.cpp
index 63c3a7758b..2d263311a3 100644
--- a/Kernel/MemoryManager.cpp
+++ b/Kernel/MemoryManager.cpp
@@ -652,6 +652,12 @@ RetainPtr<VMObject> VMObject::create_anonymous(size_t size)
return adopt(*new VMObject(size));
}
+RetainPtr<VMObject> VMObject::create_framebuffer_wrapper(PhysicalAddress paddr, size_t size)
+{
+ size = ceilDiv(size, PAGE_SIZE) * PAGE_SIZE;
+ return adopt(*new VMObject(paddr, size));
+}
+
RetainPtr<VMObject> VMObject::clone()
{
return adopt(*new VMObject(*this));
@@ -676,6 +682,18 @@ VMObject::VMObject(size_t size)
m_physical_pages.resize(page_count());
}
+VMObject::VMObject(PhysicalAddress paddr, size_t size)
+ : m_anonymous(true)
+ , m_size(size)
+{
+ MM.register_vmo(*this);
+ for (size_t i = 0; i < size; i += PAGE_SIZE) {
+ m_physical_pages.append(adopt(*new PhysicalPage(paddr.offset(i), false)));
+ }
+ ASSERT(m_physical_pages.size() == page_count());
+}
+
+
VMObject::VMObject(RetainPtr<Vnode>&& vnode, size_t size)
: m_size(size)
, m_vnode(move(vnode))
diff --git a/Kernel/MemoryManager.h b/Kernel/MemoryManager.h
index c5732a3ea8..cb8863ac81 100644
--- a/Kernel/MemoryManager.h
+++ b/Kernel/MemoryManager.h
@@ -23,6 +23,7 @@ class PhysicalPage {
AK_MAKE_ETERNAL
friend class MemoryManager;
friend class PageDirectory;
+ friend class VMObject;
public:
PhysicalAddress paddr() const { return m_paddr; }
@@ -73,6 +74,7 @@ class VMObject : public Retainable<VMObject> {
public:
static RetainPtr<VMObject> create_file_backed(RetainPtr<Vnode>&&, size_t);
static RetainPtr<VMObject> create_anonymous(size_t);
+ static RetainPtr<VMObject> create_framebuffer_wrapper(PhysicalAddress, size_t);
RetainPtr<VMObject> clone();
~VMObject();
@@ -93,6 +95,7 @@ private:
VMObject(RetainPtr<Vnode>&&, size_t);
explicit VMObject(VMObject&);
explicit VMObject(size_t);
+ VMObject(PhysicalAddress, size_t);
String m_name;
bool m_anonymous { false };
Unix::off_t m_vnode_offset { 0 };
diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp
index c13c824b60..60347dfcd9 100644
--- a/Kernel/Process.cpp
+++ b/Kernel/Process.cpp
@@ -1811,3 +1811,76 @@ Unix::clock_t Process::sys$times(Unix::tms* times)
times->tms_cstime = m_ticks_in_kernel_for_dead_children;
return 0;
}
+
+struct vbe_info_structure {
+ char signature[4]; // must be "VESA" to indicate valid VBE support
+ word version; // VBE version; high byte is major version, low byte is minor version
+ dword oem; // segment:offset pointer to OEM
+ dword capabilities; // bitfield that describes card capabilities
+ dword video_modes; // segment:offset pointer to list of supported video modes
+ word video_memory; // amount of video memory in 64KB blocks
+ word software_rev; // software revision
+ dword vendor; // segment:offset to card vendor string
+ dword product_name; // segment:offset to card model name
+ dword product_rev; // segment:offset pointer to product revision
+ char reserved[222]; // reserved for future expansion
+ char oem_data[256]; // OEM BIOSes store their strings in this area
+} __attribute__ ((packed));
+
+struct vbe_mode_info_structure {
+ word attributes; // deprecated, only bit 7 should be of interest to you, and it indicates the mode supports a linear frame buffer.
+ byte window_a; // deprecated
+ byte window_b; // deprecated
+ word granularity; // deprecated; used while calculating bank numbers
+ word window_size;
+ word segment_a;
+ word segment_b;
+ dword win_func_ptr; // deprecated; used to switch banks from protected mode without returning to real mode
+ word pitch; // number of bytes per horizontal line
+ word width; // width in pixels
+ word height; // height in pixels
+ byte w_char; // unused...
+ byte y_char; // ...
+ byte planes;
+ byte bpp; // bits per pixel in this mode
+ byte banks; // deprecated; total number of banks in this mode
+ byte memory_model;
+ byte bank_size; // deprecated; size of a bank, almost always 64 KB but may be 16 KB...
+ byte image_pages;
+ byte reserved0;
+
+ byte red_mask;
+ byte red_position;
+ byte green_mask;
+ byte green_position;
+ byte blue_mask;
+ byte blue_position;
+ byte reserved_mask;
+ byte reserved_position;
+ byte direct_color_attributes;
+
+ dword framebuffer; // physical address of the linear frame buffer; write here to draw to the screen
+ dword off_screen_mem_off;
+ word off_screen_mem_size; // size of memory in the framebuffer but not being displayed on the screen
+ byte reserved1[206];
+} __attribute__ ((packed));
+
+DisplayInfo Process::get_display_info()
+{
+ DisplayInfo info;
+ //auto* vinfo = reinterpret_cast<vbe_info_structure*>(0xc000);
+ auto* vmode = reinterpret_cast<vbe_mode_info_structure*>(0x2000);
+ dbgprintf("VESA framebuffer, %ux%u, %u bpp @ P%x\n", vmode->width, vmode->height, vmode->bpp, vmode->framebuffer);
+ dbgprintf("Returning display info in %s<%u>\n", name().characters(), pid());
+ info.width = vmode->width;
+ info.height = vmode->height;
+ info.bpp = vmode->bpp;
+ info.pitch = vmode->pitch;
+ size_t framebuffer_size = info.pitch * info.height;
+ if (!m_display_framebuffer_region) {
+ auto framebuffer_vmo = VMObject::create_framebuffer_wrapper(PhysicalAddress(vmode->framebuffer), framebuffer_size);
+ m_display_framebuffer_region = allocate_region_with_vmo(LinearAddress(0xe0000000), framebuffer_size, move(framebuffer_vmo), 0, "framebuffer", true, true);
+ }
+ info.framebuffer = m_display_framebuffer_region->linearAddress.asPtr();
+ return info;
+}
diff --git a/Kernel/Process.h b/Kernel/Process.h
index 64770bcdb2..f84ca09fb7 100644
--- a/Kernel/Process.h
+++ b/Kernel/Process.h
@@ -32,6 +32,14 @@ struct SignalActionData {
LinearAddress restorer;
};
+struct DisplayInfo {
+ unsigned width;
+ unsigned height;
+ unsigned bpp;
+ unsigned pitch;
+ byte* framebuffer;
+};
+
class Process : public InlineLinkedListNode<Process> {
friend class InlineLinkedListNode<Process>;
public:
@@ -175,6 +183,8 @@ public:
Unix::clock_t sys$times(Unix::tms*);
int sys$utime(const char* pathname, const struct Unix::utimbuf*);
+ DisplayInfo get_display_info();
+
static void initialize();
void crash() NORETURN;
@@ -317,6 +327,8 @@ private:
Region* m_stack_region { nullptr };
Region* m_signal_stack_user_region { nullptr };
Region* m_signal_stack_kernel_region { nullptr };
+
+ RetainPtr<Region> m_display_framebuffer_region;
};
extern Process* current;
diff --git a/Kernel/WindowComposer.cpp b/Kernel/WindowComposer.cpp
new file mode 100644
index 0000000000..b6be2f4575
--- /dev/null
+++ b/Kernel/WindowComposer.cpp
@@ -0,0 +1,12 @@
+#include "WindowComposer.h"
+#include "Process.h"
+
+void WindowComposer_main()
+{
+ auto info = current->get_display_info();
+
+ dbgprintf("Entering WindowComposer main loop.\n");
+ for (;;) {
+
+ }
+}
diff --git a/Kernel/WindowComposer.h b/Kernel/WindowComposer.h
new file mode 100644
index 0000000000..3aecaf817b
--- /dev/null
+++ b/Kernel/WindowComposer.h
@@ -0,0 +1,7 @@
+#pragma once
+
+class WindowComposer {
+public:
+
+};
+
diff --git a/Kernel/init.cpp b/Kernel/init.cpp
index f36e3baa94..3b6074d21a 100644
--- a/Kernel/init.cpp
+++ b/Kernel/init.cpp
@@ -102,6 +102,9 @@ static void init_stage2()
Process::create_kernel_process("spawn_stress", spawn_stress);
#endif
+ extern void WindowComposer_main();
+ Process::create_kernel_process("WindowComposer", WindowComposer_main);
+
current->sys$exit(0);
ASSERT_NOT_REACHED();
}