2022-03-26 05:54:00 +01:00
|
|
|
#include <stdint.h>
|
|
|
|
#include <stddef.h>
|
|
|
|
#include <limine.h>
|
|
|
|
|
|
|
|
// The Limine requests can be placed anywhere, but it is important that
|
|
|
|
// the compiler does not optimise them away, so, usually, they should
|
|
|
|
// be made volatile or equivalent.
|
|
|
|
|
2023-03-30 07:45:42 +02:00
|
|
|
static volatile struct limine_framebuffer_request framebuffer_request = {
|
|
|
|
.id = LIMINE_FRAMEBUFFER_REQUEST,
|
2022-03-26 05:54:00 +01:00
|
|
|
.revision = 0
|
|
|
|
};
|
|
|
|
|
2023-03-08 08:21:58 +01:00
|
|
|
// GCC and Clang reserve the right to generate calls to the following
|
|
|
|
// 4 functions even if they are not directly called.
|
|
|
|
// Implement them as the C specification mandates.
|
|
|
|
// DO NOT remove or rename these functions, or stuff will eventually break!
|
|
|
|
// They CAN be moved to a different .c file.
|
|
|
|
|
|
|
|
void *memcpy(void *dest, const void *src, size_t n) {
|
|
|
|
uint8_t *pdest = (uint8_t *)dest;
|
|
|
|
const uint8_t *psrc = (const uint8_t *)src;
|
|
|
|
|
|
|
|
for (size_t i = 0; i < n; i++) {
|
|
|
|
pdest[i] = psrc[i];
|
2022-03-26 05:54:00 +01:00
|
|
|
}
|
2023-03-08 08:21:58 +01:00
|
|
|
|
|
|
|
return dest;
|
|
|
|
}
|
|
|
|
|
|
|
|
void *memset(void *s, int c, size_t n) {
|
|
|
|
uint8_t *p = (uint8_t *)s;
|
|
|
|
|
|
|
|
for (size_t i = 0; i < n; i++) {
|
|
|
|
p[i] = (uint8_t)c;
|
|
|
|
}
|
|
|
|
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
|
|
|
void *memmove(void *dest, const void *src, size_t n) {
|
|
|
|
uint8_t *pdest = (uint8_t *)dest;
|
|
|
|
const uint8_t *psrc = (const uint8_t *)src;
|
|
|
|
|
|
|
|
if (src > dest) {
|
|
|
|
for (size_t i = 0; i < n; i++) {
|
|
|
|
pdest[i] = psrc[i];
|
|
|
|
}
|
|
|
|
} else if (src < dest) {
|
|
|
|
for (size_t i = n; i > 0; i--) {
|
|
|
|
pdest[i-1] = psrc[i-1];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return dest;
|
|
|
|
}
|
|
|
|
|
|
|
|
int memcmp(const void *s1, const void *s2, size_t n) {
|
|
|
|
const uint8_t *p1 = (const uint8_t *)s1;
|
|
|
|
const uint8_t *p2 = (const uint8_t *)s2;
|
|
|
|
|
|
|
|
for (size_t i = 0; i < n; i++) {
|
|
|
|
if (p1[i] != p2[i]) {
|
|
|
|
return p1[i] < p2[i] ? -1 : 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
2022-03-26 05:54:00 +01:00
|
|
|
}
|
|
|
|
|
2023-03-08 08:21:58 +01:00
|
|
|
// Halt and catch fire function.
|
|
|
|
static void hcf(void) {
|
|
|
|
asm ("cli");
|
|
|
|
for (;;) {
|
|
|
|
asm ("hlt");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-03-26 05:54:00 +01:00
|
|
|
// The following will be our kernel's entry point.
|
2023-03-08 08:21:58 +01:00
|
|
|
// If renaming _start() to something else, make sure to change the
|
|
|
|
// linker script accordingly.
|
2022-03-26 05:54:00 +01:00
|
|
|
void _start(void) {
|
2023-03-30 07:45:42 +02:00
|
|
|
// Ensure we got a framebuffer.
|
|
|
|
if (framebuffer_request.response == NULL
|
|
|
|
|| framebuffer_request.response->framebuffer_count < 1) {
|
2023-03-08 08:21:58 +01:00
|
|
|
hcf();
|
2022-03-26 05:54:00 +01:00
|
|
|
}
|
|
|
|
|
2023-03-30 07:45:42 +02:00
|
|
|
// Fetch the first framebuffer.
|
|
|
|
struct limine_framebuffer *framebuffer = framebuffer_request.response->framebuffers[0];
|
2023-02-28 12:41:28 +01:00
|
|
|
|
2023-03-30 07:45:42 +02:00
|
|
|
// Note: we assume the framebuffer model is RGB with 32-bit pixels.
|
|
|
|
for (size_t i = 0; i < 100; i++) {
|
|
|
|
uint32_t *fb_ptr = framebuffer->address;
|
|
|
|
fb_ptr[i * (framebuffer->pitch / 4) + i] = 0xffffff;
|
|
|
|
}
|
2022-03-26 05:54:00 +01:00
|
|
|
|
|
|
|
// We're done, just hang...
|
2023-03-08 08:21:58 +01:00
|
|
|
hcf();
|
2022-03-26 05:54:00 +01:00
|
|
|
}
|