mirror of
https://github.com/wichtounet/thor-os.git
synced 2025-09-18 09:04:49 -04:00
Merge branch 'master' of github.com:wichtounet/thor-os
This commit is contained in:
commit
fc6df08e76
23
LICENSE
23
LICENSE
@ -0,0 +1,23 @@
|
||||
Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
Permission is hereby granted, free of charge, to any person or organization
|
||||
obtaining a copy of the software and accompanying documentation covered by
|
||||
this license (the "Software") to use, reproduce, display, distribute,
|
||||
execute, and transmit the Software, and to prepare derivative works of the
|
||||
Software, and to permit third-parties to whom the Software is furnished to
|
||||
do so, all subject to the following:
|
||||
|
||||
The copyright notices in the Software and this entire statement, including
|
||||
the above license grant, this restriction and the following disclaimer,
|
||||
must be included in all copies of the Software, in whole or in part, and
|
||||
all derivative works of the Software, unless such copies or derivative
|
||||
works are solely in the form of machine-executable object code generated by
|
||||
a source language processor.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
@ -4,3 +4,7 @@ thor-os
|
||||
Thor is a minimalistic operating system created for learning reasons.
|
||||
|
||||
It is currently a 64bit OS written in assembly and C++.
|
||||
|
||||
## License ##
|
||||
|
||||
This project is distributed under the Boost Software License 1.0. Read `LICENSE_1_0.txt` for details.
|
||||
|
11
add_license.bash
Normal file
11
add_license.bash
Normal file
@ -0,0 +1,11 @@
|
||||
for file in "$@"
|
||||
do
|
||||
lines=`grep "Distributed under the Boost Software License" $file | wc -l`
|
||||
|
||||
if [[ $lines == 0 ]]
|
||||
then
|
||||
cp ${file} ${file}.orig
|
||||
cat license_header ${file}.orig > ${file}
|
||||
rm ${file}.orig
|
||||
fi
|
||||
done
|
@ -1,3 +1,10 @@
|
||||
//=======================================================================
|
||||
// Copyright Baptiste Wicht 2013.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//=======================================================================
|
||||
|
||||
[BITS 16]
|
||||
|
||||
jmp rm_start
|
||||
|
@ -1,3 +1,10 @@
|
||||
//=======================================================================
|
||||
// Copyright Baptiste Wicht 2013.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//=======================================================================
|
||||
|
||||
[BITS 16]
|
||||
|
||||
; Functions
|
||||
|
@ -5,7 +5,7 @@ CPP_FLAGS=-masm=intel -Iinclude/ -nostdlib -O1 -std=c++11 -fno-exceptions -fno-r
|
||||
KERNEL_FLAGS=$(CPP_FLAGS)
|
||||
KERNEL_LINK_FLAGS=-lgcc -T linker.ld $(CPP_FLAGS)
|
||||
|
||||
KERNEL_O_FILES=kernel.o keyboard.o console.o kernel_utils.o timer.o shell.o utils.o memory.o ata.o thor.o
|
||||
KERNEL_O_FILES=kernel.o keyboard.o console.o kernel_utils.o timer.o shell.o utils.o memory.o ata.o thor.o disks.o
|
||||
|
||||
CRTBEGIN_OBJ:=$(shell $(CC) $(CFLAGS) -print-file-name=crtbegin.o)
|
||||
CRTEND_OBJ:=$(shell $(CC) $(CFLAGS) -print-file-name=crtend.o)
|
||||
@ -47,6 +47,9 @@ ata.o: src/ata.cpp
|
||||
thor.o: src/thor.cpp
|
||||
$(CC) $(KERNEL_FLAGS) -c src/thor.cpp -o thor.o
|
||||
|
||||
disks.o: src/disks.cpp
|
||||
$(CC) $(KERNEL_FLAGS) -c src/disks.cpp -o disks.o
|
||||
|
||||
clean:
|
||||
rm -f *.o
|
||||
rm -f *.bin
|
||||
|
136
kernel/include/array.hpp
Normal file
136
kernel/include/array.hpp
Normal file
@ -0,0 +1,136 @@
|
||||
//=======================================================================
|
||||
// Copyright Baptiste Wicht 2013.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//=======================================================================
|
||||
|
||||
#ifndef ARRAY_H
|
||||
#define ARRAY_H
|
||||
|
||||
#include "thor.hpp"
|
||||
|
||||
template<typename T, uint64_t N>
|
||||
class array {
|
||||
private:
|
||||
T data[N];
|
||||
|
||||
public:
|
||||
typedef T value_type;
|
||||
typedef value_type* iterator;
|
||||
typedef const value_type* const_iterator;
|
||||
typedef uint64_t size_type;
|
||||
|
||||
T& operator[](size_type pos){
|
||||
return data[pos];
|
||||
}
|
||||
|
||||
const T& operator[](size_type pos) const {
|
||||
return data[pos];
|
||||
}
|
||||
|
||||
size_type size(){
|
||||
return N;
|
||||
}
|
||||
|
||||
iterator begin(){
|
||||
return iterator(&data[0]);
|
||||
}
|
||||
|
||||
const_iterator begin() const {
|
||||
return const_iterator(&data[0]);
|
||||
}
|
||||
|
||||
iterator end(){
|
||||
return iterator(&data[N]);
|
||||
}
|
||||
|
||||
const_iterator end() const {
|
||||
return const_iterator(&data[N]);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class unique_heap_array {
|
||||
public:
|
||||
typedef T value_type;
|
||||
typedef value_type* pointer_type;
|
||||
typedef value_type* iterator;
|
||||
typedef const value_type* const_iterator;
|
||||
typedef uint64_t size_type;
|
||||
|
||||
private:
|
||||
T* array;
|
||||
uint64_t _size;
|
||||
|
||||
public:
|
||||
unique_heap_array() : array(nullptr), _size(0) {}
|
||||
|
||||
explicit unique_heap_array(T* a, size_type s) : array(a), _size(s) {}
|
||||
explicit unique_heap_array(size_type s) : _size(s) {
|
||||
array = reinterpret_cast<T*>(k_malloc(sizeof(T) * s));
|
||||
}
|
||||
|
||||
unique_heap_array(unique_heap_array&& u) : array(u.release()), _size(u._size) {
|
||||
u._size = 0;
|
||||
}
|
||||
|
||||
unique_heap_array& operator=(unique_heap_array&& u){
|
||||
_size = u._size;
|
||||
reset(u.release());
|
||||
u._size = 0;
|
||||
return *this;
|
||||
}
|
||||
|
||||
~unique_heap_array(){
|
||||
reset();
|
||||
_size = 0;
|
||||
}
|
||||
|
||||
// Disable copy
|
||||
unique_heap_array(const unique_heap_array& rhs) = delete;
|
||||
unique_heap_array& operator=(const unique_heap_array& rhs) = delete;
|
||||
|
||||
size_type size() const {
|
||||
return _size;
|
||||
}
|
||||
|
||||
const T& operator[](size_type pos) const {
|
||||
return array[pos];
|
||||
}
|
||||
|
||||
T& operator[](size_type pos){
|
||||
return array[pos];
|
||||
}
|
||||
|
||||
pointer_type release(){
|
||||
pointer_type p = array;
|
||||
array = nullptr;
|
||||
return p;
|
||||
}
|
||||
|
||||
void reset(pointer_type p = pointer_type()){
|
||||
if(array!= p){
|
||||
k_free(reinterpret_cast<uint64_t*>(array));
|
||||
array= nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
iterator begin(){
|
||||
return iterator(&array[0]);
|
||||
}
|
||||
|
||||
const_iterator begin() const {
|
||||
return const_iterator(&array[0]);
|
||||
}
|
||||
|
||||
iterator end(){
|
||||
return iterator(&array[_size]);
|
||||
}
|
||||
|
||||
const_iterator end() const {
|
||||
return const_iterator(&array[_size]);
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
@ -1,8 +1,17 @@
|
||||
//=======================================================================
|
||||
// Copyright Baptiste Wicht 2013.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//=======================================================================
|
||||
|
||||
#ifndef ATA_H
|
||||
#define ATA_H
|
||||
|
||||
#include "types.hpp"
|
||||
|
||||
namespace ata {
|
||||
|
||||
struct drive_descriptor {
|
||||
uint16_t controller;
|
||||
uint8_t drive;
|
||||
@ -14,6 +23,8 @@ void detect_disks();
|
||||
uint8_t number_of_disks();
|
||||
drive_descriptor& drive(uint8_t disk);
|
||||
|
||||
bool ata_read_sectors(drive_descriptor& drive, uint64_t start, uint8_t count, void* destination);
|
||||
bool read_sectors(drive_descriptor& drive, uint64_t start, uint8_t count, void* destination);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -1,3 +1,10 @@
|
||||
//=======================================================================
|
||||
// Copyright Baptiste Wicht 2013.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//=======================================================================
|
||||
|
||||
#ifndef CONSOLE_H
|
||||
#define CONSOLE_H
|
||||
|
||||
|
61
kernel/include/disks.hpp
Normal file
61
kernel/include/disks.hpp
Normal file
@ -0,0 +1,61 @@
|
||||
//=======================================================================
|
||||
// Copyright Baptiste Wicht 2013.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//=======================================================================
|
||||
|
||||
#ifndef DISKS_H
|
||||
#define DISKS_H
|
||||
|
||||
#include "types.hpp"
|
||||
#include "array.hpp"
|
||||
|
||||
namespace disks {
|
||||
|
||||
enum class disk_type {
|
||||
ATA
|
||||
};
|
||||
|
||||
struct disk_descriptor {
|
||||
uint64_t uuid;
|
||||
disk_type type;
|
||||
void* descriptor;
|
||||
};
|
||||
|
||||
enum class partition_type {
|
||||
FAT32,
|
||||
UNKNOWN
|
||||
};
|
||||
|
||||
struct partition_descriptor {
|
||||
uint64_t uuid;
|
||||
partition_type type;
|
||||
uint64_t start;
|
||||
uint64_t sectors;
|
||||
};
|
||||
|
||||
void detect_disks();
|
||||
|
||||
uint64_t detected_disks();
|
||||
|
||||
bool disk_exists(uint64_t uuid);
|
||||
|
||||
const disk_descriptor& disk_by_index(uint64_t index);
|
||||
const disk_descriptor& disk_by_uuid(uint64_t uuid);
|
||||
|
||||
const char* disk_type_to_string(disk_type type);
|
||||
const char* partition_type_to_string(partition_type type);
|
||||
|
||||
bool read_sectors(const disk_descriptor& disk, uint64_t start, uint8_t count, void* destination);
|
||||
unique_heap_array<partition_descriptor> partitions(const disk_descriptor& disk);
|
||||
bool partition_exists(const disk_descriptor& disk, uint64_t uuid);
|
||||
|
||||
void mount(const disk_descriptor& disk, uint64_t uuid);
|
||||
|
||||
const disk_descriptor* mounted_disk();
|
||||
const partition_descriptor* mounted_partition();
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -1,3 +1,10 @@
|
||||
//=======================================================================
|
||||
// Copyright Baptiste Wicht 2013.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//=======================================================================
|
||||
|
||||
#ifndef KERNEL_UTILS_H
|
||||
#define KERNEL_UTILS_H
|
||||
|
||||
|
@ -1,8 +1,24 @@
|
||||
//=======================================================================
|
||||
// Copyright Baptiste Wicht 2013.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//=======================================================================
|
||||
|
||||
#ifndef KEYBOARD_H
|
||||
#define KEYBOARD_H
|
||||
|
||||
#include "types.hpp"
|
||||
|
||||
namespace keyboard {
|
||||
|
||||
const char KEY_ENTER = 0x1C;
|
||||
const char KEY_BACKSPACE = 0x0E;
|
||||
|
||||
void install_driver();
|
||||
char get_char();
|
||||
char key_to_ascii(uint8_t key);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -1,3 +1,10 @@
|
||||
//=======================================================================
|
||||
// Copyright Baptiste Wicht 2013.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//=======================================================================
|
||||
|
||||
#ifndef MEMORY_H
|
||||
#define MEMORY_H
|
||||
|
||||
|
@ -1,3 +1,10 @@
|
||||
//=======================================================================
|
||||
// Copyright Baptiste Wicht 2013.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//=======================================================================
|
||||
|
||||
#ifndef SHELL_H
|
||||
#define SHELL_
|
||||
|
||||
|
@ -1,3 +1,10 @@
|
||||
//=======================================================================
|
||||
// Copyright Baptiste Wicht 2013.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//=======================================================================
|
||||
|
||||
#ifndef THOR_H
|
||||
#define THOR_H
|
||||
|
||||
|
@ -1,3 +1,10 @@
|
||||
//=======================================================================
|
||||
// Copyright Baptiste Wicht 2013.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//=======================================================================
|
||||
|
||||
#ifndef TIMER_H
|
||||
#define TIMER_H
|
||||
|
||||
|
@ -1,3 +1,10 @@
|
||||
//=======================================================================
|
||||
// Copyright Baptiste Wicht 2013.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//=======================================================================
|
||||
|
||||
#ifndef TYPES_H
|
||||
#define TYPES_H
|
||||
|
||||
|
67
kernel/include/unique_ptr.hpp
Normal file
67
kernel/include/unique_ptr.hpp
Normal file
@ -0,0 +1,67 @@
|
||||
//=======================================================================
|
||||
// Copyright Baptiste Wicht 2013.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//=======================================================================
|
||||
|
||||
#ifndef UNIQUE_PTR_H
|
||||
#define UNIQUE_PTR_H
|
||||
|
||||
#include "thor.hpp"
|
||||
|
||||
template <typename T>
|
||||
class unique_ptr {
|
||||
public:
|
||||
typedef T* pointer_type;
|
||||
typedef T element_type;
|
||||
|
||||
private:
|
||||
pointer_type pointer;
|
||||
|
||||
public:
|
||||
explicit unique_ptr(pointer_type p) : pointer(p){}
|
||||
|
||||
unique_ptr() : pointer(pointer_type()) {}
|
||||
|
||||
unique_ptr(unique_ptr&& u) : pointer(u.release()) {}
|
||||
unique_ptr& operator=(unique_ptr&& u){
|
||||
reset(u.release());
|
||||
return *this;
|
||||
}
|
||||
|
||||
~unique_ptr(){
|
||||
reset();
|
||||
}
|
||||
|
||||
// Disable copy
|
||||
unique_ptr(const unique_ptr& rhs) = delete;
|
||||
unique_ptr& operator=(const unique_ptr& rhs) = delete;
|
||||
|
||||
element_type& operator*() const {
|
||||
return *get();
|
||||
}
|
||||
|
||||
pointer_type operator->() const {
|
||||
return get();
|
||||
}
|
||||
|
||||
pointer_type get() const {
|
||||
return pointer;
|
||||
}
|
||||
|
||||
pointer_type release(){
|
||||
pointer_type p = pointer;
|
||||
pointer = nullptr;
|
||||
return p;
|
||||
}
|
||||
|
||||
void reset(pointer_type p = pointer_type()){
|
||||
if(pointer != p){
|
||||
k_free(reinterpret_cast<uint64_t*>(pointer));
|
||||
pointer = nullptr;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
@ -1,9 +1,17 @@
|
||||
//=======================================================================
|
||||
// Copyright Baptiste Wicht 2013.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//=======================================================================
|
||||
|
||||
#ifndef UTILS_H
|
||||
#define UTILS_H
|
||||
|
||||
#include "types.hpp"
|
||||
|
||||
uint64_t parse(const char* str);
|
||||
uint64_t parse(const char* str, const char* end);
|
||||
|
||||
bool str_equals(const char* a, const char* b);
|
||||
bool str_contains(const char* a, char c);
|
||||
|
@ -1,3 +1,10 @@
|
||||
//=======================================================================
|
||||
// Copyright Baptiste Wicht 2013.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//=======================================================================
|
||||
|
||||
#include "ata.hpp"
|
||||
#include "kernel_utils.hpp"
|
||||
#include "timer.hpp"
|
||||
@ -37,8 +44,7 @@ namespace {
|
||||
#define MASTER_BIT 0
|
||||
#define SLAVE_BIT 1
|
||||
|
||||
bool detected = false;
|
||||
drive_descriptor* drives;
|
||||
ata::drive_descriptor* drives;
|
||||
|
||||
volatile bool primary_invoked = false;
|
||||
volatile bool secondary_invoked = false;
|
||||
@ -88,7 +94,7 @@ static uint8_t wait_for_controller(uint16_t controller, uint8_t mask, uint8_t va
|
||||
return timeout;
|
||||
}
|
||||
|
||||
bool select_device(drive_descriptor& drive){
|
||||
bool select_device(ata::drive_descriptor& drive){
|
||||
auto controller = drive.controller;
|
||||
|
||||
if(in_byte(controller + ATA_STATUS) & (ATA_STATUS_BSY | ATA_STATUS_DRQ)){
|
||||
@ -107,47 +113,35 @@ bool select_device(drive_descriptor& drive){
|
||||
|
||||
} //end of anonymous namespace
|
||||
|
||||
void detect_disks(){
|
||||
if(!detected){
|
||||
drives = reinterpret_cast<drive_descriptor*>(k_malloc(4 * sizeof(drive_descriptor)));
|
||||
void ata::detect_disks(){
|
||||
drives = reinterpret_cast<drive_descriptor*>(k_malloc(4 * sizeof(drive_descriptor)));
|
||||
|
||||
drives[0] = {ATA_PRIMARY, 0xE0, false, MASTER_BIT};
|
||||
drives[1] = {ATA_PRIMARY, 0xF0, false, SLAVE_BIT};
|
||||
drives[2] = {ATA_SECONDARY, 0xE0, false, MASTER_BIT};
|
||||
drives[3] = {ATA_SECONDARY, 0xF0, false, SLAVE_BIT};
|
||||
drives[0] = {ATA_PRIMARY, 0xE0, false, MASTER_BIT};
|
||||
drives[1] = {ATA_PRIMARY, 0xF0, false, SLAVE_BIT};
|
||||
drives[2] = {ATA_SECONDARY, 0xE0, false, MASTER_BIT};
|
||||
drives[3] = {ATA_SECONDARY, 0xF0, false, SLAVE_BIT};
|
||||
|
||||
for(uint8_t i = 0; i < 4; ++i){
|
||||
auto& drive = drives[i];
|
||||
for(uint8_t i = 0; i < 4; ++i){
|
||||
auto& drive = drives[i];
|
||||
|
||||
out_byte(drive.controller + 0x6, drive.drive);
|
||||
sleep_ms(4);
|
||||
drive.present = in_byte(drive.controller + 0x7) & 0x40;
|
||||
}
|
||||
|
||||
register_irq_handler<14>(primary_controller_handler);
|
||||
register_irq_handler<15>(secondary_controller_handler);
|
||||
|
||||
detected = true;
|
||||
out_byte(drive.controller + 0x6, drive.drive);
|
||||
sleep_ms(4);
|
||||
drive.present = in_byte(drive.controller + 0x7) & 0x40;
|
||||
}
|
||||
|
||||
register_irq_handler<14>(primary_controller_handler);
|
||||
register_irq_handler<15>(secondary_controller_handler);
|
||||
}
|
||||
|
||||
uint8_t number_of_disks(){
|
||||
if(!detected){
|
||||
detect_disks();
|
||||
}
|
||||
|
||||
uint8_t ata::number_of_disks(){
|
||||
return 4;
|
||||
}
|
||||
|
||||
drive_descriptor& drive(uint8_t disk){
|
||||
if(!detected){
|
||||
detect_disks();
|
||||
}
|
||||
|
||||
ata::drive_descriptor& ata::drive(uint8_t disk){
|
||||
return drives[disk];
|
||||
}
|
||||
|
||||
bool ata_read_sectors(drive_descriptor& drive, uint64_t start, uint8_t count, void* destination){
|
||||
bool ata::read_sectors(drive_descriptor& drive, uint64_t start, uint8_t count, void* destination){
|
||||
//Select the device
|
||||
if(!select_device(drive)){
|
||||
return false;
|
||||
|
@ -1,3 +1,10 @@
|
||||
//=======================================================================
|
||||
// Copyright Baptiste Wicht 2013.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//=======================================================================
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "console.hpp"
|
||||
|
200
kernel/src/disks.cpp
Normal file
200
kernel/src/disks.cpp
Normal file
@ -0,0 +1,200 @@
|
||||
//=======================================================================
|
||||
// Copyright Baptiste Wicht 2013.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//=======================================================================
|
||||
|
||||
#include "disks.hpp"
|
||||
#include "ata.hpp"
|
||||
#include "thor.hpp"
|
||||
#include "console.hpp"
|
||||
|
||||
#include "unique_ptr.hpp"
|
||||
#include "array.hpp"
|
||||
|
||||
namespace {
|
||||
|
||||
//For now, 4 is enough as only the ata driver is implemented
|
||||
array<disks::disk_descriptor, 4> _disks;
|
||||
|
||||
uint64_t number_of_disks = 0;
|
||||
|
||||
struct partition_descriptor_t {
|
||||
uint8_t boot_flag;
|
||||
uint8_t chs_begin[3];
|
||||
uint8_t type_code;
|
||||
uint8_t chs_end[3];
|
||||
uint32_t lba_begin;
|
||||
uint32_t sectors;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
static_assert(sizeof(partition_descriptor_t) == 16, "A partition descriptor is 16 bytes long");
|
||||
|
||||
struct boot_record_t {
|
||||
uint8_t boot_code[446];
|
||||
partition_descriptor_t partitions[4];
|
||||
uint16_t signature;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
static_assert(sizeof(boot_record_t) == 512, "The boot record is 512 bytes long");
|
||||
|
||||
const disks::disk_descriptor* _mounted_disk;
|
||||
const disks::partition_descriptor* _mounted_partition;
|
||||
|
||||
} //end of anonymous namespace
|
||||
|
||||
void disks::detect_disks(){
|
||||
ata::detect_disks();
|
||||
|
||||
for(uint8_t i = 0; i < ata::number_of_disks(); ++i){
|
||||
auto& descriptor = ata::drive(i);
|
||||
|
||||
if(descriptor.present){
|
||||
_disks[number_of_disks] = {number_of_disks, disks::disk_type::ATA, &descriptor};
|
||||
++number_of_disks;
|
||||
}
|
||||
}
|
||||
|
||||
_mounted_disk = nullptr;
|
||||
_mounted_partition = nullptr;
|
||||
}
|
||||
|
||||
uint64_t disks::detected_disks(){
|
||||
return number_of_disks;
|
||||
}
|
||||
|
||||
const disks::disk_descriptor& disks::disk_by_index(uint64_t index){
|
||||
return _disks[index];
|
||||
}
|
||||
|
||||
const disks::disk_descriptor& disks::disk_by_uuid(uint64_t uuid){
|
||||
for(uint64_t i = 0; i < number_of_disks; ++i){
|
||||
if(_disks[i].uuid == uuid){
|
||||
return _disks[i];
|
||||
}
|
||||
}
|
||||
|
||||
//Unreachable
|
||||
}
|
||||
|
||||
bool disks::disk_exists(uint64_t uuid){
|
||||
for(uint64_t i = 0; i < number_of_disks; ++i){
|
||||
if(_disks[i].uuid == uuid){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
const char* disks::disk_type_to_string(disk_type type){
|
||||
switch(type){
|
||||
case disk_type::ATA:
|
||||
return "ATA";
|
||||
default:
|
||||
return "Invalid Type";
|
||||
}
|
||||
}
|
||||
|
||||
const char* disks::partition_type_to_string(partition_type type){
|
||||
switch(type){
|
||||
case partition_type::FAT32:
|
||||
return "FAT32";
|
||||
case partition_type::UNKNOWN:
|
||||
return "Unknown";
|
||||
default:
|
||||
return "Invalid Type";
|
||||
}
|
||||
}
|
||||
|
||||
bool disks::read_sectors(const disk_descriptor& disk, uint64_t start, uint8_t count, void* destination){
|
||||
switch(disk.type){
|
||||
case disk_type::ATA:
|
||||
return ata::read_sectors(*static_cast<ata::drive_descriptor*>(disk.descriptor), start, count, destination);
|
||||
|
||||
default:
|
||||
k_print_line("BOOH");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
unique_heap_array<disks::partition_descriptor> disks::partitions(const disk_descriptor& disk){
|
||||
unique_ptr<uint64_t> buffer(k_malloc(512));
|
||||
|
||||
if(!read_sectors(disk, 0, 1, buffer.get())){
|
||||
k_print_line("Read Boot Record failed");
|
||||
|
||||
return {};
|
||||
} else {
|
||||
auto* boot_record = reinterpret_cast<boot_record_t*>(buffer.get());
|
||||
|
||||
if(boot_record->signature != 0xAA55){
|
||||
k_print_line("Invalid boot record signature");
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
uint64_t n = 0;
|
||||
for(int i = 0; i < 4; ++i){
|
||||
if(boot_record->partitions[i].type_code > 0){
|
||||
++n;
|
||||
}
|
||||
}
|
||||
|
||||
unique_heap_array<partition_descriptor> partitions(n);
|
||||
uint64_t p = 0;
|
||||
|
||||
for(uint64_t i = 0; i < 4; ++i){
|
||||
if(boot_record->partitions[i].type_code > 0){
|
||||
partition_type type;
|
||||
if(boot_record->partitions[i].type_code == 0x0B || boot_record->partitions[i].type_code == 0x0C){
|
||||
type = partition_type::FAT32;
|
||||
} else {
|
||||
type = partition_type::UNKNOWN;
|
||||
}
|
||||
|
||||
partitions[p] = {p, type, boot_record->partitions[i].lba_begin, boot_record->partitions[i].sectors};
|
||||
|
||||
++p;
|
||||
}
|
||||
}
|
||||
|
||||
return partitions;
|
||||
}
|
||||
}
|
||||
|
||||
bool disks::partition_exists(const disk_descriptor& disk, uint64_t uuid){
|
||||
for(auto& partition : partitions(disk)){
|
||||
if(partition.uuid == uuid){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void disks::mount(const disk_descriptor& disk, uint64_t uuid){
|
||||
_mounted_disk = &disk;
|
||||
|
||||
if(_mounted_partition){
|
||||
delete _mounted_partition;
|
||||
}
|
||||
|
||||
for(auto& partition : partitions(disk)){
|
||||
if(partition.uuid == uuid){
|
||||
auto p = new partition_descriptor();
|
||||
*p = partition;
|
||||
_mounted_partition = p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const disks::disk_descriptor* disks::mounted_disk(){
|
||||
return _mounted_disk;
|
||||
}
|
||||
|
||||
const disks::partition_descriptor* disks::mounted_partition(){
|
||||
return _mounted_partition;
|
||||
}
|
@ -1,6 +1,15 @@
|
||||
//=======================================================================
|
||||
// Copyright Baptiste Wicht 2013.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//=======================================================================
|
||||
|
||||
#include "memory.hpp"
|
||||
#include "timer.hpp"
|
||||
#include "shell.hpp"
|
||||
#include "keyboard.hpp"
|
||||
#include "disks.hpp"
|
||||
|
||||
extern "C" {
|
||||
|
||||
@ -8,6 +17,8 @@ void __attribute__ ((section ("main_section"))) kernel_main(){
|
||||
load_memory_map();
|
||||
init_memory_manager();
|
||||
install_timer();
|
||||
keyboard::install_driver();
|
||||
disks::detect_disks();
|
||||
init_shell();
|
||||
|
||||
return;
|
||||
|
@ -1,21 +1,40 @@
|
||||
//=======================================================================
|
||||
// Copyright Baptiste Wicht 2013.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//=======================================================================
|
||||
|
||||
#include "kernel_utils.hpp"
|
||||
|
||||
uint8_t in_byte(uint16_t _port){
|
||||
uint8_t rv;
|
||||
__asm__ __volatile__ ("in %0, %1" : "=a" (rv) : "dN" (_port));
|
||||
return rv;
|
||||
}
|
||||
|
||||
void out_byte (uint16_t _port, uint8_t _data){
|
||||
__asm__ __volatile__ ("out %0, %1" : : "dN" (_port), "a" (_data));
|
||||
__asm__ __volatile__ ("in %[data], %[port]"
|
||||
: [data] "=a" (rv)
|
||||
: [port] "dN" (_port));
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
uint16_t in_word(uint16_t _port){
|
||||
uint16_t rv;
|
||||
__asm__ __volatile__ ("in %0, %1" : "=a" (rv) : "dN" (_port));
|
||||
|
||||
__asm__ __volatile__ ("in %[data], %[port]"
|
||||
: [data] "=a" (rv)
|
||||
: [port] "dN" (_port));
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
void out_word(uint16_t _port, uint16_t _data){
|
||||
__asm__ __volatile__ ("out %0, %1" : : "dN" (_port), "a" (_data));
|
||||
void out_byte (uint16_t _port, uint8_t _data){
|
||||
__asm__ __volatile__ ("out %[port], %[data]"
|
||||
: /* No outputs */
|
||||
: [port] "dN" (_port), [data] "a" (_data));
|
||||
}
|
||||
|
||||
void out_word(uint16_t _port, uint16_t _data){
|
||||
__asm__ __volatile__ ("out %[port], %[data]"
|
||||
: /* No outputs */
|
||||
: [port] "dN" (_port), [data] "a" (_data));
|
||||
}
|
||||
|
@ -1,4 +1,12 @@
|
||||
//=======================================================================
|
||||
// Copyright Baptiste Wicht 2013.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//=======================================================================
|
||||
|
||||
#include "keyboard.hpp"
|
||||
#include "kernel_utils.hpp"
|
||||
|
||||
namespace {
|
||||
|
||||
@ -42,8 +50,50 @@ char qwertz[128] =
|
||||
0, /* All other keys are undefined */
|
||||
};
|
||||
|
||||
const uint8_t BUFFER_SIZE = 64;
|
||||
|
||||
char input_buffer[BUFFER_SIZE];
|
||||
volatile uint8_t start;
|
||||
volatile uint8_t count;
|
||||
|
||||
void keyboard_handler(){
|
||||
auto key = static_cast<char>(in_byte(0x60));
|
||||
|
||||
if(count == BUFFER_SIZE){
|
||||
//The buffer is full, we loose the characters
|
||||
} else {
|
||||
auto end = (start + count) % BUFFER_SIZE;
|
||||
input_buffer[end] = key;
|
||||
++count;
|
||||
}
|
||||
}
|
||||
|
||||
char key_to_ascii(uint8_t key){
|
||||
}
|
||||
|
||||
void keyboard::install_driver(){
|
||||
register_irq_handler<1>(keyboard_handler);
|
||||
|
||||
start = 0;
|
||||
count = 0;
|
||||
}
|
||||
|
||||
char keyboard::get_char(){
|
||||
//Wait for the buffer to contains something
|
||||
while(count == 0){
|
||||
__asm__ __volatile__ ("nop");
|
||||
__asm__ __volatile__ ("nop");
|
||||
__asm__ __volatile__ ("nop");
|
||||
__asm__ __volatile__ ("nop");
|
||||
__asm__ __volatile__ ("nop");
|
||||
}
|
||||
|
||||
auto key = input_buffer[start];
|
||||
start = (start + 1) % BUFFER_SIZE;
|
||||
--count;
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
char keyboard::key_to_ascii(uint8_t key){
|
||||
return qwertz[key];
|
||||
}
|
||||
|
@ -1,7 +1,19 @@
|
||||
//=======================================================================
|
||||
// Copyright Baptiste Wicht 2013.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//=======================================================================
|
||||
|
||||
#include "memory.hpp"
|
||||
#include "console.hpp"
|
||||
|
||||
namespace {
|
||||
|
||||
//Used to compile with malloc operations in the console
|
||||
//can produce a lot of output
|
||||
const bool DEBUG_MALLOC = false;
|
||||
|
||||
struct bios_mmap_entry {
|
||||
uint32_t base_low;
|
||||
uint32_t base_high;
|
||||
@ -20,7 +32,12 @@ mmapentry e820_mmap[32];
|
||||
|
||||
void mmap_query(uint64_t cmd, uint64_t* result){
|
||||
uint64_t tmp;
|
||||
__asm__ __volatile__ ("mov r8, %0; int 62; mov %1, rax" : : "dN" (cmd), "a" (tmp));
|
||||
|
||||
__asm__ __volatile__ ("mov r8, %[port]; int 62; mov %[dst], rax"
|
||||
: [dst] "=a" (tmp)
|
||||
: [port] "dN" (cmd)
|
||||
: "cc", "memory", "r8");
|
||||
|
||||
*result = tmp;
|
||||
}
|
||||
|
||||
@ -104,6 +121,35 @@ uint64_t* allocate_block(uint64_t blocks){
|
||||
return block;
|
||||
}
|
||||
|
||||
template<bool Debug>
|
||||
void debug_malloc(const char* point = nullptr){
|
||||
if(Debug){
|
||||
if(point){
|
||||
k_print_line(point);
|
||||
}
|
||||
|
||||
auto it = malloc_head;
|
||||
|
||||
k_print("next: ");
|
||||
do {
|
||||
k_printf("%h -> ", reinterpret_cast<uint64_t>(it));
|
||||
it = it->next;
|
||||
} while(it != malloc_head);
|
||||
|
||||
k_printf("%h\n", malloc_head);
|
||||
|
||||
it = malloc_head;
|
||||
|
||||
k_print("prev: ");
|
||||
do {
|
||||
k_printf("%h <- ", reinterpret_cast<uint64_t>(it));
|
||||
it = it->prev;
|
||||
} while(it != malloc_head);
|
||||
|
||||
k_printf("%h\n", malloc_head);
|
||||
}
|
||||
}
|
||||
|
||||
} //end of anonymous namespace
|
||||
|
||||
void init_memory_manager(){
|
||||
@ -141,12 +187,12 @@ uint64_t* k_malloc(uint64_t bytes){
|
||||
auto header = reinterpret_cast<malloc_header_chunk*>(block);
|
||||
header->size = MIN_BLOCKS * BLOCK_SIZE - META_SIZE;
|
||||
|
||||
header->next = current->next;
|
||||
header->prev = current;
|
||||
|
||||
current->next->prev = header;
|
||||
current->next = header;
|
||||
|
||||
header->next = current->next;
|
||||
header->prev = current;
|
||||
|
||||
auto footer = reinterpret_cast<malloc_footer_chunk*>(
|
||||
reinterpret_cast<uintptr_t>(block) + header->size + sizeof(malloc_header_chunk));
|
||||
footer->size = header->size;
|
||||
@ -154,7 +200,7 @@ uint64_t* k_malloc(uint64_t bytes){
|
||||
//This block is big enough
|
||||
|
||||
//Is it worth splitting the block ?
|
||||
if(current->size - bytes - META_SIZE > MIN_SPLIT){
|
||||
if(current->size > bytes + META_SIZE + MIN_SPLIT){
|
||||
auto new_block_size = current->size - bytes - META_SIZE;
|
||||
|
||||
//Set the new size;
|
||||
@ -177,12 +223,16 @@ uint64_t* k_malloc(uint64_t bytes){
|
||||
reinterpret_cast<uintptr_t>(new_block) + new_block_size + sizeof(malloc_header_chunk));
|
||||
new_footer->size = new_block_size;
|
||||
|
||||
debug_malloc<DEBUG_MALLOC>("after malloc split");
|
||||
|
||||
break;
|
||||
} else {
|
||||
//Remove this node from the free list
|
||||
current->prev->next = current->next;
|
||||
current->next->prev = current->prev;
|
||||
|
||||
debug_malloc<DEBUG_MALLOC>("after malloc no split");
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -213,6 +263,8 @@ void k_free(uint64_t* block){
|
||||
|
||||
header->next->prev = free_header;
|
||||
header->next = free_header;
|
||||
|
||||
debug_malloc<DEBUG_MALLOC>("after free");
|
||||
}
|
||||
|
||||
void load_memory_map(){
|
||||
|
@ -1,3 +1,10 @@
|
||||
//=======================================================================
|
||||
// Copyright Baptiste Wicht 2013.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//=======================================================================
|
||||
|
||||
#include "types.hpp"
|
||||
#include "keyboard.hpp"
|
||||
#include "kernel_utils.hpp"
|
||||
@ -6,7 +13,7 @@
|
||||
#include "timer.hpp"
|
||||
#include "utils.hpp"
|
||||
#include "memory.hpp"
|
||||
#include "ata.hpp"
|
||||
#include "disks.hpp"
|
||||
|
||||
namespace {
|
||||
|
||||
@ -22,13 +29,16 @@ void echo_command(const char* params);
|
||||
void mmap_command(const char* params);
|
||||
void memory_command(const char* params);
|
||||
void disks_command(const char* params);
|
||||
void partitions_command(const char* params);
|
||||
void mount_command(const char* params);
|
||||
void ls_command(const char* params);
|
||||
|
||||
struct command_definition {
|
||||
const char* name;
|
||||
void (*function)(const char*);
|
||||
};
|
||||
|
||||
command_definition commands[10] = {
|
||||
command_definition commands[13] = {
|
||||
{"reboot", reboot_command},
|
||||
{"help", help_command},
|
||||
{"uptime", uptime_command},
|
||||
@ -39,6 +49,9 @@ command_definition commands[10] = {
|
||||
{"mmap", mmap_command},
|
||||
{"memory", memory_command},
|
||||
{"disks", disks_command},
|
||||
{"partitions", partitions_command},
|
||||
{"mount", mount_command},
|
||||
{"ls", ls_command},
|
||||
};
|
||||
|
||||
uint64_t current_input_length = 0;
|
||||
@ -46,45 +59,44 @@ char current_input[50];
|
||||
|
||||
void exec_command();
|
||||
|
||||
#define KEY_ENTER 0x1C
|
||||
#define KEY_BACKSPACE 0x0E
|
||||
void start_shell(){
|
||||
while(true){
|
||||
auto key = keyboard::get_char();
|
||||
|
||||
void keyboard_handler(){
|
||||
uint8_t key = in_byte(0x60);
|
||||
|
||||
if(key & 0x80){
|
||||
//TODO Handle shift
|
||||
} else {
|
||||
if(key == KEY_ENTER){
|
||||
current_input[current_input_length] = '\0';
|
||||
|
||||
k_print_line();
|
||||
|
||||
exec_command();
|
||||
|
||||
if(get_column() != 0){
|
||||
set_column(0);
|
||||
set_line(get_line() + 1);
|
||||
}
|
||||
|
||||
current_input_length = 0;
|
||||
|
||||
k_print("thor> ");
|
||||
} else if(key == KEY_BACKSPACE){
|
||||
if(current_input_length > 0){
|
||||
set_column(get_column() - 1);
|
||||
k_print(' ');
|
||||
set_column(get_column() - 1);
|
||||
|
||||
--current_input_length;
|
||||
}
|
||||
if(key & 0x80){
|
||||
//TODO Handle shift
|
||||
} else {
|
||||
auto qwertz_key = key_to_ascii(key);
|
||||
if(key == keyboard::KEY_ENTER){
|
||||
current_input[current_input_length] = '\0';
|
||||
|
||||
if(qwertz_key > 0){
|
||||
current_input[current_input_length++] = qwertz_key;
|
||||
k_print(qwertz_key);
|
||||
}
|
||||
k_print_line();
|
||||
|
||||
exec_command();
|
||||
|
||||
if(get_column() != 0){
|
||||
set_column(0);
|
||||
set_line(get_line() + 1);
|
||||
}
|
||||
|
||||
current_input_length = 0;
|
||||
|
||||
k_print("thor> ");
|
||||
} else if(key == keyboard::KEY_BACKSPACE){
|
||||
if(current_input_length > 0){
|
||||
set_column(get_column() - 1);
|
||||
k_print(' ');
|
||||
set_column(get_column() - 1);
|
||||
|
||||
--current_input_length;
|
||||
}
|
||||
} else {
|
||||
auto qwertz_key = keyboard::key_to_ascii(key);
|
||||
|
||||
if(qwertz_key > 0){
|
||||
current_input[current_input_length++] = qwertz_key;
|
||||
k_print(qwertz_key);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -256,32 +268,79 @@ void memory_command(const char*){
|
||||
k_printf("Total used memory: %m\n", used_memory());
|
||||
k_printf("Total free memory: %m\n", free_memory());
|
||||
}
|
||||
|
||||
uint16_t* buffer = reinterpret_cast<uint16_t*>(k_malloc(512));
|
||||
|
||||
if(!ata_read_sectors(drive(0), 2048, 1, buffer)){
|
||||
k_print_line("Read failed");
|
||||
} else {
|
||||
for(int i = 0; i < 80; i += 8){
|
||||
k_printf("%.4h %.4h %.4h %.4h %.4h %.4h %.4h %.4h\n",
|
||||
(uint64_t) buffer[i+0], (uint64_t) buffer[i+1], (uint64_t) buffer[i+2], (uint64_t) buffer[i+3],
|
||||
(uint64_t) buffer[i+4], (uint64_t) buffer[i+5], (uint64_t) buffer[i+6], (uint64_t) buffer[i+7]);
|
||||
}
|
||||
|
||||
k_free(reinterpret_cast<uint64_t*>(buffer));
|
||||
}
|
||||
}
|
||||
|
||||
void disks_command(const char*){
|
||||
k_print_line("Controller Drive Present");
|
||||
k_print_line("UUID Type");
|
||||
|
||||
for(uint64_t i = 0; i < number_of_disks(); ++i){
|
||||
auto& descriptor = drive(i);
|
||||
for(uint64_t i = 0; i < disks::detected_disks(); ++i){
|
||||
auto& descriptor = disks::disk_by_index(i);
|
||||
|
||||
k_printf("%12h %8h %s\n", descriptor.controller, descriptor.drive, descriptor.present ? "Yes" : "No");
|
||||
k_printf("%10d %s\n", descriptor.uuid, disks::disk_type_to_string(descriptor.type));
|
||||
}
|
||||
}
|
||||
|
||||
void partitions_command(const char* params){
|
||||
const char* delay_str = params + 11;
|
||||
|
||||
auto uuid = parse(delay_str);
|
||||
|
||||
if(disks::disk_exists(uuid)){
|
||||
auto partitions = disks::partitions(disks::disk_by_uuid(uuid));
|
||||
|
||||
if(partitions.size() > 0){
|
||||
k_print_line("UUID Type Start Sectors");
|
||||
|
||||
for(auto& partition : partitions){
|
||||
k_printf("%10d %12s %10d %d\n", partition.uuid,
|
||||
disks::partition_type_to_string(partition.type),
|
||||
partition.start, partition.sectors);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
k_printf("Disks %d does not exist\n", uuid);
|
||||
}
|
||||
}
|
||||
|
||||
void mount_command(const char* params){
|
||||
if(!*(params+5)){
|
||||
auto md = disks::mounted_disk();
|
||||
auto mp = disks::mounted_partition();
|
||||
|
||||
if(md && mp){
|
||||
k_printf("%d:%d is mounted\n", md->uuid, mp->uuid);
|
||||
} else {
|
||||
k_print_line("Nothing is mounted");
|
||||
}
|
||||
} else {
|
||||
const char* it = params + 6;
|
||||
const char* it_end = it;
|
||||
|
||||
while(*it_end != ' '){
|
||||
++it_end;
|
||||
}
|
||||
|
||||
auto disk_uuid = parse(it, it_end);
|
||||
auto partition_uuid = parse(it_end + 1);
|
||||
|
||||
if(disks::disk_exists(disk_uuid)){
|
||||
auto& disk = disks::disk_by_uuid(disk_uuid);
|
||||
if(disks::partition_exists(disk, partition_uuid)){
|
||||
disks::mount(disk, partition_uuid);
|
||||
} else {
|
||||
k_printf("Partition %d does not exist\n", partition_uuid);
|
||||
}
|
||||
} else {
|
||||
k_printf("Disk %d does not exist\n", disk_uuid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ls_command(const char*){
|
||||
//TODO Implement mount first
|
||||
//TODO Implement ls
|
||||
}
|
||||
|
||||
} //end of anonymous namespace
|
||||
|
||||
void init_shell(){
|
||||
@ -291,5 +350,5 @@ void init_shell(){
|
||||
|
||||
k_print("thor> ");
|
||||
|
||||
register_irq_handler<1>(keyboard_handler);
|
||||
start_shell();
|
||||
}
|
||||
|
@ -1,3 +1,10 @@
|
||||
//=======================================================================
|
||||
// Copyright Baptiste Wicht 2013.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//=======================================================================
|
||||
|
||||
#include "thor.hpp"
|
||||
#include "memory.hpp"
|
||||
|
||||
|
@ -1,3 +1,10 @@
|
||||
//=======================================================================
|
||||
// Copyright Baptiste Wicht 2013.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//=======================================================================
|
||||
|
||||
#include "timer.hpp"
|
||||
|
||||
#include "kernel_utils.hpp"
|
||||
|
@ -1,3 +1,10 @@
|
||||
//=======================================================================
|
||||
// Copyright Baptiste Wicht 2013.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//=======================================================================
|
||||
|
||||
#include "utils.hpp"
|
||||
|
||||
bool str_equals(const char* a, const char* b){
|
||||
@ -9,6 +16,20 @@ bool str_equals(const char* a, const char* b){
|
||||
return *a == *b;
|
||||
}
|
||||
|
||||
uint64_t parse(const char* it, const char* end){
|
||||
int i = end - it - 1;
|
||||
|
||||
uint64_t factor = 1;
|
||||
uint64_t acc = 0;
|
||||
|
||||
for(; i >= 0; --i){
|
||||
acc += (it[i] - '0') * factor;
|
||||
factor *= 10;
|
||||
}
|
||||
|
||||
return acc;
|
||||
}
|
||||
|
||||
uint64_t parse(const char* str){
|
||||
int i = 0;
|
||||
|
||||
|
7
license_header
Normal file
7
license_header
Normal file
@ -0,0 +1,7 @@
|
||||
//=======================================================================
|
||||
// Copyright Baptiste Wicht 2013.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//=======================================================================
|
||||
|
@ -1,3 +1,10 @@
|
||||
//=======================================================================
|
||||
// Copyright Baptiste Wicht 2013.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//=======================================================================
|
||||
|
||||
|
||||
; Variables
|
||||
|
||||
@ -122,24 +129,28 @@ _irq%1:
|
||||
test rax, rax
|
||||
je .eoi
|
||||
|
||||
push rbx
|
||||
push rax
|
||||
push rcx
|
||||
push rdx
|
||||
push rsi
|
||||
push rdi
|
||||
push r8
|
||||
push r9
|
||||
push r10
|
||||
push r11
|
||||
|
||||
; Call the handler
|
||||
call rax
|
||||
|
||||
push r9
|
||||
push r8
|
||||
pop r11
|
||||
pop r10
|
||||
pop r9
|
||||
pop r8
|
||||
pop rdi
|
||||
pop rsi
|
||||
pop rdx
|
||||
pop rcx
|
||||
pop rbx
|
||||
pop rax
|
||||
|
||||
.eoi:
|
||||
|
||||
|
@ -1,3 +1,10 @@
|
||||
//=======================================================================
|
||||
// Copyright Baptiste Wicht 2013.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//=======================================================================
|
||||
|
||||
[BITS 16]
|
||||
|
||||
[ORG 0x1000]
|
||||
|
@ -1,3 +1,10 @@
|
||||
//=======================================================================
|
||||
// Copyright Baptiste Wicht 2013.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//=======================================================================
|
||||
|
||||
%define BLACK_F 0x0
|
||||
%define BLUE_F 0x1
|
||||
%define GREEN_F 0x2
|
||||
|
@ -1,3 +1,10 @@
|
||||
//=======================================================================
|
||||
// Copyright Baptiste Wicht 2013.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//=======================================================================
|
||||
|
||||
; Some utility macros
|
||||
|
||||
; Define a string and a variable containing its length
|
||||
|
@ -1,3 +1,10 @@
|
||||
//=======================================================================
|
||||
// Copyright Baptiste Wicht 2013.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//=======================================================================
|
||||
|
||||
; Compute the length of string representation of the integer
|
||||
; in r8 = integer to print
|
||||
; out rax = string length of int
|
||||
|
Loading…
x
Reference in New Issue
Block a user