Merge branch 'hardware-deploy'
This commit is contained in:
commit
ee4d584790
7 changed files with 203 additions and 20 deletions
1
Makefile
1
Makefile
|
|
@ -9,6 +9,7 @@ CFLAGS += -ggdb
|
||||||
# preferentially in alphabetical order.
|
# preferentially in alphabetical order.
|
||||||
KERNEL_SOURCES_x86_64 := \
|
KERNEL_SOURCES_x86_64 := \
|
||||||
src/x86_64/apic.c \
|
src/x86_64/apic.c \
|
||||||
|
src/x86_64/loadcs.S \
|
||||||
src/x86_64/uart.c \
|
src/x86_64/uart.c \
|
||||||
src/x86_64/mem.c \
|
src/x86_64/mem.c \
|
||||||
src/x86_64/asm.c \
|
src/x86_64/asm.c \
|
||||||
|
|
|
||||||
34
bochsrc
Normal file
34
bochsrc
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
cpu: count=1, reset_on_triple_fault=1
|
||||||
|
cpuid: x86_64=1, mmx=1, sep=1, simd=sse4_2, apic=xapic, aes=1, movbe=1, xsave=1
|
||||||
|
cpuid: family=6, model=0x1a, stepping=5
|
||||||
|
|
||||||
|
memory: guest=512, host=256
|
||||||
|
|
||||||
|
romimage: file=$BXSHARE/BIOS-bochs-latest, options=fastboot
|
||||||
|
|
||||||
|
vgaromimage: file=$BXSHARE/VGABIOS-lgpl-latest
|
||||||
|
|
||||||
|
mouse: enabled=0
|
||||||
|
|
||||||
|
pci: enabled=1, chipset=i440fx
|
||||||
|
|
||||||
|
ata0: enabled=1, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14
|
||||||
|
ata1: enabled=1, ioaddr1=0x170, ioaddr2=0x370, irq=15
|
||||||
|
ata2: enabled=0, ioaddr1=0x1e8, ioaddr2=0x3e0, irq=11
|
||||||
|
ata3: enabled=0, ioaddr1=0x168, ioaddr2=0x360, irq=9
|
||||||
|
|
||||||
|
# hard-coded 16MB disk size
|
||||||
|
ata0-master: type=disk, mode=flat, path="build/disk.img", cylinders=64, heads=16, spt=32
|
||||||
|
|
||||||
|
boot: disk
|
||||||
|
|
||||||
|
panic: action=ask
|
||||||
|
error: action=report
|
||||||
|
info: action=report
|
||||||
|
debug: action=ignore, pci=report # report BX_DEBUG from module 'pci'
|
||||||
|
|
||||||
|
debugger_log: -
|
||||||
|
|
||||||
|
com1: enabled=1, mode=socket-server, dev=localhost:1111
|
||||||
|
port_e9_hack: enabled=1
|
||||||
|
|
||||||
|
|
@ -3,6 +3,6 @@
|
||||||
"initrd": { "type": "tar", "directory": "build/boot" },
|
"initrd": { "type": "tar", "directory": "build/boot" },
|
||||||
"config": "bootboot.cfg",
|
"config": "bootboot.cfg",
|
||||||
"partitions": [
|
"partitions": [
|
||||||
{ "type": "fat16", "size": 16 }
|
{ "type": "boot", "size": 16 }
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
127
src/kernel.c
127
src/kernel.c
|
|
@ -28,6 +28,7 @@
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <cpuid.h>
|
||||||
|
|
||||||
#include "x86_64/apic.h"
|
#include "x86_64/apic.h"
|
||||||
#include "x86_64/mem.h"
|
#include "x86_64/mem.h"
|
||||||
|
|
@ -71,11 +72,25 @@ void check_initrd() {
|
||||||
putln();
|
putln();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void console_init(void);
|
||||||
|
|
||||||
/******************************************
|
/******************************************
|
||||||
* Entry point, called by BOOTBOOT Loader *
|
* Entry point, called by BOOTBOOT Loader *
|
||||||
******************************************/
|
******************************************/
|
||||||
void _start() {
|
void _start() {
|
||||||
/*** NOTE: this code runs on all cores in parallel ***/
|
/*** NOTE: this code runs on all cores in parallel ***/
|
||||||
|
|
||||||
|
unsigned info[4];
|
||||||
|
__get_cpuid(0x1, &info[0], &info[1], &info[2], &info[3]);
|
||||||
|
unsigned procid = info[1] >> 24;
|
||||||
|
if (procid != bootboot.bspid) {
|
||||||
|
while (1) {
|
||||||
|
__asm__ ("hlt");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console_init();
|
||||||
|
|
||||||
int x, y, s = bootboot.fb_scanline, w = bootboot.fb_width, h = bootboot.fb_height;
|
int x, y, s = bootboot.fb_scanline, w = bootboot.fb_width, h = bootboot.fb_height;
|
||||||
|
|
||||||
if (s) {
|
if (s) {
|
||||||
|
|
@ -125,11 +140,19 @@ void _start() {
|
||||||
}
|
}
|
||||||
putln();
|
putln();
|
||||||
|
|
||||||
// hang for now
|
#if 0
|
||||||
|
for (int l = 0; l < 100; l++) {
|
||||||
|
for (int i = 0; i < 300; i++) {
|
||||||
|
printf("line %d ", l);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
__asm__("sti");
|
__asm__("sti");
|
||||||
lapic_set_timer();
|
lapic_set_timer();
|
||||||
|
|
||||||
|
// hang for now
|
||||||
PANIC("end of kernel");
|
PANIC("end of kernel");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -149,3 +172,105 @@ typedef struct {
|
||||||
} __attribute__((packed)) psf2_t;
|
} __attribute__((packed)) psf2_t;
|
||||||
|
|
||||||
extern volatile unsigned char _binary_font_psf_start;
|
extern volatile unsigned char _binary_font_psf_start;
|
||||||
|
|
||||||
|
uint32_t console_output[200 * 100];
|
||||||
|
int console_max_rows;
|
||||||
|
int console_max_cols;
|
||||||
|
|
||||||
|
int text_cursor_x;
|
||||||
|
int text_cursor_y;
|
||||||
|
|
||||||
|
static unsigned char *font_get_glyph(char c)
|
||||||
|
{
|
||||||
|
psf2_t *font = (psf2_t*)&_binary_font_psf_start;
|
||||||
|
unsigned char *glyphArray = (unsigned char *)&_binary_font_psf_start + font->headersize;
|
||||||
|
|
||||||
|
if (c == 0) return NULL;
|
||||||
|
if (c >= font->numglyph) return NULL;
|
||||||
|
|
||||||
|
return glyphArray + c * font->bytesperglyph;
|
||||||
|
}
|
||||||
|
|
||||||
|
void console_init(void)
|
||||||
|
{
|
||||||
|
psf2_t *font = (psf2_t*)&_binary_font_psf_start;
|
||||||
|
console_max_cols = bootboot.fb_width / (font->width+1);
|
||||||
|
if (console_max_cols > 200) console_max_cols = 200;
|
||||||
|
console_max_rows = bootboot.fb_height / (font->height+1);
|
||||||
|
if (console_max_rows > 100) console_max_rows = 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
void console_draw(int col, int row)
|
||||||
|
{
|
||||||
|
psf2_t *font = (psf2_t*)&_binary_font_psf_start;
|
||||||
|
int line, mask, offs;
|
||||||
|
int bpl = (font->width + 7)/8;
|
||||||
|
|
||||||
|
int cx = col * (font->width + 1);
|
||||||
|
int cy = row * (font->height + 1);
|
||||||
|
|
||||||
|
uint32_t chr = console_output[col + row * console_max_cols];
|
||||||
|
if (chr == 0) chr = ' ';
|
||||||
|
|
||||||
|
unsigned char *glyph = font_get_glyph(chr);
|
||||||
|
|
||||||
|
offs = 4 * cx + cy * bootboot.fb_scanline;
|
||||||
|
|
||||||
|
for (int y = 0; y < font->height; y++) {
|
||||||
|
line = offs;
|
||||||
|
mask = 1 << (font->width - 1);
|
||||||
|
for (int x = 0; x < font->width; x++) {
|
||||||
|
*((uint32_t*)((uint64_t)&fb+line)) = ((int)*glyph) & (mask)?0xFFFFFF:0;
|
||||||
|
mask >>= 1;
|
||||||
|
line += 4;
|
||||||
|
}
|
||||||
|
*((uint32_t*)((uint64_t)&fb+line))=0;
|
||||||
|
glyph+=bpl;
|
||||||
|
offs+=bootboot.fb_scanline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void console_scroll(void)
|
||||||
|
{
|
||||||
|
for (int i = 0; i+1 < console_max_rows; i++) {
|
||||||
|
memcpy(&console_output[i * console_max_cols],
|
||||||
|
&console_output[(i+1) * console_max_cols],
|
||||||
|
console_max_cols * sizeof *console_output);
|
||||||
|
}
|
||||||
|
memset(&console_output[(console_max_rows-1) * console_max_cols], 0,
|
||||||
|
console_max_cols * sizeof *console_output);
|
||||||
|
text_cursor_y--;
|
||||||
|
|
||||||
|
for (int r = 0; r < console_max_rows; r++) {
|
||||||
|
for (int c = 0; c < console_max_cols; c++) {
|
||||||
|
console_draw(c, r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void visual_putc(char c)
|
||||||
|
{
|
||||||
|
int col = text_cursor_x;
|
||||||
|
int row = text_cursor_y;
|
||||||
|
|
||||||
|
if (c == '\r') {
|
||||||
|
text_cursor_x = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c == '\n') {
|
||||||
|
text_cursor_y++;
|
||||||
|
if (text_cursor_y >= console_max_rows) {
|
||||||
|
console_scroll();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
text_cursor_x++;
|
||||||
|
|
||||||
|
if (col >= console_max_cols) return;
|
||||||
|
if (row >= console_max_rows) return;
|
||||||
|
|
||||||
|
console_output[col + row * console_max_cols] = c;
|
||||||
|
console_draw(col, row);
|
||||||
|
}
|
||||||
|
|
|
||||||
30
src/std.c
30
src/std.c
|
|
@ -89,6 +89,8 @@ static unsigned int current_buffer_position = 0;
|
||||||
static void linebuf_flush(void) {
|
static void linebuf_flush(void) {
|
||||||
for (unsigned int i = 0; i < current_buffer_position; i++) {
|
for (unsigned int i = 0; i < current_buffer_position; i++) {
|
||||||
uart_write_char(linebuf[i]);
|
uart_write_char(linebuf[i]);
|
||||||
|
extern void visual_putc(char c);
|
||||||
|
visual_putc(linebuf[i]);
|
||||||
}
|
}
|
||||||
current_buffer_position = 0;
|
current_buffer_position = 0;
|
||||||
}
|
}
|
||||||
|
|
@ -290,15 +292,15 @@ void printf(const char *format, ...) {
|
||||||
sign = false;
|
sign = false;
|
||||||
break;
|
break;
|
||||||
case 'c': {
|
case 'c': {
|
||||||
char ch = (char)va_arg(args, int);
|
char ch = (char)va_arg(args, int);
|
||||||
putc(ch);
|
putc(ch);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 's': {
|
case 's': {
|
||||||
char *str = va_arg(args, char *);
|
char *str = va_arg(args, char *);
|
||||||
puts(str);
|
puts(str);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'p': {
|
case 'p': {
|
||||||
void *ptr = va_arg(args, void *);
|
void *ptr = va_arg(args, void *);
|
||||||
putu64x((uint64_t)(intptr_t)ptr);
|
putu64x((uint64_t)(intptr_t)ptr);
|
||||||
|
|
@ -331,13 +333,13 @@ void printf(const char *format, ...) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case '%': {
|
case '%': {
|
||||||
putc('%');
|
putc('%');
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
PANIC("printf: unsupported format specifier");
|
PANIC("printf: unsupported format specifier");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (do_number) {
|
if (do_number) {
|
||||||
if (number_size_bits == 64) {
|
if (number_size_bits == 64) {
|
||||||
|
|
|
||||||
17
src/x86_64/loadcs.S
Normal file
17
src/x86_64/loadcs.S
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
.section .note.GNU-stack
|
||||||
|
|
||||||
|
.text
|
||||||
|
|
||||||
|
.global loadcs
|
||||||
|
|
||||||
|
// void loadcs(uint16_t ss, uint16_t cs)
|
||||||
|
// Loads new values into the SS and CS segment selector registers.
|
||||||
|
loadcs:
|
||||||
|
mov (%rsp), %rdx // return address
|
||||||
|
leaq 0x8(%rsp), %rax // old stack pointer from before call
|
||||||
|
push %rdi // ss
|
||||||
|
push %rax // rsp
|
||||||
|
pushf // rflags
|
||||||
|
push %rsi // cs
|
||||||
|
push %rdx // rip
|
||||||
|
iretq
|
||||||
|
|
@ -2,6 +2,8 @@
|
||||||
#include "std.h" // remove later, this is only for interrupt handler
|
#include "std.h" // remove later, this is only for interrupt handler
|
||||||
#include "x86_64/apic.h"
|
#include "x86_64/apic.h"
|
||||||
|
|
||||||
|
extern void loadcs(uint16_t ss, uint16_t cs);
|
||||||
|
|
||||||
uint64_t gdt[3];
|
uint64_t gdt[3];
|
||||||
|
|
||||||
void write_segment_descriptor(uint64_t *entry, uint8_t dpl, uint8_t executable) {
|
void write_segment_descriptor(uint64_t *entry, uint8_t dpl, uint8_t executable) {
|
||||||
|
|
@ -40,13 +42,15 @@ void init_gdt() {
|
||||||
|
|
||||||
__asm__("lgdt (%0)" ::"r"(gdtr));
|
__asm__("lgdt (%0)" ::"r"(gdtr));
|
||||||
|
|
||||||
|
__asm__("mov %0, %%es" ::"r"(DATA_SEGMENT << 3));
|
||||||
__asm__("mov %0, %%ds" ::"r"(DATA_SEGMENT << 3));
|
__asm__("mov %0, %%ds" ::"r"(DATA_SEGMENT << 3));
|
||||||
|
__asm__("mov %0, %%fs" ::"r"(DATA_SEGMENT << 3));
|
||||||
// TODO set code segment -> iret?
|
__asm__("mov %0, %%gs" ::"r"(DATA_SEGMENT << 3));
|
||||||
|
loadcs(DATA_SEGMENT << 3, CODE_SEGMENT << 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct __attribute__((packed))
|
__attribute__ ((packed))
|
||||||
int_desc_entry {
|
struct int_desc_entry {
|
||||||
uint16_t offset1;
|
uint16_t offset1;
|
||||||
uint16_t selector;
|
uint16_t selector;
|
||||||
uint8_t ist;
|
uint8_t ist;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue