Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Scrolling & Multiple Shells & 1 screen per shell #1

Open
wants to merge 10 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 17 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,23 @@ all:
$(MAKE) -C user/ all VERBOSE=$(VERBOSE)
$(MAKE) -C kernel/ kernel.bin VERBOSE=$(VERBOSE)

msw: docker.msw run
macos: docker.macos run

test-kernel:
./kernel/run_tests.sh

test-user:
./user/run_tests.sh

docker:
docker run -i --platform linux/amd64 --entrypoint 'make' --workdir /psys-base --rm -v $(PWD):/psys-base gcc:11.4.0
docker.msw:
docker run -i --platform linux/amd64 --entrypoint 'make' --workdir /KrapOS --rm -v C:\_Lejus\KrapOS:/KrapOS gcc:11.4.0
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

!! Do not use absolute path.
Make could provide something like $(PWD).

docker.macos:
docker run -i --platform linux/amd64 --entrypoint 'make' --workdir /KrapOS --rm -v $(PWD):/KrapOS gcc:11.4.0

debug: run-kernel-debug run-debugger
debug.macos: run-kernel-debug run-debugger.macos
debug.msw: run-kernel-debug.msw run-debugger.msw

run: run-kernel

Expand All @@ -28,12 +34,21 @@ run-kernel-debug:
killall qemu-system-i386 || true
qemu-system-i386 -machine q35 -m 256 -kernel kernel/kernel.bin -s -S -debugcon stdio > qemu-output.txt &

run-kernel-debug.msw:
taskkill /F /IM qemu-system-i386.exe /T > nul 2>&1
qemu-system-i386 -machine q35 -m 256 -kernel kernel/kernel.bin -s -S -debugcon stdio > qemu-output.txt

run-debugger:
/usr/bin/gdb kernel/kernel.bin -ex 'target remote localhost:1234'

run-debugger.macos:
lldb kernel/kernel.bin -o 'gdb-remote localhost:1234'
run-debugger.msw:
gdb kernel/kernel.bin -ex 'target remote localhost:1234'

clean.msw:
$(MAKE) clean.msw -C kernel/
$(MAKE) clean.msw -C user/
clean:
$(MAKE) clean -C kernel/
$(MAKE) clean -C user/
Expand Down
4 changes: 4 additions & 0 deletions kernel/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -145,4 +145,8 @@ $(OUTPUT):
.PHONY: clean
clean:
rm -rf $(OUTPUT) kernel.bin cd.iso
clean.msw:
rd /s /q out
del kernel.bin
del cd.iso

9 changes: 3 additions & 6 deletions kernel/it.c
Original file line number Diff line number Diff line change
@@ -1,10 +1,4 @@
#include "stdio.h"
#include "cpu.h"
#include "it.h"
#include "screen.h"
#include "segment.h"
#include "process.h"
#include "kbd.h"

uint32_t ticks = 0;

Expand Down Expand Up @@ -39,6 +33,9 @@ void tic_PIT(void){
outb(0x20,0x20);
ticks++;

// Handle sleeping processes
seek_for_awaking_processes();

scheduler();
}

Expand Down
7 changes: 7 additions & 0 deletions kernel/it.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
#ifndef __IT_H__
#define __IT_H__

#include "stdio.h"
#include "cpu.h"
#include "screen.h"
#include "segment.h"
#include "process.h"
#include "kbd.h"

#define IDT 0x1000
#define CST_IT 0x8E00
#define USER_CST_IT 0xEE00
Expand Down
2 changes: 1 addition & 1 deletion kernel/it_handlers.S
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,4 @@ IT_49_handler:
popl %edi
popl %esi

iret
iret
113 changes: 101 additions & 12 deletions kernel/kbd.c
Original file line number Diff line number Diff line change
@@ -1,34 +1,49 @@
#include "kbd.h"
#include "stdio.h"
#include "cpu.h"
#include "mem.h"
#include "string.h"
#include "process.h"
#include "queue.h"

