mirror of
https://github.com/wichtounet/thor-os.git
synced 2025-09-18 17:15:09 -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.
|
Thor is a minimalistic operating system created for learning reasons.
|
||||||
|
|
||||||
It is currently a 64bit OS written in assembly and C++.
|
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]
|
[BITS 16]
|
||||||
|
|
||||||
jmp rm_start
|
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]
|
[BITS 16]
|
||||||
|
|
||||||
; Functions
|
; Functions
|
||||||
|
@ -5,7 +5,7 @@ CPP_FLAGS=-masm=intel -Iinclude/ -nostdlib -O1 -std=c++11 -fno-exceptions -fno-r
|
|||||||
KERNEL_FLAGS=$(CPP_FLAGS)
|
KERNEL_FLAGS=$(CPP_FLAGS)
|
||||||
KERNEL_LINK_FLAGS=-lgcc -T linker.ld $(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)
|
CRTBEGIN_OBJ:=$(shell $(CC) $(CFLAGS) -print-file-name=crtbegin.o)
|
||||||
CRTEND_OBJ:=$(shell $(CC) $(CFLAGS) -print-file-name=crtend.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
|
thor.o: src/thor.cpp
|
||||||
$(CC) $(KERNEL_FLAGS) -c src/thor.cpp -o thor.o
|
$(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:
|
clean:
|
||||||
rm -f *.o
|
rm -f *.o
|
||||||
rm -f *.bin
|
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
|
#ifndef ATA_H
|
||||||
#define ATA_H
|
#define ATA_H
|
||||||
|
|
||||||
#include "types.hpp"
|
#include "types.hpp"
|
||||||
|
|
||||||
|
namespace ata {
|
||||||
|
|
||||||
struct drive_descriptor {
|
struct drive_descriptor {
|
||||||
uint16_t controller;
|
uint16_t controller;
|
||||||
uint8_t drive;
|
uint8_t drive;
|
||||||
@ -14,6 +23,8 @@ void detect_disks();
|
|||||||
uint8_t number_of_disks();
|
uint8_t number_of_disks();
|
||||||
drive_descriptor& drive(uint8_t disk);
|
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
|
#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
|
#ifndef CONSOLE_H
|
||||||
#define 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
|
#ifndef KERNEL_UTILS_H
|
||||||
#define 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
|
#ifndef KEYBOARD_H
|
||||||
#define KEYBOARD_H
|
#define KEYBOARD_H
|
||||||
|
|
||||||
#include "types.hpp"
|
#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);
|
char key_to_ascii(uint8_t key);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#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
|
#ifndef MEMORY_H
|
||||||
#define 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
|
#ifndef SHELL_H
|
||||||
#define SHELL_
|
#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
|
#ifndef THOR_H
|
||||||
#define 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
|
#ifndef TIMER_H
|
||||||
#define 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
|
#ifndef TYPES_H
|
||||||
#define 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
|
#ifndef UTILS_H
|
||||||
#define UTILS_H
|
#define UTILS_H
|
||||||
|
|
||||||
#include "types.hpp"
|
#include "types.hpp"
|
||||||
|
|
||||||
uint64_t parse(const char* str);
|
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_equals(const char* a, const char* b);
|
||||||
bool str_contains(const char* a, char c);
|
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 "ata.hpp"
|
||||||
#include "kernel_utils.hpp"
|
#include "kernel_utils.hpp"
|
||||||
#include "timer.hpp"
|
#include "timer.hpp"
|
||||||
@ -37,8 +44,7 @@ namespace {
|
|||||||
#define MASTER_BIT 0
|
#define MASTER_BIT 0
|
||||||
#define SLAVE_BIT 1
|
#define SLAVE_BIT 1
|
||||||
|
|
||||||
bool detected = false;
|
ata::drive_descriptor* drives;
|
||||||
drive_descriptor* drives;
|
|
||||||
|
|
||||||
volatile bool primary_invoked = false;
|
volatile bool primary_invoked = false;
|
||||||
volatile bool secondary_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;
|
return timeout;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool select_device(drive_descriptor& drive){
|
bool select_device(ata::drive_descriptor& drive){
|
||||||
auto controller = drive.controller;
|
auto controller = drive.controller;
|
||||||
|
|
||||||
if(in_byte(controller + ATA_STATUS) & (ATA_STATUS_BSY | ATA_STATUS_DRQ)){
|
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
|
} //end of anonymous namespace
|
||||||
|
|
||||||
void detect_disks(){
|
void ata::detect_disks(){
|
||||||
if(!detected){
|
drives = reinterpret_cast<drive_descriptor*>(k_malloc(4 * sizeof(drive_descriptor)));
|
||||||
drives = reinterpret_cast<drive_descriptor*>(k_malloc(4 * sizeof(drive_descriptor)));
|
|
||||||
|
|
||||||
drives[0] = {ATA_PRIMARY, 0xE0, false, MASTER_BIT};
|
drives[0] = {ATA_PRIMARY, 0xE0, false, MASTER_BIT};
|
||||||
drives[1] = {ATA_PRIMARY, 0xF0, false, SLAVE_BIT};
|
drives[1] = {ATA_PRIMARY, 0xF0, false, SLAVE_BIT};
|
||||||
drives[2] = {ATA_SECONDARY, 0xE0, false, MASTER_BIT};
|
drives[2] = {ATA_SECONDARY, 0xE0, false, MASTER_BIT};
|
||||||
drives[3] = {ATA_SECONDARY, 0xF0, false, SLAVE_BIT};
|
drives[3] = {ATA_SECONDARY, 0xF0, false, SLAVE_BIT};
|
||||||
|
|
||||||
for(uint8_t i = 0; i < 4; ++i){
|
for(uint8_t i = 0; i < 4; ++i){
|
||||||
auto& drive = drives[i];
|
auto& drive = drives[i];
|
||||||
|
|
||||||
out_byte(drive.controller + 0x6, drive.drive);
|
out_byte(drive.controller + 0x6, drive.drive);
|
||||||
sleep_ms(4);
|
sleep_ms(4);
|
||||||
drive.present = in_byte(drive.controller + 0x7) & 0x40;
|
drive.present = in_byte(drive.controller + 0x7) & 0x40;
|
||||||
}
|
|
||||||
|
|
||||||
register_irq_handler<14>(primary_controller_handler);
|
|
||||||
register_irq_handler<15>(secondary_controller_handler);
|
|
||||||
|
|
||||||
detected = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
register_irq_handler<14>(primary_controller_handler);
|
||||||
|
register_irq_handler<15>(secondary_controller_handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t number_of_disks(){
|
uint8_t ata::number_of_disks(){
|
||||||
if(!detected){
|
|
||||||
detect_disks();
|
|
||||||
}
|
|
||||||
|
|
||||||
return 4;
|
return 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
drive_descriptor& drive(uint8_t disk){
|
ata::drive_descriptor& ata::drive(uint8_t disk){
|
||||||
if(!detected){
|
|
||||||
detect_disks();
|
|
||||||
}
|
|
||||||
|
|
||||||
return drives[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
|
//Select the device
|
||||||
if(!select_device(drive)){
|
if(!select_device(drive)){
|
||||||
return false;
|
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 <stdarg.h>
|
||||||
|
|
||||||
#include "console.hpp"
|
#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 "memory.hpp"
|
||||||
#include "timer.hpp"
|
#include "timer.hpp"
|
||||||
#include "shell.hpp"
|
#include "shell.hpp"
|
||||||
|
#include "keyboard.hpp"
|
||||||
|
#include "disks.hpp"
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
@ -8,6 +17,8 @@ void __attribute__ ((section ("main_section"))) kernel_main(){
|
|||||||
load_memory_map();
|
load_memory_map();
|
||||||
init_memory_manager();
|
init_memory_manager();
|
||||||
install_timer();
|
install_timer();
|
||||||
|
keyboard::install_driver();
|
||||||
|
disks::detect_disks();
|
||||||
init_shell();
|
init_shell();
|
||||||
|
|
||||||
return;
|
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"
|
#include "kernel_utils.hpp"
|
||||||
|
|
||||||
uint8_t in_byte(uint16_t _port){
|
uint8_t in_byte(uint16_t _port){
|
||||||
uint8_t rv;
|
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__ ("in %[data], %[port]"
|
||||||
__asm__ __volatile__ ("out %0, %1" : : "dN" (_port), "a" (_data));
|
: [data] "=a" (rv)
|
||||||
|
: [port] "dN" (_port));
|
||||||
|
|
||||||
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t in_word(uint16_t _port){
|
uint16_t in_word(uint16_t _port){
|
||||||
uint16_t rv;
|
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;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
void out_word(uint16_t _port, uint16_t _data){
|
void out_byte (uint16_t _port, uint8_t _data){
|
||||||
__asm__ __volatile__ ("out %0, %1" : : "dN" (_port), "a" (_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 "keyboard.hpp"
|
||||||
|
#include "kernel_utils.hpp"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
@ -42,8 +50,50 @@ char qwertz[128] =
|
|||||||
0, /* All other keys are undefined */
|
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];
|
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 "memory.hpp"
|
||||||
|
#include "console.hpp"
|
||||||
|
|
||||||
namespace {
|
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 {
|
struct bios_mmap_entry {
|
||||||
uint32_t base_low;
|
uint32_t base_low;
|
||||||
uint32_t base_high;
|
uint32_t base_high;
|
||||||
@ -20,7 +32,12 @@ mmapentry e820_mmap[32];
|
|||||||
|
|
||||||
void mmap_query(uint64_t cmd, uint64_t* result){
|
void mmap_query(uint64_t cmd, uint64_t* result){
|
||||||
uint64_t tmp;
|
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;
|
*result = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,6 +121,35 @@ uint64_t* allocate_block(uint64_t blocks){
|
|||||||
return block;
|
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
|
} //end of anonymous namespace
|
||||||
|
|
||||||
void init_memory_manager(){
|
void init_memory_manager(){
|
||||||
@ -141,12 +187,12 @@ uint64_t* k_malloc(uint64_t bytes){
|
|||||||
auto header = reinterpret_cast<malloc_header_chunk*>(block);
|
auto header = reinterpret_cast<malloc_header_chunk*>(block);
|
||||||
header->size = MIN_BLOCKS * BLOCK_SIZE - META_SIZE;
|
header->size = MIN_BLOCKS * BLOCK_SIZE - META_SIZE;
|
||||||
|
|
||||||
|
header->next = current->next;
|
||||||
|
header->prev = current;
|
||||||
|
|
||||||
current->next->prev = header;
|
current->next->prev = header;
|
||||||
current->next = header;
|
current->next = header;
|
||||||
|
|
||||||
header->next = current->next;
|
|
||||||
header->prev = current;
|
|
||||||
|
|
||||||
auto footer = reinterpret_cast<malloc_footer_chunk*>(
|
auto footer = reinterpret_cast<malloc_footer_chunk*>(
|
||||||
reinterpret_cast<uintptr_t>(block) + header->size + sizeof(malloc_header_chunk));
|
reinterpret_cast<uintptr_t>(block) + header->size + sizeof(malloc_header_chunk));
|
||||||
footer->size = header->size;
|
footer->size = header->size;
|
||||||
@ -154,7 +200,7 @@ uint64_t* k_malloc(uint64_t bytes){
|
|||||||
//This block is big enough
|
//This block is big enough
|
||||||
|
|
||||||
//Is it worth splitting the block ?
|
//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;
|
auto new_block_size = current->size - bytes - META_SIZE;
|
||||||
|
|
||||||
//Set the new 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));
|
reinterpret_cast<uintptr_t>(new_block) + new_block_size + sizeof(malloc_header_chunk));
|
||||||
new_footer->size = new_block_size;
|
new_footer->size = new_block_size;
|
||||||
|
|
||||||
|
debug_malloc<DEBUG_MALLOC>("after malloc split");
|
||||||
|
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
//Remove this node from the free list
|
//Remove this node from the free list
|
||||||
current->prev->next = current->next;
|
current->prev->next = current->next;
|
||||||
current->next->prev = current->prev;
|
current->next->prev = current->prev;
|
||||||
|
|
||||||
|
debug_malloc<DEBUG_MALLOC>("after malloc no split");
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -213,6 +263,8 @@ void k_free(uint64_t* block){
|
|||||||
|
|
||||||
header->next->prev = free_header;
|
header->next->prev = free_header;
|
||||||
header->next = free_header;
|
header->next = free_header;
|
||||||
|
|
||||||
|
debug_malloc<DEBUG_MALLOC>("after free");
|
||||||
}
|
}
|
||||||
|
|
||||||
void load_memory_map(){
|
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 "types.hpp"
|
||||||
#include "keyboard.hpp"
|
#include "keyboard.hpp"
|
||||||
#include "kernel_utils.hpp"
|
#include "kernel_utils.hpp"
|
||||||
@ -6,7 +13,7 @@
|
|||||||
#include "timer.hpp"
|
#include "timer.hpp"
|
||||||
#include "utils.hpp"
|
#include "utils.hpp"
|
||||||
#include "memory.hpp"
|
#include "memory.hpp"
|
||||||
#include "ata.hpp"
|
#include "disks.hpp"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
@ -22,13 +29,16 @@ void echo_command(const char* params);
|
|||||||
void mmap_command(const char* params);
|
void mmap_command(const char* params);
|
||||||
void memory_command(const char* params);
|
void memory_command(const char* params);
|
||||||
void disks_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 {
|
struct command_definition {
|
||||||
const char* name;
|
const char* name;
|
||||||
void (*function)(const char*);
|
void (*function)(const char*);
|
||||||
};
|
};
|
||||||
|
|
||||||
command_definition commands[10] = {
|
command_definition commands[13] = {
|
||||||
{"reboot", reboot_command},
|
{"reboot", reboot_command},
|
||||||
{"help", help_command},
|
{"help", help_command},
|
||||||
{"uptime", uptime_command},
|
{"uptime", uptime_command},
|
||||||
@ -39,6 +49,9 @@ command_definition commands[10] = {
|
|||||||
{"mmap", mmap_command},
|
{"mmap", mmap_command},
|
||||||
{"memory", memory_command},
|
{"memory", memory_command},
|
||||||
{"disks", disks_command},
|
{"disks", disks_command},
|
||||||
|
{"partitions", partitions_command},
|
||||||
|
{"mount", mount_command},
|
||||||
|
{"ls", ls_command},
|
||||||
};
|
};
|
||||||
|
|
||||||
uint64_t current_input_length = 0;
|
uint64_t current_input_length = 0;
|
||||||
@ -46,45 +59,44 @@ char current_input[50];
|
|||||||
|
|
||||||
void exec_command();
|
void exec_command();
|
||||||
|
|
||||||
#define KEY_ENTER 0x1C
|
void start_shell(){
|
||||||
#define KEY_BACKSPACE 0x0E
|
while(true){
|
||||||
|
auto key = keyboard::get_char();
|
||||||
|
|
||||||
void keyboard_handler(){
|
if(key & 0x80){
|
||||||
uint8_t key = in_byte(0x60);
|
//TODO Handle shift
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
auto qwertz_key = key_to_ascii(key);
|
if(key == keyboard::KEY_ENTER){
|
||||||
|
current_input[current_input_length] = '\0';
|
||||||
|
|
||||||
if(qwertz_key > 0){
|
k_print_line();
|
||||||
current_input[current_input_length++] = qwertz_key;
|
|
||||||
k_print(qwertz_key);
|
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 used memory: %m\n", used_memory());
|
||||||
k_printf("Total free memory: %m\n", free_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*){
|
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){
|
for(uint64_t i = 0; i < disks::detected_disks(); ++i){
|
||||||
auto& descriptor = drive(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
|
} //end of anonymous namespace
|
||||||
|
|
||||||
void init_shell(){
|
void init_shell(){
|
||||||
@ -291,5 +350,5 @@ void init_shell(){
|
|||||||
|
|
||||||
k_print("thor> ");
|
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 "thor.hpp"
|
||||||
#include "memory.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 "timer.hpp"
|
||||||
|
|
||||||
#include "kernel_utils.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"
|
#include "utils.hpp"
|
||||||
|
|
||||||
bool str_equals(const char* a, const char* b){
|
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;
|
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){
|
uint64_t parse(const char* str){
|
||||||
int i = 0;
|
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
|
; Variables
|
||||||
|
|
||||||
@ -122,24 +129,28 @@ _irq%1:
|
|||||||
test rax, rax
|
test rax, rax
|
||||||
je .eoi
|
je .eoi
|
||||||
|
|
||||||
push rbx
|
push rax
|
||||||
push rcx
|
push rcx
|
||||||
push rdx
|
push rdx
|
||||||
push rsi
|
push rsi
|
||||||
push rdi
|
push rdi
|
||||||
push r8
|
push r8
|
||||||
push r9
|
push r9
|
||||||
|
push r10
|
||||||
|
push r11
|
||||||
|
|
||||||
; Call the handler
|
; Call the handler
|
||||||
call rax
|
call rax
|
||||||
|
|
||||||
push r9
|
pop r11
|
||||||
push r8
|
pop r10
|
||||||
|
pop r9
|
||||||
|
pop r8
|
||||||
pop rdi
|
pop rdi
|
||||||
pop rsi
|
pop rsi
|
||||||
pop rdx
|
pop rdx
|
||||||
pop rcx
|
pop rcx
|
||||||
pop rbx
|
pop rax
|
||||||
|
|
||||||
.eoi:
|
.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]
|
[BITS 16]
|
||||||
|
|
||||||
[ORG 0x1000]
|
[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 BLACK_F 0x0
|
||||||
%define BLUE_F 0x1
|
%define BLUE_F 0x1
|
||||||
%define GREEN_F 0x2
|
%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
|
; Some utility macros
|
||||||
|
|
||||||
; Define a string and a variable containing its length
|
; 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
|
; Compute the length of string representation of the integer
|
||||||
; in r8 = integer to print
|
; in r8 = integer to print
|
||||||
; out rax = string length of int
|
; out rax = string length of int
|
||||||
|
Loading…
x
Reference in New Issue
Block a user