Compare commits
No commits in common. "51af007cd51610f443731f37ee1ee00f1bc5335c" and "f79f04361afeb9aa089f734552fb8981bb6e4ec3" have entirely different histories.
51af007cd5
...
f79f04361a
53
bochsrc.txt
Normal file
53
bochsrc.txt
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
# configuration file generated by Bochs
|
||||||
|
plugin_ctrl: unmapped=1, biosdev=1, speaker=1, extfpuirq=1, parallel=1, serial=1, iodebug=1
|
||||||
|
config_interface: textconfig
|
||||||
|
display_library: x
|
||||||
|
memory: host=32, guest=32
|
||||||
|
romimage: file="/usr/share/bochs/BIOS-bochs-latest", address=0x0, options=none
|
||||||
|
vgaromimage: file="/usr/share/bochs/VGABIOS-lgpl-latest"
|
||||||
|
boot: a
|
||||||
|
floppy_bootsig_check: disabled=1
|
||||||
|
floppya: 1_44=/dev/loop0, status=inserted
|
||||||
|
# no floppyb
|
||||||
|
ata0: enabled=0
|
||||||
|
ata1: enabled=0
|
||||||
|
ata2: enabled=0
|
||||||
|
ata3: enabled=0
|
||||||
|
optromimage1: file=none
|
||||||
|
optromimage2: file=none
|
||||||
|
optromimage3: file=none
|
||||||
|
optromimage4: file=none
|
||||||
|
optramimage1: file=none
|
||||||
|
optramimage2: file=none
|
||||||
|
optramimage3: file=none
|
||||||
|
optramimage4: file=none
|
||||||
|
pci: enabled=1, chipset=i440fx
|
||||||
|
vga: extension=vbe, update_freq=5, realtime=1
|
||||||
|
cpu: count=1:1:1, ips=1000000, quantum=16, model=bx_generic, reset_on_triple_fault=0, cpuid_limit_winnt=0, ignore_bad_msrs=1, mwait_is_nop=0
|
||||||
|
cpuid: level=6, stepping=3, model=3, family=6, vendor_string="AuthenticAMD", brand_string="AMD Athlon(tm) processor"
|
||||||
|
cpuid: mmx=1, apic=xapic, simd=sse2, sse4a=0, misaligned_sse=0, sep=1, movbe=0, adx=0
|
||||||
|
cpuid: aes=0, sha=0, xsave=0, xsaveopt=0, avx_f16c=0, avx_fma=0, bmi=0, xop=0, fma4=0
|
||||||
|
cpuid: tbm=0, x86_64=1, 1g_pages=0, pcid=0, fsgsbase=0, smep=0, smap=0, mwait=1
|
||||||
|
print_timestamps: enabled=0
|
||||||
|
debugger_log: ../red.debug
|
||||||
|
magic_break: enabled=1
|
||||||
|
port_e9_hack: enabled=0
|
||||||
|
private_colormap: enabled=0
|
||||||
|
clock: sync=none, time0=local, rtc_sync=0
|
||||||
|
# no cmosimage
|
||||||
|
# no loader
|
||||||
|
log: ../red.log
|
||||||
|
logprefix: %t%e%d
|
||||||
|
debug: action=ignore
|
||||||
|
info: action=report
|
||||||
|
error: action=report
|
||||||
|
panic: action=ask
|
||||||
|
keyboard: type=mf, serial_delay=250, paste_delay=100000, user_shortcut=none
|
||||||
|
mouse: type=ps2, enabled=0, toggle=ctrl+mbutton
|
||||||
|
speaker: enabled=1, mode=system
|
||||||
|
parport1: enabled=1, file=none
|
||||||
|
parport2: enabled=0
|
||||||
|
com1: enabled=1, mode=null
|
||||||
|
com2: enabled=0
|
||||||
|
com3: enabled=0
|
||||||
|
com4: enabled=0
|
|
@ -6,7 +6,6 @@ kernel\utils.c
|
||||||
kernel\graphics.c
|
kernel\graphics.c
|
||||||
kernel\print.c
|
kernel\print.c
|
||||||
kernel\interrupts.c
|
kernel\interrupts.c
|
||||||
kernel\ports.c
|
|
||||||
kernel\memory.c
|
kernel\memory.c
|
||||||
kernel\memory\memmove.c
|
kernel\memory\memmove.c
|
||||||
kernel\memory\memcmp.c
|
kernel\memory\memcmp.c
|
||||||
|
|
|
@ -618,9 +618,6 @@ static const char* ExceptionStrings[] = {
|
||||||
/* = Sync Functions = */
|
/* = Sync Functions = */
|
||||||
/* ============================================================= */
|
/* ============================================================= */
|
||||||
|
|
||||||
/* Required functions */
|
|
||||||
size_t strlen(const char* string);
|
|
||||||
|
|
||||||
/* System Initialization */
|
/* System Initialization */
|
||||||
void PrepareSystem(FILELOADER_PARAMS* FLOP);
|
void PrepareSystem(FILELOADER_PARAMS* FLOP);
|
||||||
|
|
||||||
|
@ -642,13 +639,10 @@ uint32_t ReadPort(uint16_t Port, int Length);
|
||||||
uint32_t WritePort(uint16_t Port, uint32_t Data, int Length);
|
uint32_t WritePort(uint16_t Port, uint32_t Data, int Length);
|
||||||
|
|
||||||
/* Serial functions */
|
/* Serial functions */
|
||||||
void serialWrite(const char chr);
|
void serial_write(const char chr);
|
||||||
void serialPrint(const char* data);
|
void serial_print(const char* data);
|
||||||
void serialPrintf(const char* format, ...);
|
void serial_printf(const char* format, ...);
|
||||||
void serialInit();
|
void init_serial();
|
||||||
void inttoa(int input, char* output);
|
|
||||||
void itoh(int input, char* output);
|
|
||||||
void zeroString(char* string);
|
|
||||||
|
|
||||||
/* ==================== Registers ==================== */
|
/* ==================== Registers ==================== */
|
||||||
size_t ReadModelSpecificRegister(size_t MSR);
|
size_t ReadModelSpecificRegister(size_t MSR);
|
||||||
|
@ -682,15 +676,15 @@ void SetLDT(uint16_t LDTData);
|
||||||
uint16_t FetchTSR(void);
|
uint16_t FetchTSR(void);
|
||||||
void SetTSR(uint16_t TSRData);
|
void SetTSR(uint16_t TSRData);
|
||||||
|
|
||||||
void InstallGDT(void);
|
void InstallGDT(void);
|
||||||
void InstallIDT(void);
|
void InstallIDT(void);
|
||||||
void InstallPaging(void);
|
void InstallPaging(void);
|
||||||
|
|
||||||
/* ==================== Branding ==================== */
|
/* ==================== Branding ==================== */
|
||||||
char* FetchBrandStr(uint32_t* Str);
|
char* FetchBrandStr(uint32_t* Str);
|
||||||
char* FetchManufacturer(char* ID);
|
char* FetchManufacturer(char* ID);
|
||||||
|
|
||||||
void ScanCPUFeatures(size_t RAX, size_t RCX);
|
void ScanCPUFeatures(size_t RAX, size_t RCX);
|
||||||
|
|
||||||
/* ==================== Interrupts ==================== */
|
/* ==================== Interrupts ==================== */
|
||||||
|
|
||||||
|
|
|
@ -43,12 +43,12 @@ __attribute__((aligned(4096))) static size_t FirstPageTable[512] = {0};
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//Play sound using built in speaker
|
//Play sound using built in speaker
|
||||||
static void playPCSpeaker(uint32_t frequency) {
|
static void play_sound(uint32_t nFrequence) {
|
||||||
uint32_t Div;
|
uint32_t Div;
|
||||||
uint8_t tmp;
|
uint8_t tmp;
|
||||||
|
|
||||||
//Set the PIT to the desired frequency
|
//Set the PIT to the desired frequency
|
||||||
Div = 1193180 / frequency;
|
Div = 1193180 / nFrequence;
|
||||||
WritePort(0x0043, 0xb6, 1);
|
WritePort(0x0043, 0xb6, 1);
|
||||||
WritePort(0x0042, (uint8_t) (Div), 1);
|
WritePort(0x0042, (uint8_t) (Div), 1);
|
||||||
WritePort(0x0042, (uint8_t) (Div >> 8), 1);
|
WritePort(0x0042, (uint8_t) (Div >> 8), 1);
|
||||||
|
@ -61,22 +61,22 @@ __attribute__((aligned(4096))) static size_t FirstPageTable[512] = {0};
|
||||||
}
|
}
|
||||||
|
|
||||||
//make it shutup
|
//make it shutup
|
||||||
static void stopPCSpeaker() {
|
static void nosound() {
|
||||||
uint8_t tmp = ReadPort(0x0061, 1) & 0xFC;
|
uint8_t tmp = ReadPort(0x0061, 1) & 0xFC;
|
||||||
|
|
||||||
WritePort(0x0061, tmp, 1);
|
WritePort(0x0061, tmp, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Make a beep
|
//Make a beep
|
||||||
void beepPCSpeaker() {
|
void beep() {
|
||||||
playPCSpeaker(1000);
|
play_sound(1000);
|
||||||
awaitTicks(10);
|
timer_wait(10);
|
||||||
stopPCSpeaker();
|
nosound();
|
||||||
//set_PIT_2(old_frequency);
|
//set_PIT_2(old_frequency);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void awaitTicks(int ticks) {
|
void timer_wait(int ticks){
|
||||||
uint64_t FinalTick = time + ticks;
|
uint64_t FinalTick = time + ticks;
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
@ -94,19 +94,9 @@ void PrepareSystem(FILELOADER_PARAMS* FLOP) {
|
||||||
|
|
||||||
|
|
||||||
SetupPrinting(FLOP->GPU_Info->GPUs[0]);
|
SetupPrinting(FLOP->GPU_Info->GPUs[0]);
|
||||||
ClearScreen(Print_Info.defaultGPU);
|
|
||||||
printf("1");
|
|
||||||
SetupPrinting(FLOP->GPU_Info->GPUs[1]);
|
|
||||||
ClearScreen(Print_Info.defaultGPU);
|
|
||||||
printf("2");
|
|
||||||
/* All print functions are now available. */
|
/* All print functions are now available. */
|
||||||
printf("ready!");
|
printf("ready!");
|
||||||
|
|
||||||
serialInit();
|
|
||||||
serialPrintf("Kernel has been given control of the computer.\nStarting bootstrap init.\n");
|
|
||||||
|
|
||||||
FLOP->RTServices->ResetSystem(EfiResetShutdown, EFI_SUCCESS, 0, L"");
|
|
||||||
|
|
||||||
InstallGDT();
|
InstallGDT();
|
||||||
InstallIDT();
|
InstallIDT();
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,9 @@
|
||||||
and other functions that are uniquely
|
and other functions that are uniquely
|
||||||
related to the above tasks. */
|
related to the above tasks. */
|
||||||
|
|
||||||
#include <kernel.h>
|
#include <kernel/utils.h>
|
||||||
|
#include <kernel/descriptor_tables.h>
|
||||||
|
#include <kernel/serial.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The GDT gate setting function.
|
* The GDT gate setting function.
|
||||||
|
|
|
@ -37,6 +37,8 @@ void SetupPrinting(EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE GPU) {
|
||||||
Print_Info.cursorPos = 0;
|
Print_Info.cursorPos = 0;
|
||||||
|
|
||||||
Print_Info.scrollMode = 0;
|
Print_Info.scrollMode = 0;
|
||||||
|
|
||||||
|
ClearScreen(GPU);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WriteScaledFormatString(EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE GPU,
|
void WriteScaledFormatString(EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE GPU,
|
||||||
|
|
|
@ -52,8 +52,8 @@ void ISR_Common(INTERRUPT_FRAME* Frame, size_t Exception) {
|
||||||
if(Exception < 32) {
|
if(Exception < 32) {
|
||||||
/* ExceptionStrings is an array of c-strings defined in kernel.h */
|
/* ExceptionStrings is an array of c-strings defined in kernel.h */
|
||||||
|
|
||||||
serialPrint(ExceptionStrings[Exception]);
|
serial_print(ExceptionStrings[Exception]);
|
||||||
serialPrint(" Exception.\r\n");
|
serial_print(" Exception.\r\n");
|
||||||
printf("%s exception!", ExceptionStrings[Exception]);
|
printf("%s exception!", ExceptionStrings[Exception]);
|
||||||
panic();
|
panic();
|
||||||
}
|
}
|
||||||
|
@ -63,8 +63,8 @@ void ISR_Common(INTERRUPT_FRAME* Frame, size_t Exception) {
|
||||||
into what went wrong. In pure Curle style, though, we just ignore the error code. */
|
into what went wrong. In pure Curle style, though, we just ignore the error code. */
|
||||||
void ISR_Error_Common(EXCEPTION_FRAME* Frame, size_t Exception) {
|
void ISR_Error_Common(EXCEPTION_FRAME* Frame, size_t Exception) {
|
||||||
if(Exception < 32) {
|
if(Exception < 32) {
|
||||||
serialPrint(ExceptionStrings[Exception]);
|
serial_print(ExceptionStrings[Exception]);
|
||||||
serialPrintf(" Exception. Context given: %d\r\n", Frame->ErrorCode);
|
serial_printf(" Exception. Context given: %d\r\n", Frame->ErrorCode);
|
||||||
printf("%s exception. Context: %x", ExceptionStrings[Exception], Frame->ErrorCode);
|
printf("%s exception. Context: %x", ExceptionStrings[Exception], Frame->ErrorCode);
|
||||||
panic();
|
panic();
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,8 @@ void gdb_end() {} /* GDB Debugging stump */
|
||||||
static size_t time = 0;
|
static size_t time = 0;
|
||||||
|
|
||||||
int kernel_main(FILELOADER_PARAMS* FLOP) {
|
int kernel_main(FILELOADER_PARAMS* FLOP) {
|
||||||
|
init_serial();
|
||||||
|
serial_printf("Kernel has been given control of the computer.\nStarting bootstrap init.\n");
|
||||||
/* The kernel is started in 64-bit Long Mode by Syncboot. */
|
/* The kernel is started in 64-bit Long Mode by Syncboot. */
|
||||||
|
|
||||||
/* PrepareSystem just initializes all hardware features and gets the system ready to execute every function.
|
/* PrepareSystem just initializes all hardware features and gets the system ready to execute every function.
|
||||||
|
|
110
kernel/serial.c
110
kernel/serial.c
|
@ -14,118 +14,132 @@
|
||||||
|
|
||||||
#include <kernel.h>
|
#include <kernel.h>
|
||||||
|
|
||||||
#define SERIAL_DATA(base) (base)
|
#define SERIAL_DATA_PORT(base) (base)
|
||||||
#define SERIAL_DLAB(base) (base + 1)
|
#define SERIAL_FIFO_COMMAND_PORT(base) (base + 2)
|
||||||
#define SERIAL_FIFO(base) (base + 2)
|
#define SERIAL_LINE_COMMAND_PORT(base) (base + 3)
|
||||||
#define SERIAL_LINE(base) (base + 3)
|
#define SERIAL_MODEM_COMMAND_PORT(base) (base + 4)
|
||||||
#define SERIAL_MODEM(base) (base + 4)
|
#define SERIAL_LINE_STATUS_PORT(base) (base + 5)
|
||||||
#define SERIAL_LINE_STATUS(base) (base + 5)
|
#define SERIAL_COM1_BASE 0x3F8
|
||||||
#define COM1 0x3F8
|
|
||||||
|
|
||||||
|
#define SERIAL_LINE_ENABLE_DLAB 0x80
|
||||||
|
|
||||||
/** serialSetBaudrate:
|
/** serial_set_baud_rate:
|
||||||
* Sets the speed that data is sent via the serial port.
|
* Sets the speed that data is sent via the serial port.
|
||||||
* The default speed is 115200 bits/s.
|
* The default speed is 115200 bits/s.
|
||||||
* The argument given is the divisor of the number.
|
* The argument given is the divisor of the number.
|
||||||
* Hence, the new speed becomes (115200/divisor) bits/s.
|
* Hence, the new speed becomes (115200/divisor) bits/s.
|
||||||
*
|
*
|
||||||
|
* @param com The COM port to configure.
|
||||||
* @param divisor The new divisor for the baud rate.
|
* @param divisor The new divisor for the baud rate.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void serialSetBaudrate() {
|
void serial_set_baud_rate(uint16_t com, uint16_t divisor) {
|
||||||
WritePort(SERIAL_LINE(COM1), 0x80, 1);
|
WritePort(SERIAL_LINE_COMMAND_PORT(com),
|
||||||
|
SERIAL_LINE_ENABLE_DLAB, 1);
|
||||||
|
|
||||||
WritePort(SERIAL_DATA(COM1), 0x03, 1);
|
WritePort(SERIAL_DATA_PORT(com),
|
||||||
|
(divisor >> 8) & 0x00FF, 1);
|
||||||
|
|
||||||
WritePort(SERIAL_DLAB(COM1), 0x00, 1);
|
WritePort(SERIAL_DATA_PORT(com),
|
||||||
|
divisor & 0x00FF, 1);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** serialConfigure:
|
/** serial_configure_line:
|
||||||
* Sets a specific data byteset in the Serial hardware.
|
* Sets a specific data byteset in the Serial hardware.
|
||||||
* Required for expected operation.
|
* Required for expected operation.
|
||||||
|
*
|
||||||
|
* @param com The COM port to configure.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void serialConfigure() {
|
void serial_configure_line(uint16_t com) {
|
||||||
/* Bit: | 7 | 6 | 5 4 3 | 2 | 1 0 |
|
/* Bit: | 7 | 6 | 5 4 3 | 2 | 1 0 |
|
||||||
* Content: | d | b | parity | s | dl |
|
* Content: | d | b | parity | s | dl |
|
||||||
* Value: | 0 | 0 | 0 0 0 | 0 | 1 1 | = 0x03
|
* Value: | 0 | 0 | 0 0 0 | 0 | 1 1 | = 0x03
|
||||||
*/
|
*/
|
||||||
WritePort(SERIAL_LINE(COM1), 0x03, 1);
|
|
||||||
|
WritePort(SERIAL_LINE_COMMAND_PORT(com), 0x0B, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** serialConfigureBuffers:
|
/** serial_configure_buffers:
|
||||||
* Enables FIFO (First In First Out) on the Serial line.
|
* Enables FIFO (First In First Out) on the Serial line.
|
||||||
* It clears both the receive and transmit queues.
|
* It clears both the receive and transmit queues.
|
||||||
* It uses a 14 byte wide queue.
|
* It uses a 14 byte wide queue.
|
||||||
*
|
*
|
||||||
|
* @param com The COM port to configure.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void serialConfigureBuffers() {
|
void serial_configure_buffers(uint16_t com) {
|
||||||
/* Bit: | 7 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|
/* Bit: | 7 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|
||||||
* Content: | 1v1 | bs | r | dma | clt | clr | e |
|
* Content: | 1v1 | bs | r | dma | clt | clr | e |
|
||||||
* Value: | 1 1 | 0 | 0 | 0 | 1 | 1 | 1 | = 0xC7
|
* Value: | 1 1 | 0 | 0 | 0 | 1 | 1 | 1 | = 0xC7
|
||||||
*/
|
*/
|
||||||
|
|
||||||
WritePort(SERIAL_FIFO(COM1), 0xC7, 1);
|
WritePort(SERIAL_FIFO_COMMAND_PORT(com), 0xC7, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** serialConfigureModem:
|
/** serial_configure_modem
|
||||||
|
* @param com The COM port to configure.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void serialConfigureModem() {
|
void serial_configure_modem(uint16_t com) {
|
||||||
/* Bit: | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|
/* Bit: | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|
||||||
* Content: | r | r | af | lb | ao2 | ao1 | rts | dtr |
|
* Content: | r | r | af | lb | ao2 | ao1 | rts | dtr |
|
||||||
* Value: | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | = 0x03
|
* Value: | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | = 0x03
|
||||||
*/
|
*/
|
||||||
|
|
||||||
WritePort(SERIAL_MODEM(COM1), 0x03, 1);
|
WritePort(SERIAL_MODEM_COMMAND_PORT(com), 0x3, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** serialCheck:
|
/** serial_check_tqueue:
|
||||||
* Checks whether the Transmit FIFO Queue is empty on the given port.
|
* Checks whether the Transmit FIFO Queue is empty on the given port.
|
||||||
*
|
*
|
||||||
|
* @param com The COM port to check.
|
||||||
* @return 0 If the queue is not empty.
|
* @return 0 If the queue is not empty.
|
||||||
* 1 If the queue is empty.
|
* 1 If the queue is empty.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int serialCheck() {
|
int serial_check_tqueue(uint16_t com) {
|
||||||
return ReadPort(SERIAL_LINE_STATUS(COM1), 1) & 0x20;
|
return ReadPort(SERIAL_LINE_STATUS_PORT(com), 1) & 0x20;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** serial_write:
|
/** serial_write:
|
||||||
* Prints a single character to the serial port.
|
* Prints a single character to the serial port.
|
||||||
* Does nothing fancy.
|
* Does nothing fancy.
|
||||||
|
* @param com The COM port to write to.
|
||||||
* @param data The character to write.
|
* @param data The character to write.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void serialWrite(const char chr) {
|
void serial_write(const char chr) {
|
||||||
|
uint16_t com = SERIAL_COM1_BASE;
|
||||||
//Hang until we have access to the COM port.
|
//Hang until we have access to the COM port.
|
||||||
while(!serialCheck());
|
while(serial_check_tqueue(com) == 0);
|
||||||
WritePort(COM1, chr, 1);
|
WritePort(com, chr, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** serialPrint:
|
/** serial_print:
|
||||||
* Prints a string to the serial port.
|
* Prints a string to the serial port.
|
||||||
* Does not support ANSI codes, or color.
|
* Does not support ANSI codes, or color.
|
||||||
*
|
*
|
||||||
|
* @param com The COM port to write to.
|
||||||
* @param data The string to write.
|
* @param data The string to write.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void serialPrint(const char* data) {
|
void serial_print(const char* data) {
|
||||||
for(size_t i = 0; i < strlen(data); i++) {
|
for(size_t i = 0; i < strlen(data); i++) {
|
||||||
serialWrite(data[i]);
|
serial_write(data[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** serialPrintf:
|
/** serial_printf:
|
||||||
* A printf-style function for the serial port.
|
* A printf-style function for the serial port.
|
||||||
*
|
*
|
||||||
* @param format The base string - used to substitute the succeding values.
|
* @param format The base string - used to substitute the succeding values.
|
||||||
* @param ... The substitutions.
|
* @param ... The substitutions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void serialPrintf(const char* format, ...) {
|
void serial_printf(const char* format, ...) {
|
||||||
|
uint16_t com = SERIAL_COM1_BASE;
|
||||||
uint32_t storage; //To hold temporary variables
|
uint32_t storage; //To hold temporary variables
|
||||||
char stringstore[10] = {0}; //To convert ints to strings.
|
char stringstore[10] = {0}; //To convert ints to strings.
|
||||||
va_list list;
|
va_list list;
|
||||||
|
@ -138,46 +152,46 @@ void serialPrintf(const char* format, ...) {
|
||||||
if(format[i+1] == 'd') {
|
if(format[i+1] == 'd') {
|
||||||
|
|
||||||
storage = va_arg(list, int);
|
storage = va_arg(list, int);
|
||||||
inttoa(storage, stringstore);
|
int_to_ascii(storage, stringstore);
|
||||||
serialPrint(stringstore);
|
serial_print(stringstore);
|
||||||
zeroString(stringstore);
|
empty_string(stringstore);
|
||||||
i += 2;
|
i += 2;
|
||||||
|
|
||||||
} else if(format[i+1] == 'x') {
|
} else if(format[i+1] == 'x') {
|
||||||
|
|
||||||
storage = va_arg(list, int);
|
storage = va_arg(list, int);
|
||||||
itoh(storage, stringstore);
|
int_to_hex(storage, stringstore);
|
||||||
serialPrint(stringstore);
|
serial_print(stringstore);
|
||||||
zeroString(stringstore);
|
empty_string(stringstore);
|
||||||
i += 2;
|
i += 2;
|
||||||
|
|
||||||
} else if(format[i+1] == 's') {
|
} else if(format[i+1] == 's') {
|
||||||
|
|
||||||
serialPrint(va_arg(list, char*));
|
serial_print(va_arg(list, char*));
|
||||||
i += 2;
|
i += 2;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
serialPrint("ERROR: Attempting to parse unknown format string.");
|
serial_print("ERROR: Attempting to parse unknown format string.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
serialWrite(format[i]);
|
serial_write(format[i]);
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
va_end(list); //Free the list
|
va_end(list); //Free the list
|
||||||
}
|
}
|
||||||
|
|
||||||
void serialInit() {
|
void init_serial() {
|
||||||
// Disable interrupts
|
// Disable interrupts
|
||||||
WritePort(SERIAL_DLAB(COM1), 0x00, 1);
|
WritePort(SERIAL_COM1_BASE + 1, 0x00, 1);
|
||||||
|
|
||||||
// Set baud rate divisor to 3
|
// Set baud rate divisor.
|
||||||
serialSetBaudrate();
|
serial_set_baud_rate(SERIAL_COM1_BASE, 3);
|
||||||
// 8 bits, no parity, one stop bit.
|
// 8 bits, no parity, one stop bit.
|
||||||
serialConfigure();
|
serial_configure_line(SERIAL_COM1_BASE);
|
||||||
// Enable FIFO and clear buffers.
|
// Enable FIFO and clear buffers.
|
||||||
serialConfigureBuffers();
|
serial_configure_buffers(SERIAL_COM1_BASE);
|
||||||
// Enable IRQs, RTS/DSR set.
|
// Enable IRQs, RTS/DSR set.
|
||||||
serialConfigureModem();
|
serial_configure_modem(SERIAL_COM1_BASE);
|
||||||
}
|
}
|
||||||
|
|
|
@ -93,7 +93,7 @@ int memcmp (const void *str1, const void *str2, size_t count) {
|
||||||
* @param string: The string to be written into.
|
* @param string: The string to be written into.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void inttoa(int num, char* string) {
|
void int_to_ascii(int num, char* string) {
|
||||||
size_t i = 0; //Counter.
|
size_t i = 0; //Counter.
|
||||||
// TODO: Convert this to a for-loop?
|
// TODO: Convert this to a for-loop?
|
||||||
int32_t calc = 0;
|
int32_t calc = 0;
|
||||||
|
@ -157,8 +157,8 @@ char* itoc(size_t num) {
|
||||||
* @param num: Number to convert
|
* @param num: Number to convert
|
||||||
* @param string: String pointer to put the converted number.
|
* @param string: String pointer to put the converted number.
|
||||||
*/
|
*/
|
||||||
void itoh(int num, char* string) {
|
void int_to_hex(int num, char* string) {
|
||||||
zeroString(string);
|
empty_string(string);
|
||||||
|
|
||||||
uint8_t i = 8;
|
uint8_t i = 8;
|
||||||
uint8_t temp = 0;
|
uint8_t temp = 0;
|
||||||
|
@ -182,7 +182,7 @@ void itoh(int num, char* string) {
|
||||||
* @param string: The string to empty.
|
* @param string: The string to empty.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void zeroString(char* string) {
|
void empty_string(char* string) {
|
||||||
size_t len = strlen(string);
|
size_t len = strlen(string);
|
||||||
|
|
||||||
for(size_t i = 0; i < len + 1; i++) {
|
for(size_t i = 0; i < len + 1; i++) {
|
||||||
|
|
91
makefile
Executable file
91
makefile
Executable file
|
@ -0,0 +1,91 @@
|
||||||
|
DEFAULT_HOST:=i686-elf
|
||||||
|
HOST?=DEFAULT_HOST
|
||||||
|
HOSTARCH:=i386
|
||||||
|
CC:=$(PREFIX)/bin/$(DEFAULT_HOST)-gcc
|
||||||
|
|
||||||
|
CFLAGS?= -O0 -g -fno-pie -fno-stack-protector -Wl,--build-id=none
|
||||||
|
CPPFLAGS?=
|
||||||
|
LDFLAGS?=
|
||||||
|
LIBS?=
|
||||||
|
|
||||||
|
DESTDIR?=
|
||||||
|
PREFIX?=/usr/local
|
||||||
|
EXEC_PREFIX?=$(PREFIX)
|
||||||
|
BOOTDIR?=$(EXEC_PREFIX)/boot
|
||||||
|
INCLUDEDIR?=$(PREFIX)/include
|
||||||
|
|
||||||
|
CFLAGS:=$(CFLAGS) -ffreestanding -Wall -Wextra -I"../include" -I"../../include"
|
||||||
|
CPPFLAGS:=$(CPPFLAGS) -D__is_kernel -Iinclude
|
||||||
|
LDFLAGS:=$(LDFLAGS)
|
||||||
|
LIBS:=$(LIBS) -nostdlib -lgcc
|
||||||
|
|
||||||
|
ARCHDIR=arch/$(HOSTARCH)
|
||||||
|
|
||||||
|
include $(ARCHDIR)/make.config
|
||||||
|
|
||||||
|
CFLAGS:=$(CFLAGS) $(KERNEL_ARCH_CFLAGS)
|
||||||
|
CPPFLAGS:=$(CPPFLAGS) $(KERNEL_ARCH_CPPFLAGS)
|
||||||
|
LDFLAGS:=$(LDFLAGS) $(KERNEL_ARCH_LDFLAGS)
|
||||||
|
LIBS:=$(LIBS) $(KERNEL_ARCH_LIBS)
|
||||||
|
|
||||||
|
KERNEL_OBJS= \
|
||||||
|
$(KERNEL_ARCH_OBJS) \
|
||||||
|
kernel/utils.o \
|
||||||
|
kernel/serial.o \
|
||||||
|
kernel/interrupts.o \
|
||||||
|
kernel/descriptor_tables.o\
|
||||||
|
kernel/kernel.o
|
||||||
|
|
||||||
|
OBJS=\
|
||||||
|
$(KERNEL_OBJS)
|
||||||
|
|
||||||
|
LINK_LIST=\
|
||||||
|
$(LDFLAGS) \
|
||||||
|
$(KERNEL_OBJS) \
|
||||||
|
$(LIBS) \
|
||||||
|
|
||||||
|
.PHONY: all clean install install-headers install-kernel
|
||||||
|
.SUFFIXES: .o .c .s
|
||||||
|
|
||||||
|
all: red.kernel
|
||||||
|
|
||||||
|
red.kernel: $(OBJS) $(ARCHDIR)/linker.ld
|
||||||
|
$(CC) -T $(ARCHDIR)/linker.ld -o $@ $(CFLAGS) $(LINK_LIST)
|
||||||
|
|
||||||
|
kernel/interrupts.o:
|
||||||
|
$(CC) -MD -c kernel/interrupts.c -o $@ -std=gnu11 $(CFLAGS) -mno-red-zone -mgeneral-regs-only $(CPPFLAGS)
|
||||||
|
|
||||||
|
.c.o:
|
||||||
|
$(CC) -MD -c $< -o $@ -std=gnu11 $(CFLAGS) $(CPPFLAGS)
|
||||||
|
.s.o:
|
||||||
|
nasm -f elf $< -o $@
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f red.kernel
|
||||||
|
rm -f $(OBJS) *.o */*.o */*/*.o
|
||||||
|
rm -f $(OBJS:.o=.d) *.d */*.d */*/*.d
|
||||||
|
|
||||||
|
install: install-headers install-kernel gen-iso
|
||||||
|
|
||||||
|
install-headers:
|
||||||
|
mkdir -p $(DESTDIR)$(INCLUDEDIR)
|
||||||
|
cp -R --preserve=timestamps include/. $(DESTDIR)$(INCLUDEDIR)/.
|
||||||
|
|
||||||
|
install-kernel: red.kernel
|
||||||
|
mkdir -p $(DESTDIR)$(BOOTDIR)
|
||||||
|
cp red.kernel $(DESTDIR)$(BOOTDIR)
|
||||||
|
|
||||||
|
gen-iso:
|
||||||
|
rm -f red.iso
|
||||||
|
cp red.kernel iso/boot/kernel.elf
|
||||||
|
genisoimage -R \
|
||||||
|
-b boot/grub/stage2_eltorito \
|
||||||
|
-no-emul-boot \
|
||||||
|
-A ProjectRED \
|
||||||
|
-input-charset utf8 \
|
||||||
|
-quiet \
|
||||||
|
-boot-info-table \
|
||||||
|
-o red.iso \
|
||||||
|
iso
|
||||||
|
|
||||||
|
-include $(OBJS:.o=.d)
|
Loading…
Reference in New Issue
Block a user