kbd_buf keyboard_buffer;
int writing;
int echo = 1;
int echoing = 0;

void init_keyboard_buffer(void){
void init_keyboard_buffer(void) {
keyboard_buffer.count = 0;
keyboard_buffer.write_head = 0;
keyboard_buffer.read_head = 0;
writing = 0;
}

void kbd_int(void){
void kbd_int(void) {
// Read the scancode from the keyboard port
unsigned char scancode = inb(0x60);

// Acknowledge the interruption
outb(0x20,0x20);

// Translate scancode to a character
do_scancode((char) scancode);
if(scancode == 224){
scancode = inb(0x60);
outb(0x20,0x20);
if (scancode == 72) {
cmd_hist_up();
}
if (scancode == 73) {
scroll_up();
}
if (scancode == 80) {
cmd_hist_down();
}
if (scancode == 81) {
scroll_down();
}
}
else if(scancode == 73 || scancode == 81 || scancode == 72 || scancode == 80) {
return;
} else {
// Translate scancode to a character
do_scancode((char) scancode);
}
}

void keyboard_data(char *str){
void keyboard_data(char *str) {
int i = 0;
char c = str[i];

Expand All @@ -44,14 +59,18 @@ void keyboard_data(char *str){
keyboard_buffer.count--;
if(echo){
c = '\b';
echoing = true;
cons_write(&c, 1);
echoing = false;
}
}
} else {
// Echo the char to the console if enabled
if (echo) {
echoing = true;
if (c == '\r') cons_write("\n", 1);
cons_write(&c, 1);
echoing = false;
}
// Increase kbd buffers counters
keyboard_buffer.write_head = (keyboard_buffer.write_head + 1) % KBD_BUF_SIZE;
Expand All @@ -71,9 +90,79 @@ void keyboard_data(char *str){
}
}

void kbd_leds(unsigned char leds){
void kbd_leds(unsigned char leds) {
// Write the led status to the keyboard port
outb(0xED, 0x60);
for (int i = 0; i < 100000; i++);
outb(leds, 0x60);
}

void cons_echo(int on) {
echo = on;
}

int cons_read(char *string, unsigned long length){
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cons_read in kbd.c file ?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could benefit from another file like cons.c/h

if(length <= 0) return 0;
long unsigned int read = 0;
char buffer[length];

// If precedent call left a cons_read
if(keyboard_buffer.buf[keyboard_buffer.read_head] == 13){
keyboard_buffer.count--;
keyboard_buffer.read_head = (keyboard_buffer.read_head + 1) % KBD_BUF_SIZE;
return 0;
}
writing++;

// Lock until 13 char
process_t* running = process_table->running;
running->state = LOCKED_IO;
queue_add(running, process_table->io_queue, process_t, queue_link, priority);
scheduler();

for(read = 0 ; read < length ; read++){
if(keyboard_buffer.buf[keyboard_buffer.read_head] == 13){
keyboard_buffer.read_head = (keyboard_buffer.read_head + 1) % KBD_BUF_SIZE;
keyboard_buffer.count--;
break;
}
// Copy keyboard buffer to final buffer, atomically
buffer[read] = keyboard_buffer.buf[keyboard_buffer.read_head];
keyboard_buffer.count--;
keyboard_buffer.read_head = (keyboard_buffer.read_head + 1) % KBD_BUF_SIZE;
}

// Copy to caller buffer
memcpy(string, buffer, read);
// Add cmd to history
if (running->shell_props != NULL) {
cmd_hist_t* cmd_hist = running->shell_props->cmd_hist;
if (read > 0) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What would happen if the "read" is > 0 but it's not a shell.
For example : Process has shell_props (it's a shell) and calls a function that reads from user (shell built-in function asking for parameters or whatever)

// Clear the buffer cell we are about to write to
for (uint16_t i = 0; i<MAX_COMMAND_LENGTH; i++) {
cmd_hist->buf[cmd_hist->max][i] = '\0';
}
strcpy(cmd_hist->buf[cmd_hist->max], string);
cmd_hist->index = cmd_hist->max;
cmd_hist->count_read = 0;
cmd_hist->max = (cmd_hist->max + 1) % MAX_COMMANDS_HIST;
if (cmd_hist->count < MAX_COMMANDS_HIST) {
cmd_hist->count++;
}
} else {
cmd_hist->index = cmd_hist->max;
cmd_hist->count_read = 0;
}
}

// End of writing phase
writing--;
return read;
}

void cons_write(const char *str, long size) {
if (size < 0){
return;
}
console_putbytes(str, size);
}
27 changes: 25 additions & 2 deletions kernel/kbd.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,13 @@
#define __KBD_H__

#include "stdint.h"
#include "stdio.h"
#include "cpu.h"
#include "mem.h"
#include "string.h"
#include "process.h"
#include "queue.h"
#include "screen.h"

#define KBD_BUF_SIZE 512

Expand All @@ -33,6 +40,8 @@ typedef struct kbd_buf {
uint32_t count;
} kbd_buf;

void init_keyboard_buffer(void);

/* Call this function for each scancode received to translate them to
characters. */
void do_scancode(int scancode);
Expand All @@ -45,16 +54,30 @@ void keyboard_data(char *str);
state of the keyboard driver (do_scancode). */
void kbd_leds(unsigned char leds);

void init_keyboard_buffer(void);

/**
* @brief Changes the echo mode of the console
* @param on: 0 to disable echo, != 0 to enable
*/
void cons_echo(int on);

/**
* @brief Reads from the terminal
* @param string: address to write string to
* @param length: length of the string
* @return the number of characters read
*/
int cons_read(char *string, unsigned long length);

/**
* @brief Sends to the terminal the string of length size at addresse str
* @param str: string to write
* @param size: length of the string
*/
void cons_write(const char *str, long size);

extern kbd_buf keyboard_buffer;
extern int writing;
extern int echo;
extern int echoing;

#endif
52 changes: 1 addition & 51 deletions kernel/primitive.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ int chprio(int pid, int newprio){
queue_del(process, queue_link);
queue_add(process, waiting_queue, process_t, queue_link,priority);
// No scheduler call here, the process will be waken up by the next sender
} else if (process->state == RUNNING){
} else if (process->state == RUNNING) {
scheduler();
}
}
Expand All @@ -47,56 +47,6 @@ int chprio(int pid, int newprio){
return -1;
}

void cons_echo(int on) {
echo = on;
}

int cons_read(char *string, unsigned long length){
if(length <= 0) return 0;
writing++;
long unsigned int read = 0;
char buffer[length];

// If precedent call left a cons_read
if(keyboard_buffer.buf[keyboard_buffer.read_head] == 13){
keyboard_buffer.count--;
keyboard_buffer.read_head = (keyboard_buffer.read_head + 1) % KBD_BUF_SIZE;
return 0;
}

// Lock until 13 char
process_table->running->state = LOCKED_IO;
queue_add(process_table->running, process_table->io_queue, process_t, queue_link, priority);
scheduler();

for(read = 0 ; read < length ; read++){
if(keyboard_buffer.buf[keyboard_buffer.read_head] == 13){
keyboard_buffer.read_head = (keyboard_buffer.read_head + 1) % KBD_BUF_SIZE;
keyboard_buffer.count--;
break;
}
// Copy keyboard buffer to final buffer, atomically
buffer[read] = keyboard_buffer.buf[keyboard_buffer.read_head];
keyboard_buffer.count--;
keyboard_buffer.read_head = (keyboard_buffer.read_head + 1) % KBD_BUF_SIZE;
}

// Copy to caller buffer
memcpy(string, buffer, read);

// End of writing phase
writing--;

return read;
}

void cons_write(const char *str, long size) {
if (size < 0){
return;
}
console_putbytes(str, size);
}

int getpid(void){
return process_table->running->pid;
}
Expand Down
Loading