org
This commit is contained in:
parent
ce2b373313
commit
9114529153
8
.clang-format
Normal file
8
.clang-format
Normal file
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
BasedOnStyle: LLVM
|
||||
AlignAfterOpenBracket: Align
|
||||
AlignConsecutiveDeclarations: 'true'
|
||||
AlignTrailingComments: 'true'
|
||||
DisableFormat: 'false'
|
||||
|
||||
...
|
|
@ -1,4 +1,6 @@
|
|||
cmake_minimum_required(VERSION 3.10)
|
||||
set(CMAKE_C_COMPILER_WORKS 1) # todo: find the proper fix for this, rn this is
|
||||
# b/c cmake expects libc to be avaliable and it's not under nixos
|
||||
|
||||
project(razzle C ASM)
|
||||
|
||||
|
@ -20,7 +22,7 @@ set(CMAKE_ASM_FLAGS "-g")
|
|||
set(LINKER_SCRIPT ${CMAKE_SOURCE_DIR}/linker.ld)
|
||||
|
||||
# Common source files
|
||||
FILE(GLOB SOURCES kernel/kernel.c)
|
||||
FILE(GLOB_RECURSE SOURCES kernel/*.c)
|
||||
|
||||
# Architecture Specific Files
|
||||
if (ARCH STREQUAL "i386")
|
||||
|
@ -40,13 +42,15 @@ add_custom_command(OUTPUT os.iso
|
|||
COMMENT "Generating OS ISO"
|
||||
)
|
||||
|
||||
# Supplemental PCI data to be loaded into memory
|
||||
add_custom_target(pci_supp
|
||||
COMMAND xxd -i ../build_supp/pci/pci.ids > ../kernel/pci_supp.c
|
||||
COMMAND xxd -i ../build_supp/pci/pci.ids > ../supp/pci_supp.c
|
||||
COMMENT "Generating Supplemental PCI data"
|
||||
)
|
||||
|
||||
|
||||
# Run & Debug targets
|
||||
add_custom_target(run COMMAND qemu-system-i386 -boot d -m 512 -machine type=pc-i440fx-3.1 -serial stdio -device piix3-ide,id=ide -drive id=disk,file=/dev/null,format=raw,if=none -device ide-hd,drive=disk,bus=ide.1 -device ide-cd,drive=cdrom -drive id=cdrom,file=os.iso,media=cdrom,if=none DEPENDS os.iso)
|
||||
add_custom_target(run
|
||||
COMMAND qemu-system-i386 -boot d -m 512 -machine type=pc-i440fx-3.1 -serial mon:stdio -device piix3-ide,id=ide -drive id=disk,file=/dev/null,format=raw,if=none -device ide-hd,drive=disk,bus=ide.1 -device ide-cd,drive=cdrom -drive id=cdrom,file=os.iso,media=cdrom,if=none
|
||||
DEPENDS os.iso)
|
||||
add_custom_target(debug COMMAND ../debug.sh DEPENDS os.iso)
|
||||
|
||||
|
|
9
arch/i386/asm/asm.c
Normal file
9
arch/i386/asm/asm.c
Normal file
|
@ -0,0 +1,9 @@
|
|||
#include "asm.h"
|
||||
|
||||
void __sl_acquire(uint32_t *lock_id) {
|
||||
__asm__("retry_lock: lock bts $0,(%0); pause; jc retry_lock" : "+g"(lock_id));
|
||||
}
|
||||
|
||||
void __sl_release(uint32_t *lock_id) {
|
||||
__asm__("lock btr $0, (%0)" : "+g"(lock_id));
|
||||
}
|
|
@ -9,13 +9,8 @@ struct regs {
|
|||
unsigned int eip, cs, eflags, useresp, ss;
|
||||
};
|
||||
|
||||
void __sl_acquire(uint32_t *lock_id) {
|
||||
__asm__("retry_lock: lock bts $0,(%0); pause; jc retry_lock" : "+g"(lock_id));
|
||||
}
|
||||
|
||||
void __sl_release(uint32_t *lock_id) {
|
||||
__asm__("lock btr $0, (%0)" : "+g"(lock_id));
|
||||
}
|
||||
void __sl_acquire(uint32_t *);
|
||||
void __sl_release(uint32_t *);
|
||||
|
||||
static inline void outb(int port, int val) {
|
||||
__asm__ volatile("outb %b0, %w1" : : "a"(val), "Nd"(port) : "memory");
|
||||
|
@ -37,6 +32,16 @@ static inline uint32_t inl(uint32_t port) {
|
|||
return val;
|
||||
}
|
||||
|
||||
static inline void outw(uint16_t port, uint16_t val) {
|
||||
__asm__ volatile("outw %w0, %w1" : : "a"(val), "Nd"(port) : "memory");
|
||||
}
|
||||
|
||||
static inline uint16_t inw(uint16_t port) {
|
||||
uint32_t val;
|
||||
__asm__ volatile("inw %w1, %w0" : "=a"(val) : "Nd"(port) : "memory");
|
||||
return val;
|
||||
}
|
||||
|
||||
static inline void interrupt_disable() { __asm__ volatile("cli"); }
|
||||
|
||||
static inline void interrupt_enable() { __asm__ volatile("sti"); }
|
|
@ -1,6 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include "../../kernel/memory.c"
|
||||
#include "../../kernel/memory/memory.h"
|
||||
#include <stdint.h>
|
||||
|
||||
struct gdt_row_t {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include "../../kernel/memory.c"
|
||||
#include "../../kernel/memory/memory.h"
|
||||
#include "./handlers.h"
|
||||
#include "gdt.c"
|
||||
|
||||
|
@ -26,7 +26,8 @@ enum idt_flag_t {
|
|||
IDTFLAG_INTERRUPT = 0b00001110,
|
||||
};
|
||||
|
||||
#define KERNEL_INTERRUPT_FLAG (IDTFLAG_PRESENT | IDTFLAG_DPL_KERNEL | IDTFLAG_INTERRUPT)
|
||||
#define KERNEL_INTERRUPT_FLAG \
|
||||
(IDTFLAG_PRESENT | IDTFLAG_DPL_KERNEL | IDTFLAG_INTERRUPT)
|
||||
#define USER_TRAP_FLAG (IDTFLAG_PRESENT | IDTFLAG_DPL_USER | IDTFLAG_INTERRUPT)
|
||||
|
||||
#define IDT_SIZE (256)
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#pragma once
|
||||
|
||||
#include "../../kernel/ps2.c"
|
||||
#include "../../kernel/syscall.c"
|
||||
#include "./asm.c"
|
||||
#include "../../kernel/drivers/ps2/ps2.h"
|
||||
#include "../../kernel/syscall/syscall.h"
|
||||
#include "./asm/asm.c"
|
||||
#include "./idt.c"
|
||||
#include "handlers.h"
|
||||
|
||||
|
|
|
@ -1,13 +1,4 @@
|
|||
#pragma once
|
||||
|
||||
#include "asm.c"
|
||||
|
||||
enum eflags_t {
|
||||
EFLAG_CARRY = 0x0001,
|
||||
EFLAG_RES = 0x0002,
|
||||
EFLAG_PARITY = 0x0004,
|
||||
EFLAG_INTERRUPT = 0x0200
|
||||
};
|
||||
#include "scheduler.h"
|
||||
|
||||
void initialize_registers(struct regs *new_regs, char *entrypoint,
|
||||
uint32_t address_base, uint32_t address_space_size) {
|
15
arch/i386/scheduler/scheduler.h
Normal file
15
arch/i386/scheduler/scheduler.h
Normal file
|
@ -0,0 +1,15 @@
|
|||
#pragma once
|
||||
|
||||
#include "../asm/asm.h"
|
||||
#include <stdint.h>
|
||||
|
||||
enum eflags_t {
|
||||
EFLAG_CARRY = 0x0001,
|
||||
EFLAG_RES = 0x0002,
|
||||
EFLAG_PARITY = 0x0004,
|
||||
EFLAG_INTERRUPT = 0x0200
|
||||
};
|
||||
|
||||
void initialize_registers(struct regs *, char *, uint32_t, uint32_t);
|
||||
void store_registers(struct regs *, struct regs *);
|
||||
void switch_context(struct regs *, struct regs *);
|
2
format.sh
Executable file
2
format.sh
Executable file
|
@ -0,0 +1,2 @@
|
|||
git ls-files -- '*.c' '*.h' | xargs clang-format -i -style=file
|
||||
git diff --exit-code --color
|
116
kernel/acpi/rsdp.c
Normal file
116
kernel/acpi/rsdp.c
Normal file
|
@ -0,0 +1,116 @@
|
|||
#include <stdint.h>
|
||||
|
||||
#include "../io/io.h"
|
||||
#include "../memory/memory.h"
|
||||
#include "rsdp.h"
|
||||
|
||||
struct rsdp_t {
|
||||
char signature[8];
|
||||
uint8_t checksum;
|
||||
char oem_id[6];
|
||||
uint8_t revision;
|
||||
uint32_t rsdt_address;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct xsdp_t {
|
||||
char signature[8];
|
||||
uint8_t checksum;
|
||||
char oem_id[6];
|
||||
uint8_t revision;
|
||||
uint32_t unused;
|
||||
uint32_t length;
|
||||
uint32_t xsdt_addr_hi;
|
||||
uint32_t xsdt_addr_lo;
|
||||
uint8_t checksum_ext;
|
||||
uint8_t unused_[3];
|
||||
} __attribute__((packed));
|
||||
|
||||
struct acpi_header_t {
|
||||
char signature[4];
|
||||
uint32_t length;
|
||||
uint8_t revision;
|
||||
uint8_t checksum;
|
||||
char oem_id[6];
|
||||
char oem_table_id[8];
|
||||
uint32_t oem_revision;
|
||||
uint32_t creator_id;
|
||||
uint32_t creator_division;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct rsdt_t {
|
||||
struct acpi_header_t header;
|
||||
uint32_t pointer[64];
|
||||
};
|
||||
|
||||
uint8_t validate(struct rsdp_t *ptr) {
|
||||
char sig[] = "RSD PTR ";
|
||||
if (!memseq(ptr->signature, sig, 8))
|
||||
return 0;
|
||||
|
||||
uint8_t *rsdp_bytes = (uint8_t *)ptr;
|
||||
uint8_t sum = 0;
|
||||
for (uint8_t i = 0; i < 20; i++) {
|
||||
sum += rsdp_bytes[i];
|
||||
}
|
||||
|
||||
if (sum == 0 && ptr->revision == 2) {
|
||||
printf_nolock("acpi: ACPI v2+ not yet supported :(\n");
|
||||
for (;;) {
|
||||
}
|
||||
// TODO: test with ACPI 2 System
|
||||
struct xsdp_t *r2_ptr = (struct xsdp_t *)ptr;
|
||||
|
||||
uint8_t *xsdp_bytes = ((uint8_t *)r2_ptr) + 8;
|
||||
for (uint8_t i = 0; i < 16; i++) {
|
||||
sum += xsdp_bytes[i];
|
||||
}
|
||||
}
|
||||
|
||||
return sum == 0;
|
||||
}
|
||||
|
||||
char *find_table(struct rsdt_t *table, char *sig) {
|
||||
uint32_t entries = (table->header.length - sizeof table->header) / 4;
|
||||
for (uint32_t i = 0; i < entries; i++) {
|
||||
struct acpi_header_t *entry = (struct acpi_header_t *)table->pointer[i];
|
||||
if (memseq(entry->signature, sig, 4)) {
|
||||
printf_nolock("Found %s / %s\n", entry->oem_id, entry->signature);
|
||||
printf_nolock("Signature: %s\n", entry->signature);
|
||||
printf_nolock("Length : %d\n", entry->length);
|
||||
printf_nolock("Oem ID : %s\n", entry->oem_id);
|
||||
printf_nolock("Checksum : %d\n", entry->checksum);
|
||||
return (void *)entry;
|
||||
}
|
||||
}
|
||||
|
||||
printf_nolock("Not Found");
|
||||
return 0;
|
||||
}
|
||||
|
||||
void find_rsdp() {
|
||||
struct rsdp_t *ptr;
|
||||
|
||||
volatile uint8_t found = 0;
|
||||
for (uint32_t addr = 0x00000000; addr <= 0x000FFFFF; addr++) {
|
||||
ptr = (struct rsdp_t *)addr;
|
||||
|
||||
if (validate(ptr)) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
uint8_t *ebda = (uint8_t *)(*((uint16_t *)0x40e) << 4);
|
||||
for (uint32_t i = 0; i <= 1024; i += 16) {
|
||||
ptr = (struct rsdp_t *)ebda;
|
||||
if (validate(ptr)) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
printf_nolock("acpi: RSDP Found [OEM: %s, SIG: %s]\n", ptr->oem_id,
|
||||
ptr->signature);
|
||||
}
|
3
kernel/acpi/rsdp.h
Normal file
3
kernel/acpi/rsdp.h
Normal file
|
@ -0,0 +1,3 @@
|
|||
#pragma once
|
||||
|
||||
void find_rsdp();
|
17
kernel/drivers/blk/blk.h
Normal file
17
kernel/drivers/blk/blk.h
Normal file
|
@ -0,0 +1,17 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
struct block_dev {
|
||||
char name[16];
|
||||
uint32_t sector_size;
|
||||
uint32_t device_no;
|
||||
uint32_t num_sectors;
|
||||
uint32_t (*read_sector)(uint32_t, uint32_t, char *);
|
||||
uint32_t (*write_sector)(uint32_t, uint32_t, char *);
|
||||
};
|
||||
|
||||
void BLK__init();
|
||||
uint32_t BLK__register_device(struct block_dev*);
|
||||
uint32_t BLK__get_block_devices(struct block_dev* devices, uint32_t req_num);
|
||||
uint32_t BLK__get_block_device(struct block_dev* devices, uint32_t req_num);
|
45
kernel/drivers/blk/ramblk/ramblk.c
Normal file
45
kernel/drivers/blk/ramblk/ramblk.c
Normal file
|
@ -0,0 +1,45 @@
|
|||
#include "./ramblk.h"
|
||||
#include "../../../memory/memory.h"
|
||||
#include "../blk.h"
|
||||
|
||||
#define RAMFS_BYTES (1024 * 1024 * 5) // 5 MB
|
||||
#define SECTOR_SIZE (512)
|
||||
|
||||
char ramfs_blocks[RAMFS_BYTES];
|
||||
|
||||
uint32_t RAMBLK__read_sector(uint32_t device, uint32_t sector, char *out) {
|
||||
if (sector * SECTOR_SIZE >= RAMFS_BYTES) {
|
||||
// Out of bounds
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t byte = sector * SECTOR_SIZE;
|
||||
|
||||
memcpy(ramfs_blocks + byte, out, SECTOR_SIZE);
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint32_t RAMBLK__write_sector(uint32_t device, uint32_t sector, char *in) {
|
||||
if ((sector + 1) * SECTOR_SIZE >= RAMFS_BYTES) {
|
||||
// Out of bounds
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t byte = sector * SECTOR_SIZE;
|
||||
|
||||
memcpy(in, ramfs_blocks + byte, SECTOR_SIZE);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void RAMBLK__init() {
|
||||
memset(ramfs_blocks, 0x00, RAMFS_BYTES);
|
||||
struct block_dev bd = {
|
||||
.name = "RAM_BLK",
|
||||
.sector_size = SECTOR_SIZE,
|
||||
.device_no = 0,
|
||||
.num_sectors = RAMFS_BYTES / SECTOR_SIZE,
|
||||
.read_sector = &RAMBLK__read_sector,
|
||||
.write_sector = &RAMBLK__write_sector
|
||||
};
|
||||
BLK__register_device(&bd);
|
||||
}
|
7
kernel/drivers/blk/ramblk/ramblk.h
Normal file
7
kernel/drivers/blk/ramblk/ramblk.h
Normal file
|
@ -0,0 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
void RAMBLK__init();
|
||||
uint32_t RAMBLK__read_sector(uint32_t device, uint32_t sector, char *out);
|
||||
uint32_t RAMBLK__write_sector(uint32_t device, uint32_t sector, char *in);
|
208
kernel/drivers/fs/nqfs/nqfs.c
Normal file
208
kernel/drivers/fs/nqfs/nqfs.c
Normal file
|
@ -0,0 +1,208 @@
|
|||
// Nick's Quick(ly made) File System
|
||||
#include "nqfs.h"
|
||||
#include "../../../io/io.h"
|
||||
#include "../../../memory/memory.h"
|
||||
|
||||
#define FILEPTR_SECTORS (128)
|
||||
#define FILEPTR_PER_SECTOR (4)
|
||||
#define FILEPTR_CNT (FILEPTR_SECTORS * FILEPTR_PER_SECTOR)
|
||||
|
||||
void NQFS_init() {}
|
||||
|
||||
uint32_t NQFS_get_next_free_block(struct block_dev *device) {
|
||||
char sector[512];
|
||||
struct NQFS_storage_block *sb = (struct NQFS_storage_block *)sector;
|
||||
|
||||
for (uint32_t i = FILEPTR_SECTORS; i < device->num_sectors; ++i) {
|
||||
if (!device->read_sector(device->device_no, i, sector)) {
|
||||
return 0;
|
||||
}
|
||||
if (sb->magic_number != 0xC001) {
|
||||
sb->magic_number = 0xC001;
|
||||
sb->next_sector = 0;
|
||||
if (!device->write_sector(device->device_no, i, sector)) {
|
||||
return 0;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t NQFS_create_file(struct block_dev *device, char *filename) {
|
||||
char sector[512];
|
||||
for (int i = 0; i < FILEPTR_SECTORS; ++i) {
|
||||
if (!device->read_sector(device->device_no, i, sector)) {
|
||||
return 0;
|
||||
}
|
||||
struct NQFS_inode *fp = (struct NQFS_inode *)sector;
|
||||
for (int j = 0; j < FILEPTR_PER_SECTOR; ++j) {
|
||||
if (!fp->allocd) {
|
||||
uint32_t new_sector = NQFS_get_next_free_block(device);
|
||||
if (new_sector == 0) {
|
||||
return 0;
|
||||
}
|
||||
fp->allocd = 1;
|
||||
fp->size = 0;
|
||||
fp->start_sector = new_sector;
|
||||
strncpy(filename, fp->filename, NQFS_MAX_FILENAME_SIZE);
|
||||
fp->filename[NQFS_MAX_FILENAME_SIZE - 1] = '\0';
|
||||
if (!device->write_sector(device->device_no, i, sector)) {
|
||||
return 0;
|
||||
}
|
||||
printf_nolock("Created file \"%s\" at sector %d fp %d\n", fp->filename,
|
||||
new_sector, i);
|
||||
return i;
|
||||
}
|
||||
fp++;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
uint32_t NQFS_read_bytes(struct block_dev *device, uint32_t inode_sector,
|
||||
char *out, uint32_t size) {
|
||||
char sector[512];
|
||||
struct NQFS_inode *fp = (struct NQFS_inode *)sector;
|
||||
if (!device->read_sector(device->device_no, inode_sector, sector)) {
|
||||
return 0;
|
||||
}
|
||||
char storage_sector[512];
|
||||
struct NQFS_storage_block *sb = (struct NQFS_storage_block *)storage_sector;
|
||||
|
||||
if (fp->start_sector != 0) {
|
||||
uint32_t read_sector = fp->start_sector;
|
||||
|
||||
if (size > fp->size) {
|
||||
size = fp->size;
|
||||
}
|
||||
|
||||
while (size > 0) {
|
||||
if (!device->read_sector(device->device_no, read_sector,
|
||||
storage_sector)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t readable = NQFS_STORAGE_BYTES_SECTOR;
|
||||
if (size < readable) {
|
||||
readable = size;
|
||||
}
|
||||
|
||||
// Copy data into struct
|
||||
memcpy(sb->data, out, readable);
|
||||
out += readable;
|
||||
size -= readable;
|
||||
|
||||
if (size > 0) {
|
||||
read_sector = sb->next_sector;
|
||||
if (read_sector == 0) {
|
||||
return size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return size;
|
||||
|
||||
} else {
|
||||
printf_nolock("didn't find start\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t NQFS_write_bytes(struct block_dev *device, uint32_t inode_sector,
|
||||
char *in, uint32_t size) {
|
||||
uint32_t total_written = 0;
|
||||
char sector[512];
|
||||
struct NQFS_inode *fp = (struct NQFS_inode *)sector;
|
||||
if (!device->read_sector(device->device_no, inode_sector, sector)) {
|
||||
return 0;
|
||||
}
|
||||
char storage_sector[512];
|
||||
struct NQFS_storage_block *sb = (struct NQFS_storage_block *)storage_sector;
|
||||
|
||||
if (fp->start_sector != 0) {
|
||||
uint32_t cur_size = fp->size;
|
||||
uint32_t read_sector = fp->start_sector;
|
||||
|
||||
while (cur_size >= NQFS_STORAGE_BYTES_SECTOR) {
|
||||
if (!device->read_sector(device->device_no, read_sector,
|
||||
storage_sector)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
cur_size -= NQFS_STORAGE_BYTES_SECTOR;
|
||||
read_sector = sb->next_sector;
|
||||
if (read_sector == 0) {
|
||||
sb->next_sector = NQFS_get_next_free_block(device);
|
||||
read_sector = sb->next_sector;
|
||||
if (read_sector == 0) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while (size > 0) {
|
||||
if (!device->read_sector(device->device_no, read_sector,
|
||||
storage_sector)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t writeable = NQFS_STORAGE_BYTES_SECTOR - cur_size;
|
||||
if (size < writeable) {
|
||||
writeable = size;
|
||||
}
|
||||
|
||||
// Copy data into struct
|
||||
memcpy(in + total_written, sb->data + cur_size, writeable);
|
||||
cur_size = 0;
|
||||
|
||||
fp->size += writeable;
|
||||
total_written += writeable;
|
||||
|
||||
if (!device->write_sector(device->device_no, inode_sector, sector)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Write struct out to disk
|
||||
if (!device->write_sector(device->device_no, read_sector,
|
||||
storage_sector)) {
|
||||
return 0;
|
||||
}
|
||||
size -= writeable;
|
||||
if (size > 0) {
|
||||
sb->next_sector = NQFS_get_next_free_block(device);
|
||||
// Write struct out to disk
|
||||
if (!device->write_sector(device->device_no, read_sector,
|
||||
storage_sector)) {
|
||||
return 0;
|
||||
}
|
||||
read_sector = sb->next_sector;
|
||||
if (read_sector == 0) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
printf_nolock("File didn't point to a storage block\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return total_written;
|
||||
}
|
||||
|
||||
void NQFS_DEBUG_list_files(struct block_dev *device) {
|
||||
char sector[512];
|
||||
for (int i = 0; i < FILEPTR_SECTORS; ++i) {
|
||||
if (!device->read_sector(device->device_no, i, sector)) {
|
||||
printf_nolock("Error reading sector %d\n", i);
|
||||
return;
|
||||
}
|
||||
struct NQFS_inode *fp = (struct NQFS_inode *)sector;
|
||||
for (int j = 0; j < FILEPTR_PER_SECTOR; ++j) {
|
||||
if (fp->allocd) {
|
||||
printf_nolock("Found file: %s\n", fp->filename);
|
||||
}
|
||||
fp++;
|
||||
}
|
||||
}
|
||||
}
|
32
kernel/drivers/fs/nqfs/nqfs.h
Normal file
32
kernel/drivers/fs/nqfs/nqfs.h
Normal file
|
@ -0,0 +1,32 @@
|
|||
#pragma once
|
||||
|
||||
#include "../../blk/blk.h"
|
||||
#include <stdint.h>
|
||||
|
||||
#define NQFS_MAX_FILENAME_SIZE (64)
|
||||
#define NQFS_STORAGE_BYTES_SECTOR (504)
|
||||
|
||||
struct NQFS_inode {
|
||||
uint8_t allocd;
|
||||
char filename[NQFS_MAX_FILENAME_SIZE];
|
||||
uint32_t start_sector;
|
||||
uint32_t size;
|
||||
char _[55];
|
||||
} __attribute__((packed));
|
||||
|
||||
struct NQFS_storage_block {
|
||||
uint32_t magic_number;
|
||||
char data[NQFS_STORAGE_BYTES_SECTOR];
|
||||
uint32_t next_sector;
|
||||
} __attribute__((packed));
|
||||
|
||||
uint32_t NQFS_get_next_free_inode(struct block_dev *device);
|
||||
uint32_t NQFS_create_file(struct block_dev *device, char *filename);
|
||||
|
||||
// Returns number of bytes read into char
|
||||
uint32_t NQFS_read_bytes(struct block_dev *device, uint32_t inode_sector,
|
||||
char *out, uint32_t max_size);
|
||||
uint32_t NQFS_write_bytes(struct block_dev *device, uint32_t inode_sector,
|
||||
char *in, uint32_t size);
|
||||
|
||||
void NQFS_DEBUG_list_files(struct block_dev *device);
|
|
@ -1,8 +1,6 @@
|
|||
#pragma once
|
||||
#include "./ps2.h"
|
||||
|
||||
#include "./scheduler.c"
|
||||
#include "./vga.c"
|
||||
#include <stdint.h>
|
||||
struct ps2_waiter_t ps2_waiters[MAX_PROCESSES];
|
||||
|
||||
enum key_code_t {
|
||||
backtick_tilde = 1,
|
||||
|
@ -244,24 +242,16 @@ char keycode_to_char(enum key_code_t key_code) {
|
|||
return '\0';
|
||||
}
|
||||
|
||||
|
||||
struct ps2_waiter_t {
|
||||
uint8_t alloc;
|
||||
uint32_t pid;
|
||||
};
|
||||
|
||||
struct ps2_waiter_t ps2_waiters[MAX_PROCESSES];
|
||||
|
||||
void init_ps2() {
|
||||
for(uint32_t i = 0; i < MAX_PROCESSES; i++) {
|
||||
for (uint32_t i = 0; i < MAX_PROCESSES; i++) {
|
||||
ps2_waiters[i].alloc = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void handle_keypress_char(char c) {
|
||||
if (c != '\0') {
|
||||
for(uint32_t i = 0; i < MAX_PROCESSES; i++) {
|
||||
if(ps2_waiters[i].alloc) {
|
||||
for (uint32_t i = 0; i < MAX_PROCESSES; i++) {
|
||||
if (ps2_waiters[i].alloc) {
|
||||
process_table[ps2_waiters[i].pid].registers.eax = c;
|
||||
ps2_waiters[i].alloc = 0;
|
||||
process_table[ps2_waiters[i].pid].state = TASKSTATE_ready;
|
16
kernel/drivers/ps2/ps2.h
Normal file
16
kernel/drivers/ps2/ps2.h
Normal file
|
@ -0,0 +1,16 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "../../scheduler/scheduler.h"
|
||||
|
||||
struct ps2_waiter_t {
|
||||
uint8_t alloc;
|
||||
uint32_t pid;
|
||||
};
|
||||
|
||||
extern struct ps2_waiter_t ps2_waiters[MAX_PROCESSES];
|
||||
|
||||
void init_ps2();
|
||||
void handle_keypress_char(char);
|
||||
void handle_keypress(uint8_t);
|
|
@ -1,36 +0,0 @@
|
|||
#pragma once
|
||||
#include "../../arch/i386/asm.c"
|
||||
|
||||
#define COM1 (0x3F8)
|
||||
|
||||
int serial_init() {
|
||||
outb(COM1 + 1, 0x01);
|
||||
outb(COM1 + 3, 0x80);
|
||||
outb(COM1 + 0, 0x03);
|
||||
outb(COM1 + 1, 0x00);
|
||||
outb(COM1 + 3, 0x03);
|
||||
outb(COM1 + 2, 0xC7);
|
||||
outb(COM1 + 4, 0x0B);
|
||||
outb(COM1 + 4, 0x0F);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int serial_has_tx() {
|
||||
return inb(COM1 + 5) & 0x20;
|
||||
}
|
||||
|
||||
int serial_has_rx() {
|
||||
return inb(COM1 + 5) & 1;
|
||||
}
|
||||
|
||||
void serial_tx(char a) {
|
||||
while (serial_has_tx() == 0);
|
||||
|
||||
outb(COM1,a);
|
||||
}
|
||||
|
||||
char serial_rx() {
|
||||
while (serial_has_rx() == 0);
|
||||
|
||||
return inb(COM1);
|
||||
}
|
36
kernel/drivers/serial/serial.c
Normal file
36
kernel/drivers/serial/serial.c
Normal file
|
@ -0,0 +1,36 @@
|
|||
#pragma once
|
||||
|
||||
#include "serial.h"
|
||||
#include "../../../arch/i386/asm/asm.h"
|
||||
|
||||
#define COM1 (0x3F8)
|
||||
|
||||
int serial_init() {
|
||||
outb(COM1 + 1, 0x01);
|
||||
outb(COM1 + 3, 0x80);
|
||||
outb(COM1 + 0, 0x03);
|
||||
outb(COM1 + 1, 0x00);
|
||||
outb(COM1 + 3, 0x03);
|
||||
outb(COM1 + 2, 0xC7);
|
||||
outb(COM1 + 4, 0x0B);
|
||||
outb(COM1 + 4, 0x0F);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int serial_has_tx() { return inb(COM1 + 5) & 0x20; }
|
||||
|
||||
int serial_has_rx() { return inb(COM1 + 5) & 1; }
|
||||
|
||||
void serial_tx(char a) {
|
||||
while (serial_has_tx() == 0)
|
||||
;
|
||||
|
||||
outb(COM1, a);
|
||||
}
|
||||
|
||||
char serial_rx() {
|
||||
while (serial_has_rx() == 0)
|
||||
;
|
||||
|
||||
return inb(COM1);
|
||||
}
|
5
kernel/drivers/serial/serial.h
Normal file
5
kernel/drivers/serial/serial.h
Normal file
|
@ -0,0 +1,5 @@
|
|||
#pragma once
|
||||
|
||||
int serial_init();
|
||||
void serial_tx(char);
|
||||
char serial_rx();
|
109
kernel/drivers/vga/vga.c
Normal file
109
kernel/drivers/vga/vga.c
Normal file
|
@ -0,0 +1,109 @@
|
|||
#pragma once
|
||||
|
||||
#include "vga.h"
|
||||
#include "../../memory/memory.h"
|
||||
#include <stdint.h>
|
||||
|
||||
#define WIDTH 80
|
||||
#define HEIGHT 25
|
||||
|
||||
static char vga_buf[HEIGHT * (WIDTH * 2)];
|
||||
|
||||
static uint8_t vgabuf_col = 0;
|
||||
static uint8_t vgabuf_row = 0;
|
||||
|
||||
static uint8_t vgabuf_start_row = 0;
|
||||
static uint8_t vgabuf_move_row = 0;
|
||||
|
||||
static uint8_t default_color_code = 10;
|
||||
static char *vram = (char *)0xb8000;
|
||||
|
||||
static inline int VGA_idx(int row, int col) {
|
||||
return (row * WIDTH * 2) + (col * 2);
|
||||
}
|
||||
|
||||
static inline void VGA_set(int row, int col, char c, int color_code) {
|
||||
vga_buf[VGA_idx(row, col)] = c;
|
||||
vga_buf[VGA_idx(row, col) + 1] = color_code;
|
||||
}
|
||||
|
||||
void VGA_flush() {
|
||||
int topwrite = ((HEIGHT - vgabuf_start_row) * WIDTH * 2);
|
||||
|
||||
// Fill the top of the display from the offsetted buffer
|
||||
memcpy(vga_buf + (vgabuf_start_row * WIDTH * 2), vram, topwrite);
|
||||
|
||||
// Fill the bottom of the display from the offsetted buffer
|
||||
memcpy(vga_buf, vram + topwrite, ((vgabuf_start_row)*WIDTH * 2));
|
||||
}
|
||||
|
||||
void VGA_clear_screen() {
|
||||
for (int r = 0; r < HEIGHT - 1; r++) {
|
||||
for (int c = 0; c < WIDTH; c++) {
|
||||
VGA_set(r, c, ' ', default_color_code);
|
||||
}
|
||||
}
|
||||
|
||||
vgabuf_start_row = 0;
|
||||
vgabuf_col = 0;
|
||||
vgabuf_row = 0;
|
||||
|
||||
VGA_flush();
|
||||
}
|
||||
|
||||
void VGA_clear_line() {
|
||||
for (int i = 0; i < WIDTH; ++i) {
|
||||
VGA_set(vgabuf_start_row, i, ' ', default_color_code);
|
||||
}
|
||||
}
|
||||
|
||||
void VGA_putc(char c) {
|
||||
if (vgabuf_col == WIDTH) {
|
||||
vgabuf_row = (vgabuf_row + 1) % HEIGHT;
|
||||
vgabuf_col = 0;
|
||||
|
||||
if (vgabuf_start_row > 0 || vgabuf_row == 0) {
|
||||
if (vgabuf_move_row == vgabuf_start_row) {
|
||||
vgabuf_start_row = (vgabuf_start_row + 1) % HEIGHT;
|
||||
vgabuf_move_row = vgabuf_start_row;
|
||||
} else {
|
||||
vgabuf_move_row++;
|
||||
}
|
||||
VGA_clear_line();
|
||||
}
|
||||
}
|
||||
|
||||
if (c == '\n') {
|
||||
for (int i = vgabuf_col; i < WIDTH; i++) {
|
||||
VGA_set(vgabuf_row, i, ' ', default_color_code);
|
||||
}
|
||||
vgabuf_row = (vgabuf_row + 1) % HEIGHT;
|
||||
vgabuf_col = 0;
|
||||
|
||||
if (vgabuf_start_row > 0 || vgabuf_row == 0) {
|
||||
if (vgabuf_move_row == vgabuf_start_row) {
|
||||
vgabuf_start_row = (vgabuf_start_row + 1) % HEIGHT;
|
||||
vgabuf_move_row = vgabuf_start_row;
|
||||
} else {
|
||||
vgabuf_move_row++;
|
||||
}
|
||||
VGA_clear_line();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (c == '\b') {
|
||||
if (vgabuf_col == 0) {
|
||||
vgabuf_col = WIDTH - 1;
|
||||
vgabuf_row--;
|
||||
vgabuf_move_row--;
|
||||
} else {
|
||||
vgabuf_col--;
|
||||
}
|
||||
// VGA_set(vgabuf_row, vgabuf_col, ' ', default_color_code);
|
||||
return;
|
||||
}
|
||||
|
||||
VGA_set(vgabuf_row, vgabuf_col, c, default_color_code);
|
||||
vgabuf_col++;
|
||||
}
|
5
kernel/drivers/vga/vga.h
Normal file
5
kernel/drivers/vga/vga.h
Normal file
|
@ -0,0 +1,5 @@
|
|||
#pragma once
|
||||
|
||||
void VGA_clear_screen();
|
||||
void VGA_putc(char);
|
||||
void VGA_flush();
|
|
@ -1,58 +1,12 @@
|
|||
#pragma once
|
||||
|
||||
#include "./spin_lock.c"
|
||||
#include "./drivers/serial.c"
|
||||
#include <stdarg.h>
|
||||
#include "io.h"
|
||||
#include "../drivers/serial/serial.h"
|
||||
#include "../drivers/vga/vga.h"
|
||||
#include <stdint.h>
|
||||
|
||||
#define WIDTH 80
|
||||
#define HEIGHT 25
|
||||
|
||||
static uint8_t col = 0;
|
||||
static uint8_t row = 0;
|
||||
static uint8_t color_code = 10;
|
||||
static char *vram = (char *)0xb8000;
|
||||
|
||||
void clear_screen() {
|
||||
for (int i = 0; i < HEIGHT - 1; i++) {
|
||||
for (int j = 0; j < WIDTH; j++) {
|
||||
vram[(i * WIDTH * 2) + (j * 2)] = 0;
|
||||
// vram[(i * WIDTH * 2) + (j*2 + 1)] = 0;
|
||||
}
|
||||
}
|
||||
row = 0;
|
||||
col = 0;
|
||||
}
|
||||
#include "../spin_lock.h"
|
||||
|
||||
void putc(char c) {
|
||||
if (col == WIDTH) {
|
||||
row = (row + 1) % HEIGHT;
|
||||
col = 0;
|
||||
}
|
||||
|
||||
if (c == '\n') {
|
||||
for (int i = col; i < WIDTH; i++) {
|
||||
vram[(row * WIDTH * 2) + (i * 2)] = ' ';
|
||||
vram[(row * WIDTH * 2) + (i * 2 + 1)] = color_code;
|
||||
}
|
||||
row = (row + 1) % HEIGHT;
|
||||
col = 0;
|
||||
serial_tx('\n');
|
||||
return;
|
||||
}
|
||||
|
||||
if (c == '\b') {
|
||||
col--;
|
||||
vram[(row * WIDTH * 2) + (col * 2)] = ' ';
|
||||
vram[(row * WIDTH * 2) + (col * 2 + 1)] = color_code;
|
||||
serial_tx('\b');
|
||||
return;
|
||||
}
|
||||
|
||||
vram[(row * WIDTH * 2) + (col * 2)] = c;
|
||||
vram[(row * WIDTH * 2) + (col * 2 + 1)] = color_code;
|
||||
col++;
|
||||
|
||||
VGA_putc(c);
|
||||
serial_tx(c);
|
||||
}
|
||||
|
||||
|
@ -150,6 +104,7 @@ void printf_base(char *str, va_list list) {
|
|||
putc(str[i]);
|
||||
}
|
||||
}
|
||||
VGA_flush();
|
||||
}
|
||||
|
||||
void printf_nolock(char *str, ...) {
|
7
kernel/io/io.h
Normal file
7
kernel/io/io.h
Normal file
|
@ -0,0 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
void putc(char);
|
||||
void printf(char *, ...);
|
||||
void printf_nolock(char *, ...);
|
|
@ -1,32 +1,48 @@
|
|||
#include "./drivers/serial.c"
|
||||
#include "./pci.c"
|
||||
#include "./rsdp.c"
|
||||
#include "./scheduler.c"
|
||||
#include "./vga.c"
|
||||
#pragma once
|
||||
|
||||
#include "./acpi/rsdp.h"
|
||||
#include "./drivers/serial/serial.h"
|
||||
#include "./drivers/vga/vga.h"
|
||||
#include "./io/io.h"
|
||||
#include "./pci/pci.h"
|
||||
#include "./scheduler/scheduler.h"
|
||||
#include <stdint.h>
|
||||
|
||||
#include "./test_processes.c"
|
||||
#include "../arch/i386/scheduler/scheduler.c"
|
||||
#include "../supp/test_processes.c"
|
||||
#include "./drivers/blk/ramblk/ramblk.h"
|
||||
#include "./drivers/fs/nqfs/nqfs.h"
|
||||
#include "./drivers/ps2/ps2.h"
|
||||
#include "drivers/blk/blk.h"
|
||||
|
||||
#ifdef ARCH_I386
|
||||
#include "../arch/i386/init.c"
|
||||
#endif
|
||||
|
||||
int kernel_main() {
|
||||
lock = 0;
|
||||
|
||||
outb(0x3D4, 0x0A);
|
||||
outb(0x3D5, 0x20);
|
||||
serial_init();
|
||||
|
||||
find_rsdp();
|
||||
pci_enumerate_devices();
|
||||
clear_screen();
|
||||
|
||||
VGA_clear_screen();
|
||||
interrupt_disable();
|
||||
|
||||
arch_init();
|
||||
|
||||
init_process_table();
|
||||
init_ps2();
|
||||
|
||||
// Init block device list
|
||||
BLK__init();
|
||||
|
||||
// Init block device drivers
|
||||
RAMBLK__init();
|
||||
|
||||
struct block_dev blk_devices[128];
|
||||
uint32_t blkdev_cnt = BLK__get_block_devices(blk_devices, 128);
|
||||
|
||||
for(uint32_t i = 0; i < blkdev_cnt; ++i) {
|
||||
printf("blk: %d: %s with capacity %d Bytes\n", blk_devices[i].device_no, blk_devices[i].name, (blk_devices[i].num_sectors * blk_devices[i].sector_size));
|
||||
}
|
||||
|
||||
start_process("razzle", (char *)&test_razzle);
|
||||
start_process("dazzle", (char *)&test_dazzle);
|
||||
|
@ -38,7 +54,7 @@ int kernel_main() {
|
|||
}
|
||||
|
||||
void fault_handler(struct regs *r) {
|
||||
clear_screen();
|
||||
VGA_clear_screen();
|
||||
printf("!!! Kernel Panic !!!\n");
|
||||
switch (r->int_no) {
|
||||
case 0: {
|
||||
|
|
|
@ -1,22 +1,4 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// Below doesn't work!
|
||||
// uint8_t streq(char *ptr, char* ptr2) {
|
||||
// while (1 == 1) {
|
||||
// if (*ptr != *ptr2) {
|
||||
// return 0;
|
||||
// }
|
||||
//
|
||||
// if (*ptr == '\0') {
|
||||
// return 1;
|
||||
// }
|
||||
//
|
||||
// ptr++;
|
||||
// ptr2++;
|
||||
// }
|
||||
//}
|
||||
#include "memory.h"
|
||||
|
||||
uint8_t memseq(char *ptr, char *ptr2, uint32_t len) {
|
||||
for (uint32_t i = 0; i < len; i++) {
|
9
kernel/memory/memory.h
Normal file
9
kernel/memory/memory.h
Normal file
|
@ -0,0 +1,9 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
uint8_t memseq(char *, char *, uint32_t len);
|
||||
uint8_t streq(char *, char *);
|
||||
void memset(char *, char, uint32_t);
|
||||
void memcpy(char *, char *, uint32_t);
|
||||
void strncpy(char *, char *, uint32_t);
|
|
@ -1,28 +1,14 @@
|
|||
#pragma once
|
||||
#include "./pci_supp.c"
|
||||
#include "vga.c"
|
||||
#include <stdint.h>
|
||||
#include "./pci.h"
|
||||
#include "../../supp/pci_supp.c"
|
||||
#include "../io/io.h"
|
||||
#include "../memory/memory.h"
|
||||
|
||||
#ifdef ARCH_I386
|
||||
#include "../arch/i386/asm.c"
|
||||
#include "../../arch/i386/asm/asm.h"
|
||||
#endif
|
||||
|
||||
#define PCI_NO_VENDOR (0xFFFF)
|
||||
#define PCI_MAX_NAMESIZE (128)
|
||||
#define PCI_MAX_DEVICES (256)
|
||||
|
||||
struct pci_device {
|
||||
uint16_t device_id;
|
||||
uint16_t vendor_id;
|
||||
char device_name[PCI_MAX_NAMESIZE];
|
||||
char vendor_name[PCI_MAX_NAMESIZE];
|
||||
uint32_t bar[6];
|
||||
uint8_t class_code;
|
||||
uint8_t subclass_code;
|
||||
};
|
||||
|
||||
static struct pci_device pci_devices_list[PCI_MAX_DEVICES];
|
||||
static uint32_t pci_devices_count;
|
||||
struct pci_device pci_devices_list[PCI_MAX_DEVICES];
|
||||
uint32_t pci_devices_count;
|
||||
|
||||
uint16_t pci_read_config(uint8_t bus, uint8_t slot, uint8_t function,
|
||||
uint8_t offset) {
|
22
kernel/pci/pci.h
Normal file
22
kernel/pci/pci.h
Normal file
|
@ -0,0 +1,22 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define PCI_NO_VENDOR (0xFFFF)
|
||||
#define PCI_MAX_NAMESIZE (128)
|
||||
#define PCI_MAX_DEVICES (256)
|
||||
|
||||
struct pci_device {
|
||||
uint16_t device_id;
|
||||
uint16_t vendor_id;
|
||||
char device_name[PCI_MAX_NAMESIZE];
|
||||
char vendor_name[PCI_MAX_NAMESIZE];
|
||||
uint32_t bar[6];
|
||||
uint8_t class_code;
|
||||
uint8_t subclass_code;
|
||||
};
|
||||
|
||||
extern struct pci_device pci_devices_list[PCI_MAX_DEVICES];
|
||||
extern uint32_t pci_devices_count;
|
||||
|
||||
void pci_enumerate_devices();
|
124888
kernel/pci_supp.c
124888
kernel/pci_supp.c
File diff suppressed because it is too large
Load diff
112
kernel/rsdp.c
112
kernel/rsdp.c
|
@ -1,112 +0,0 @@
|
|||
#pragma once
|
||||
#include <stdint.h>
|
||||
#include "memory.c"
|
||||
#include "vga.c"
|
||||
|
||||
struct rsdp_t {
|
||||
char signature[8];
|
||||
uint8_t checksum;
|
||||
char oem_id[6];
|
||||
uint8_t revision;
|
||||
uint32_t rsdt_address;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct xsdp_t {
|
||||
char signature[8];
|
||||
uint8_t checksum;
|
||||
char oem_id[6];
|
||||
uint8_t revision;
|
||||
uint32_t unused;
|
||||
uint32_t length;
|
||||
uint32_t xsdt_addr_hi;
|
||||
uint32_t xsdt_addr_lo;
|
||||
uint8_t checksum_ext;
|
||||
uint8_t unused_[3];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct acpi_header_t {
|
||||
char signature[4];
|
||||
uint32_t length;
|
||||
uint8_t revision;
|
||||
uint8_t checksum;
|
||||
char oem_id[6];
|
||||
char oem_table_id[8];
|
||||
uint32_t oem_revision;
|
||||
uint32_t creator_id;
|
||||
uint32_t creator_division;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct rsdt_t {
|
||||
struct acpi_header_t header;
|
||||
uint32_t pointer[64];
|
||||
};
|
||||
|
||||
uint8_t validate(struct rsdp_t *ptr) {
|
||||
char sig[] = "RSD PTR ";
|
||||
if (!memseq(ptr->signature, sig, 8)) return 0;
|
||||
|
||||
uint8_t *rsdp_bytes = (uint8_t *) ptr;
|
||||
uint8_t sum = 0;
|
||||
for(uint8_t i = 0; i < 20; i++) {
|
||||
sum += rsdp_bytes[i];
|
||||
}
|
||||
|
||||
if (sum == 0 && ptr->revision == 2) {
|
||||
printf_nolock("acpi: ACPI v2+ not yet supported :(\n");
|
||||
for(;;){}
|
||||
// TODO: test with ACPI 2 System
|
||||
struct xsdp_t *r2_ptr = (struct xsdp_t*) ptr;
|
||||
|
||||
uint8_t *xsdp_bytes = ((uint8_t *) r2_ptr) + 8;
|
||||
for(uint8_t i = 0; i < 16; i++) {
|
||||
sum += xsdp_bytes[i];
|
||||
}
|
||||
}
|
||||
|
||||
return sum == 0;
|
||||
}
|
||||
|
||||
char* find_table(struct rsdt_t* table, char* sig) {
|
||||
uint32_t entries = (table->header.length - sizeof table->header) / 4;
|
||||
for (uint32_t i = 0; i < entries; i++) {
|
||||
struct acpi_header_t* entry = (struct acpi_header_t*) table->pointer[i];
|
||||
if (memseq(entry->signature, sig, 4)) {
|
||||
printf_nolock("Found %s / %s\n", entry->oem_id, entry->signature);
|
||||
printf_nolock("Signature: %s\n", entry->signature);
|
||||
printf_nolock("Length : %d\n", entry->length);
|
||||
printf_nolock("Oem ID : %s\n", entry->oem_id);
|
||||
printf_nolock("Checksum : %d\n", entry->checksum);
|
||||
return (void*)entry;
|
||||
}
|
||||
}
|
||||
|
||||
printf_nolock("Not Found");
|
||||
return 0;
|
||||
}
|
||||
|
||||
void find_rsdp() {
|
||||
struct rsdp_t *ptr;
|
||||
|
||||
volatile uint8_t found = 0;
|
||||
for (uint32_t addr = 0x00000000; addr <= 0x000FFFFF; addr++) {
|
||||
ptr = (struct rsdp_t *) addr;
|
||||
|
||||
if (validate(ptr)) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
uint8_t* ebda = (uint8_t*)(*((uint16_t*)0x40e) << 4);
|
||||
for (uint32_t i = 0; i <= 1024; i += 16) {
|
||||
ptr = (struct rsdp_t*) ebda;
|
||||
if (validate(ptr)) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
printf_nolock("acpi: RSDP Found [OEM: %s, SIG: %s]\n", ptr->oem_id, ptr->signature);
|
||||
}
|
|
@ -1,29 +1,13 @@
|
|||
#pragma once
|
||||
#include "scheduler.h"
|
||||
#include "../io/io.h"
|
||||
#include "../memory/memory.h"
|
||||
|
||||
#ifdef ARCH_I386
|
||||
#include "../arch/i386/scheduler.c"
|
||||
#include "../../arch/i386/scheduler/scheduler.h"
|
||||
#endif
|
||||
|
||||
#include "./memory.c"
|
||||
#include "./vga.c"
|
||||
#include <stdint.h>
|
||||
|
||||
#define ADDRESS_SPACE_SIZE 1000000
|
||||
#define MAX_PROCESSES 128
|
||||
|
||||
enum task_state_t { TASKSTATE_unused, TASKSTATE_ready, TASKSTATE_blocked };
|
||||
|
||||
struct task_struct {
|
||||
uint32_t pid;
|
||||
enum task_state_t state;
|
||||
struct regs registers;
|
||||
unsigned int address_base;
|
||||
char *allocd_addr;
|
||||
char *process_name;
|
||||
};
|
||||
|
||||
static struct task_struct process_table[MAX_PROCESSES];
|
||||
static uint32_t current_pid;
|
||||
struct task_struct process_table[MAX_PROCESSES];
|
||||
uint32_t current_pid;
|
||||
|
||||
void init_process_table() {
|
||||
for (uint32_t i = 0; i < MAX_PROCESSES; i++) {
|
29
kernel/scheduler/scheduler.h
Normal file
29
kernel/scheduler/scheduler.h
Normal file
|
@ -0,0 +1,29 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef ARCH_I386
|
||||
#include "../../arch/i386/scheduler/scheduler.h"
|
||||
#endif
|
||||
|
||||
#define ADDRESS_SPACE_SIZE 1000000
|
||||
#define MAX_PROCESSES 128
|
||||
|
||||
enum task_state_t { TASKSTATE_unused, TASKSTATE_ready, TASKSTATE_blocked };
|
||||
|
||||
struct task_struct {
|
||||
uint32_t pid;
|
||||
enum task_state_t state;
|
||||
struct regs registers;
|
||||
unsigned int address_base;
|
||||
char *allocd_addr;
|
||||
char *process_name;
|
||||
};
|
||||
|
||||
extern struct task_struct process_table[MAX_PROCESSES];
|
||||
extern uint32_t current_pid;
|
||||
|
||||
void init_process_table();
|
||||
void start_process(char *, char *);
|
||||
void process_debug();
|
||||
void schedule(struct regs *);
|
|
@ -1,9 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#ifdef ARCH_I386
|
||||
#include "../arch/i386/asm.c"
|
||||
#endif
|
||||
|
||||
void sl_acquire(uint32_t *lock) { __sl_acquire(lock); }
|
||||
|
||||
void sl_release(uint32_t *lock) { __sl_release(lock); }
|
9
kernel/spin_lock.h
Normal file
9
kernel/spin_lock.h
Normal file
|
@ -0,0 +1,9 @@
|
|||
#pragma once
|
||||
|
||||
#ifdef ARCH_I386
|
||||
#include "../arch/i386/asm/asm.h"
|
||||
#endif
|
||||
|
||||
static inline void sl_acquire(uint32_t *lock) { __sl_acquire(lock); }
|
||||
|
||||
static inline void sl_release(uint32_t *lock) { __sl_release(lock); }
|
145
kernel/syscall.c
145
kernel/syscall.c
|
@ -1,145 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include "scheduler.c"
|
||||
#include "ps2.c"
|
||||
#include "pci.c"
|
||||
#include "vga.c"
|
||||
|
||||
#ifdef ARCH_I386
|
||||
#include "../arch/i386/syscall.c"
|
||||
#endif
|
||||
|
||||
enum syscall_type_d { SYSCALL_yield, SYSCALL_getc, SYSCALL_exit, SYSCALL_lspci, SYSCALL_lsproc };
|
||||
|
||||
void yield() { INVOKE_SYSCALL(SYSCALL_yield); }
|
||||
char getc() {
|
||||
INVOKE_SYSCALL(SYSCALL_getc);
|
||||
|
||||
char result;
|
||||
__asm__ volatile (
|
||||
"movb %%al, %0"
|
||||
: "=r"(result)
|
||||
);
|
||||
|
||||
return result;
|
||||
}
|
||||
uint32_t lspci(struct pci_device* devlist, uint32_t len) {
|
||||
int result = 0;
|
||||
__asm__ volatile (
|
||||
"movl %0, %%ebx"
|
||||
: : "r"((uint32_t) devlist) : "%ebx"
|
||||
);
|
||||
|
||||
__asm__ volatile (
|
||||
"movl %0, %%ecx"
|
||||
: : "r"(len) : "%ecx"
|
||||
);
|
||||
|
||||
|
||||
INVOKE_SYSCALL(SYSCALL_lspci);
|
||||
|
||||
__asm__ volatile (
|
||||
"movl %%eax, %k0"
|
||||
: "=r"(result)
|
||||
);
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
uint32_t lsproc(struct task_struct* proclist, uint32_t len) {
|
||||
int result = 0;
|
||||
__asm__ volatile (
|
||||
"movl %0, %%ebx"
|
||||
: : "r"((uint32_t) proclist) : "%ebx"
|
||||
);
|
||||
|
||||
__asm__ volatile (
|
||||
"movl %0, %%ecx"
|
||||
: : "r"(len) : "%ecx"
|
||||
);
|
||||
|
||||
|
||||
INVOKE_SYSCALL(SYSCALL_lsproc);
|
||||
|
||||
__asm__ volatile (
|
||||
"movl %%eax, %k0"
|
||||
: "=r"(result)
|
||||
);
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void __syscall_yield(struct regs *r) {
|
||||
// for now, just reschedule
|
||||
// TODO: reset PIT timer so
|
||||
// next process doesn't get an
|
||||
// unreasonably small quantum
|
||||
|
||||
schedule(r);
|
||||
}
|
||||
|
||||
void syscall(struct regs *r) {
|
||||
int syscall_no = r->eax;
|
||||
|
||||
switch (syscall_no) {
|
||||
|
||||
case SYSCALL_yield: {
|
||||
__syscall_yield(r);
|
||||
break;
|
||||
};
|
||||
|
||||
case SYSCALL_getc: {
|
||||
process_table[current_pid].state = TASKSTATE_blocked;
|
||||
|
||||
for(uint32_t i = 0; i < MAX_PROCESSES; i++) {
|
||||
if(!ps2_waiters[i].alloc) {
|
||||
ps2_waiters[i].alloc = 1;
|
||||
ps2_waiters[i].pid = current_pid;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
__syscall_yield(r);
|
||||
break;
|
||||
};
|
||||
|
||||
case SYSCALL_lspci: {
|
||||
uint32_t len = r->ecx;
|
||||
len = len < pci_devices_count ? len : pci_devices_count;
|
||||
struct pci_device* devlist = (struct pci_device*) r->ebx;
|
||||
|
||||
for (uint32_t i = 0; i < len; ++i) {
|
||||
devlist[i] = pci_devices_list[i];
|
||||
}
|
||||
|
||||
r->eax = len;
|
||||
|
||||
break;
|
||||
};
|
||||
|
||||
case SYSCALL_lsproc: {
|
||||
uint32_t len = r->ecx;
|
||||
struct task_struct*proclist = (struct task_struct*) r->ebx;
|
||||
|
||||
uint32_t i = 0, j = 0;
|
||||
for (; i < len; ++i, ++j) {
|
||||
for(; j < MAX_PROCESSES && process_table[j].state == TASKSTATE_unused; ++j) {}
|
||||
if (j == MAX_PROCESSES) break;
|
||||
|
||||
proclist[i] = process_table[j];
|
||||
}
|
||||
|
||||
r->eax = i;
|
||||
|
||||
break;
|
||||
};
|
||||
|
||||
case SYSCALL_exit: {
|
||||
process_table[current_pid].state = TASKSTATE_unused;
|
||||
__syscall_yield(r);
|
||||
break;
|
||||
};
|
||||
}
|
||||
}
|
149
kernel/syscall/syscall.c
Normal file
149
kernel/syscall/syscall.c
Normal file
|
@ -0,0 +1,149 @@
|
|||
#include "./syscall.h"
|
||||
#include "../drivers/ps2/ps2.h"
|
||||
#include "../io/io.h"
|
||||
#include "../pci/pci.h"
|
||||
#include "../scheduler/scheduler.h"
|
||||
|
||||
#ifdef ARCH_I386
|
||||
#include "../../arch/i386/syscall.h"
|
||||
#endif
|
||||
|
||||
enum syscall_type_d {
|
||||
SYSCALL_yield,
|
||||
SYSCALL_getc,
|
||||
SYSCALL_exit,
|
||||
SYSCALL_lspci,
|
||||
SYSCALL_lsproc,
|
||||
SYSCALL_powerctl
|
||||
};
|
||||
|
||||
void powerctl(uint32_t power_mode) {
|
||||
// TODO: Add reboot mode when ACPI is done
|
||||
INVOKE_SYSCALL(SYSCALL_powerctl);
|
||||
}
|
||||
|
||||
void yield() { INVOKE_SYSCALL(SYSCALL_yield); }
|
||||
char getc() {
|
||||
INVOKE_SYSCALL(SYSCALL_getc);
|
||||
|
||||
char result;
|
||||
__asm__ volatile("movb %%al, %0" : "=r"(result));
|
||||
|
||||
return result;
|
||||
}
|
||||
uint32_t lspci(struct pci_device *devlist, uint32_t len) {
|
||||
int result = 0;
|
||||
__asm__ volatile("movl %0, %%ebx" : : "r"((uint32_t)devlist) : "%ebx");
|
||||
|
||||
__asm__ volatile("movl %0, %%ecx" : : "r"(len) : "%ecx");
|
||||
|
||||
INVOKE_SYSCALL(SYSCALL_lspci);
|
||||
|
||||
__asm__ volatile("movl %%eax, %k0" : "=r"(result));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
uint32_t lsproc(struct task_struct *proclist, uint32_t len) {
|
||||
int result = 0;
|
||||
__asm__ volatile("movl %0, %%ebx" : : "r"((uint32_t)proclist) : "%ebx");
|
||||
|
||||
__asm__ volatile("movl %0, %%ecx" : : "r"(len) : "%ecx");
|
||||
|
||||
INVOKE_SYSCALL(SYSCALL_lsproc);
|
||||
|
||||
__asm__ volatile("movl %%eax, %k0" : "=r"(result));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void __syscall_powerctl() {
|
||||
// TODO: Implement properly
|
||||
printf_nolock("Attempting shutdown using hypervisor-specific methods.");
|
||||
printf_nolock("ACPI is not yet supported.");
|
||||
outw(0x604, 0x2000);
|
||||
outw(0x4004, 0x3400);
|
||||
outw(0x600, 0x34);
|
||||
outw(0xB004, 0x2000);
|
||||
}
|
||||
|
||||
void __syscall_yield(struct regs *r) {
|
||||
// for now, just reschedule
|
||||
// TODO: reset PIT timer so
|
||||
// next process doesn't get an
|
||||
// unreasonably small quantum
|
||||
|
||||
schedule(r);
|
||||
}
|
||||
|
||||
void syscall(struct regs *r) {
|
||||
int syscall_no = r->eax;
|
||||
|
||||
switch (syscall_no) {
|
||||
|
||||
case SYSCALL_powerctl: {
|
||||
__syscall_powerctl();
|
||||
break;
|
||||
};
|
||||
|
||||
case SYSCALL_yield: {
|
||||
__syscall_yield(r);
|
||||
break;
|
||||
};
|
||||
|
||||
case SYSCALL_getc: {
|
||||
process_table[current_pid].state = TASKSTATE_blocked;
|
||||
|
||||
for (uint32_t i = 0; i < MAX_PROCESSES; i++) {
|
||||
if (!ps2_waiters[i].alloc) {
|
||||
ps2_waiters[i].alloc = 1;
|
||||
ps2_waiters[i].pid = current_pid;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
__syscall_yield(r);
|
||||
break;
|
||||
};
|
||||
|
||||
case SYSCALL_lspci: {
|
||||
uint32_t len = r->ecx;
|
||||
len = len < pci_devices_count ? len : pci_devices_count;
|
||||
struct pci_device *devlist = (struct pci_device *)r->ebx;
|
||||
|
||||
for (uint32_t i = 0; i < len; ++i) {
|
||||
devlist[i] = pci_devices_list[i];
|
||||
}
|
||||
|
||||
r->eax = len;
|
||||
|
||||
break;
|
||||
};
|
||||
|
||||
case SYSCALL_lsproc: {
|
||||
uint32_t len = r->ecx;
|
||||
struct task_struct *proclist = (struct task_struct *)r->ebx;
|
||||
|
||||
uint32_t i = 0, j = 0;
|
||||
for (; i < len; ++i, ++j) {
|
||||
for (; j < MAX_PROCESSES && process_table[j].state == TASKSTATE_unused;
|
||||
++j) {
|
||||
}
|
||||
if (j == MAX_PROCESSES)
|
||||
break;
|
||||
|
||||
proclist[i] = process_table[j];
|
||||
}
|
||||
|
||||
r->eax = i;
|
||||
|
||||
break;
|
||||
};
|
||||
|
||||
case SYSCALL_exit: {
|
||||
process_table[current_pid].state = TASKSTATE_unused;
|
||||
__syscall_yield(r);
|
||||
break;
|
||||
};
|
||||
}
|
||||
}
|
12
kernel/syscall/syscall.h
Normal file
12
kernel/syscall/syscall.h
Normal file
|
@ -0,0 +1,12 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define POWERCTL_shutdown (0)
|
||||
#define POWERCTL_reboot (1)
|
||||
|
||||
void powerctl(uint32_t);
|
||||
char getc();
|
||||
uint32_t lspci();
|
||||
uint32_t lsproc();
|
||||
void yield();
|
|
@ -1,133 +0,0 @@
|
|||
/*
|
||||
* Since RAZZLE doesn't have disk support yet, all code for test processes are
|
||||
* included in this file.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "./scheduler.c"
|
||||
#include "./spin_lock.c"
|
||||
#include "./syscall.c"
|
||||
#include "./scheduler.c"
|
||||
|
||||
uint32_t lock2 = 0;
|
||||
|
||||
uint32_t counter;
|
||||
|
||||
void test_razzle() {
|
||||
sl_acquire(&lock2);
|
||||
counter = 0;
|
||||
sl_release(&lock2);
|
||||
for (;;) {
|
||||
sl_acquire(&lock2);
|
||||
counter++;
|
||||
//row = 1;
|
||||
//col = 0;
|
||||
//printf("%s (pid %d): %u \n", process_table[current_pid].process_name,
|
||||
// current_pid, i);
|
||||
sl_release(&lock2);
|
||||
yield();
|
||||
}
|
||||
}
|
||||
|
||||
void sh_cpuid() {
|
||||
char model[13];
|
||||
uint32_t res[3];
|
||||
__asm__ volatile ("mov $0, %%eax; cpuid; mov %%ebx, %0; mov %%edx, %1; mov %%ecx, %2;" : "=r" (res[0]), "=r" (res[1]), "=r" (res[2]) ::"ebx", "ecx", "edx");
|
||||
for(uint32_t i = 0; i < 3; i++) {
|
||||
model[(i*4) + 0] = (res[i] >> 0) & 0xFF;
|
||||
model[(i*4) + 1] = (res[i] >> 8) & 0xFF;
|
||||
model[(i*4) + 2] = (res[i] >> 16) & 0xFF;
|
||||
model[(i*4) + 3] = (res[i] >> 24) & 0xFF;
|
||||
}
|
||||
model[12] = '\0';
|
||||
printf("%s\n", model);
|
||||
}
|
||||
|
||||
void sh_lspci() {
|
||||
struct pci_device devlist[7];
|
||||
int devices = lspci(&devlist[0], 7);
|
||||
for(int j = 0; j < devices; ++j) {
|
||||
printf("%s %s (%d %d)\n", devlist[j].vendor_name, devlist[j].device_name, devlist[j].class_code, devlist[j].subclass_code);
|
||||
printf("Device ID: %x\n", devlist[j].device_id);
|
||||
printf("Vendor ID: %x\n", devlist[j].vendor_id);
|
||||
printf("Bar 5 : %x %u\n\n", devlist[j].bar[5], devlist[j].bar[5]);
|
||||
}
|
||||
}
|
||||
|
||||
void sh_lsproc() {
|
||||
struct task_struct proclist[7];
|
||||
int procs = lsproc(&proclist[0], 7);
|
||||
for(int j = 0; j < procs; ++j) {
|
||||
switch (proclist[j].state) {
|
||||
case TASKSTATE_ready:
|
||||
printf("R");
|
||||
break;
|
||||
case TASKSTATE_blocked:
|
||||
printf("B");
|
||||
break;
|
||||
default:
|
||||
printf("?");
|
||||
break;
|
||||
}
|
||||
printf(" %d: %s", proclist[j].pid, proclist[j].process_name);
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
void test_dazzle() {
|
||||
char prompt[] = "you@razzle ~$ ";
|
||||
char command[2048];
|
||||
|
||||
printf("%s", prompt);
|
||||
uint32_t i = 0;
|
||||
|
||||
for (;;) {
|
||||
char c = getc();
|
||||
sl_acquire(&lock2);
|
||||
|
||||
switch(c) {
|
||||
case '\b':
|
||||
command[i--] = '\0';
|
||||
printf("\b \b");
|
||||
break;
|
||||
|
||||
case '\n':
|
||||
command[i] = '\0';
|
||||
i = 0;
|
||||
|
||||
printf("\n");
|
||||
|
||||
if (streq(command, "lspci")) {
|
||||
sh_lspci();
|
||||
} else if (streq(command, "cpuid")) {
|
||||
sh_cpuid();
|
||||
} else if (streq(command, "help")) {
|
||||
printf("dazzle, the shell for RAZZLE\n");
|
||||
printf("--------------------------------------------------------\n");
|
||||
printf("help : print this menu\n");
|
||||
printf("cpuid : print CPU vendor id string\n");
|
||||
printf("lspci : print list of PCI devices\n");
|
||||
printf("lsproc : print list of running processes\n");
|
||||
printf("counter : print counter maintained by background process\n");
|
||||
} else if (streq(command, "counter")) {
|
||||
printf("%d\n", counter);
|
||||
} else if (streq(command, "lsproc")) {
|
||||
sh_lsproc();
|
||||
} else {
|
||||
printf("Unknown command\n");
|
||||
}
|
||||
|
||||
printf("%s", prompt);
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("%c", c);
|
||||
command[i++] = c;
|
||||
break;
|
||||
}
|
||||
|
||||
sl_release(&lock2);
|
||||
yield();
|
||||
}
|
||||
}
|
124887
supp/pci_supp.c
Normal file
124887
supp/pci_supp.c
Normal file
File diff suppressed because it is too large
Load diff
145
supp/test_processes.c
Normal file
145
supp/test_processes.c
Normal file
|
@ -0,0 +1,145 @@
|
|||
/*
|
||||
* Since RAZZLE doesn't have disk support yet, all code for test processes are
|
||||
* included in this file.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../kernel/io/io.h"
|
||||
#include "../kernel/memory/memory.h"
|
||||
#include "../kernel/pci/pci.h"
|
||||
#include "../kernel/scheduler/scheduler.h"
|
||||
#include "../kernel/spin_lock.h"
|
||||
#include "../kernel/syscall/syscall.h"
|
||||
|
||||
uint32_t lock2 = 0;
|
||||
|
||||
uint32_t counter;
|
||||
|
||||
void test_razzle() {
|
||||
sl_acquire(&lock2);
|
||||
counter = 0;
|
||||
sl_release(&lock2);
|
||||
for (;;) {
|
||||
sl_acquire(&lock2);
|
||||
counter++;
|
||||
// row = 1;
|
||||
// col = 0;
|
||||
// printf("%s (pid %d): %u \n", process_table[current_pid].process_name,
|
||||
// current_pid, i);
|
||||
sl_release(&lock2);
|
||||
yield();
|
||||
}
|
||||
}
|
||||
|
||||
void sh_cpuid() {
|
||||
char model[13];
|
||||
uint32_t res[3];
|
||||
__asm__ volatile(
|
||||
"mov $0, %%eax; cpuid; mov %%ebx, %0; mov %%edx, %1; mov %%ecx, %2;"
|
||||
: "=r"(res[0]), "=r"(res[1]), "=r"(res[2])::"ebx", "ecx", "edx");
|
||||
for (uint32_t i = 0; i < 3; i++) {
|
||||
model[(i * 4) + 0] = (res[i] >> 0) & 0xFF;
|
||||
model[(i * 4) + 1] = (res[i] >> 8) & 0xFF;
|
||||
model[(i * 4) + 2] = (res[i] >> 16) & 0xFF;
|
||||
model[(i * 4) + 3] = (res[i] >> 24) & 0xFF;
|
||||
}
|
||||
model[12] = '\0';
|
||||
printf("%s\n", model);
|
||||
}
|
||||
|
||||
void sh_lspci() {
|
||||
struct pci_device devlist[7];
|
||||
int devices = lspci(&devlist[0], 7);
|
||||
for (int j = 0; j < devices; ++j) {
|
||||
printf("%s %s (%d %d)\n", devlist[j].vendor_name, devlist[j].device_name,
|
||||
devlist[j].class_code, devlist[j].subclass_code);
|
||||
printf("Device ID: %x\n", devlist[j].device_id);
|
||||
printf("Vendor ID: %x\n", devlist[j].vendor_id);
|
||||
printf("Bar 5 : %x %u\n\n", devlist[j].bar[5], devlist[j].bar[5]);
|
||||
}
|
||||
}
|
||||
|
||||
void sh_lsproc() {
|
||||
struct task_struct proclist[7];
|
||||
int procs = lsproc(&proclist[0], 7);
|
||||
for (int j = 0; j < procs; ++j) {
|
||||
switch (proclist[j].state) {
|
||||
case TASKSTATE_ready:
|
||||
printf("R");
|
||||
break;
|
||||
case TASKSTATE_blocked:
|
||||
printf("B");
|
||||
break;
|
||||
default:
|
||||
printf("?");
|
||||
break;
|
||||
}
|
||||
printf(" %d: %s", proclist[j].pid, proclist[j].process_name);
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
void test_dazzle() {
|
||||
char prompt[] = "you@razzle ~$ ";
|
||||
char command[2048];
|
||||
|
||||
printf("%s", prompt);
|
||||
uint32_t i = 0;
|
||||
|
||||
for (;;) {
|
||||
char c = getc();
|
||||
sl_acquire(&lock2);
|
||||
|
||||
switch (c) {
|
||||
case '\b':
|
||||
if (i == 0)
|
||||
break;
|
||||
command[i--] = '\0';
|
||||
printf("\b \b");
|
||||
break;
|
||||
|
||||
case '\n':
|
||||
command[i] = '\0';
|
||||
i = 0;
|
||||
|
||||
printf("\n");
|
||||
|
||||
if (streq(command, "lspci")) {
|
||||
sh_lspci();
|
||||
} else if (streq(command, "cpuid")) {
|
||||
sh_cpuid();
|
||||
} else if (streq(command, "help")) {
|
||||
printf("dazzle, the shell for RAZZLE\n");
|
||||
printf("--------------------------------------------------------\n");
|
||||
printf("help : print this menu\n");
|
||||
printf("cpuid : print CPU vendor id string\n");
|
||||
printf("lspci : print list of PCI devices\n");
|
||||
printf("lsproc : print list of running processes\n");
|
||||
printf("counter : print counter maintained by background process\n");
|
||||
printf("shutdown: shuts down the VM using VM-specific methods\n");
|
||||
} else if (streq(command, "counter")) {
|
||||
printf("%d\n", counter);
|
||||
} else if (streq(command, "lsproc")) {
|
||||
sh_lsproc();
|
||||
} else if (streq(command, "shutdown")) {
|
||||
powerctl(POWERCTL_shutdown);
|
||||
printf("If the computer is still on, you must manually power it off. "
|
||||
"ACPI is not yet implemented.\n");
|
||||
} else {
|
||||
printf("Unknown command\n");
|
||||
}
|
||||
|
||||
printf("%s", prompt);
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("%c", c);
|
||||
command[i++] = c;
|
||||
break;
|
||||
}
|
||||
|
||||
sl_release(&lock2);
|
||||
yield();
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue