See description

Added finding the next free cluster
Added name to long name
Added long name to short name
Added tests for above

Added createLongNameEntry + tests

Moved tests to bottom

Added createShortNameEntry + test

Used the RTC for the date and time for the created short entry

Tidied createEntries


A bit of refactor

No symlinks for FAT32

findNextFreeCluster updates FAT

Reordered tests to better follow the FAT32FS code
FAT32 has no support for symlinks, so removed code around this.
Removed open_args from createNode as it doesn't need it

Added writeEntries + tests

Write the short and long entries to disk
findNextFreeCluster update cluster chain with parent cluster

Added FAT32 write + tests

This Added the ability to create files and directories and write to files.
Added location of the short dir entry for the file so can update the size of the file on disk
Added folders to the test FAT32 directory.
Also fixed minor bug in mkfat32

Added check for destroying the filesystem


Fixed error message for cluster size


Simpler if condition


0x0FFFFFFF => 0xFFFFFFFF


Spelling


Fixed test
This commit is contained in:
DrDeano 2021-01-04 08:50:20 +00:00
parent 5fbb8871a4
commit 4afecd6508
No known key found for this signature in database
GPG key ID: 96188600582B9ED7
19 changed files with 3192 additions and 959 deletions

View file

@ -30,6 +30,9 @@ const MemProfile = mem.MemProfile;
/// The type of a device.
pub const Device = pci.PciDeviceInfo;
/// The type of the date and time structure.
pub const DateTime = rtc.DateTime;
/// The virtual end of the kernel code.
extern var KERNEL_VADDR_END: *u32;
@ -565,10 +568,32 @@ pub fn initTask(task: *Task, entry_point: usize, allocator: *Allocator) Allocato
task.stack_pointer = @ptrToInt(&stack.*[kernel_stack_bottom]);
}
///
/// Get a list of hardware devices attached to the system.
///
/// Arguments:
/// IN allocator: *Allocator - An allocator for getting the devices
///
/// Return: []Device
/// A list of hardware devices.
///
/// Error: Allocator.Error
/// OutOfMemory - Unable to allocate space the operation.
///
pub fn getDevices(allocator: *Allocator) Allocator.Error![]Device {
return pci.getDevices(allocator);
}
///
/// Get the system date and time.
///
/// Return: DateTime
/// The current date and time.
///
pub fn getDateTime() DateTime {
return rtc.getDateTime();
}
///
/// Initialise the architecture
///

View file

@ -24,8 +24,14 @@ const CURRENT_CENTURY: u32 = 2000;
/// could report that the CMOS chip is faulty or the battery is dyeing.
const CENTURY_REGISTER: bool = false;
/// The error set that can be returned from some RTC functions.
const RtcError = error{
/// If setting the rate for interrupts is less than 3 or greater than 15.
RateError,
};
/// A structure to hold all the date and time information in the RTC.
const DateTime = struct {
pub const DateTime = struct {
second: u32,
minute: u32,
hour: u32,
@ -36,12 +42,6 @@ const DateTime = struct {
day_of_week: u32,
};
/// The error set that can be returned from some RTC functions.
const RtcError = error{
/// If setting the rate for interrupts is less than 3 or greater than 15.
RateError,
};
/// The number of ticks that has passed when RTC was initially set up.
var ticks: u32 = 0;
@ -145,66 +145,6 @@ fn readRtcRegisters() DateTime {
return date_time;
}
///
/// Read a stable time from the real time clock registers on the CMOS chip and return a BCD and
/// 12 hour converted date and time.
///
/// Return: DateTime
/// The data from the CMOS RTC registers with correct BCD conversions, 12 hour conversions and
/// the century added to the year.
///
fn readRtc() DateTime {
var date_time1 = readRtcRegisters();
var date_time2 = readRtcRegisters();
// Use the method: Read the registers twice and check if they are the same so to avoid
// inconsistent values due to RTC updates
var compare = false;
inline for (@typeInfo(DateTime).Struct.fields) |field| {
compare = compare or @field(date_time1, field.name) != @field(date_time2, field.name);
}
while (compare) {
date_time1 = readRtcRegisters();
date_time2 = readRtcRegisters();
compare = false;
inline for (@typeInfo(DateTime).Struct.fields) |field| {
compare = compare or @field(date_time1, field.name) != @field(date_time2, field.name);
}
}
// Convert BCD to binary if necessary
if (isBcd()) {
date_time1.second = bcdToBinary(date_time1.second);
date_time1.minute = bcdToBinary(date_time1.minute);
// Needs a special calculation because the upper bit is set
date_time1.hour = ((date_time1.hour & 0x0F) + (((date_time1.hour & 0x70) / 16) * 10)) | (date_time1.hour & 0x80);
date_time1.day = bcdToBinary(date_time1.day);
date_time1.month = bcdToBinary(date_time1.month);
date_time1.year = bcdToBinary(date_time1.year);
if (CENTURY_REGISTER) {
date_time1.century = bcdToBinary(date_time1.century);
}
}
// Need to add on the century to the year
if (CENTURY_REGISTER) {
date_time1.year += date_time1.century * 100;
} else {
date_time1.year += CURRENT_CENTURY;
}
// Convert to 24hr time
if (is12Hr(date_time1)) {
date_time1.hour = ((date_time1.hour & 0x7F) + 12) % 24;
}
return date_time1;
}
///
/// The interrupt handler for the RTC.
///
@ -262,6 +202,66 @@ fn enableInterrupts() void {
cmos.writeStatusRegister(cmos.StatusRegister.B, status_b | 0x40, true);
}
///
/// Read a stable time from the real time clock registers on the CMOS chip and return a BCD and
/// 12 hour converted date and time.
///
/// Return: DateTime
/// The data from the CMOS RTC registers with correct BCD conversions, 12 hour conversions and
/// the century added to the year.
///
pub fn getDateTime() DateTime {
var date_time1 = readRtcRegisters();
var date_time2 = readRtcRegisters();
// Use the method: Read the registers twice and check if they are the same so to avoid
// inconsistent values due to RTC updates
var compare = false;
inline for (@typeInfo(DateTime).Struct.fields) |field| {
compare = compare or @field(date_time1, field.name) != @field(date_time2, field.name);
}
while (compare) {
date_time1 = readRtcRegisters();
date_time2 = readRtcRegisters();
compare = false;
inline for (@typeInfo(DateTime).Struct.fields) |field| {
compare = compare or @field(date_time1, field.name) != @field(date_time2, field.name);
}
}
// Convert BCD to binary if necessary
if (isBcd()) {
date_time1.second = bcdToBinary(date_time1.second);
date_time1.minute = bcdToBinary(date_time1.minute);
// Needs a special calculation because the upper bit is set
date_time1.hour = ((date_time1.hour & 0x0F) + (((date_time1.hour & 0x70) / 16) * 10)) | (date_time1.hour & 0x80);
date_time1.day = bcdToBinary(date_time1.day);
date_time1.month = bcdToBinary(date_time1.month);
date_time1.year = bcdToBinary(date_time1.year);
if (CENTURY_REGISTER) {
date_time1.century = bcdToBinary(date_time1.century);
}
}
// Need to add on the century to the year
if (CENTURY_REGISTER) {
date_time1.year += date_time1.century * 100;
} else {
date_time1.year += CURRENT_CENTURY;
}
// Convert to 24hr time
if (is12Hr(date_time1)) {
date_time1.hour = ((date_time1.hour & 0x7F) + 12) % 24;
}
return date_time1;
}
///
/// Initialise the RTC.
///
@ -558,7 +558,7 @@ test "readRtc unstable read" {
.century = 2000,
.day_of_week = 5,
};
const actual = readRtc();
const actual = getDateTime();
expectEqual(expected, actual);
}
@ -611,7 +611,7 @@ test "readRtc is BCD" {
.century = 2000,
.day_of_week = 5,
};
const actual = readRtc();
const actual = getDateTime();
expectEqual(expected, actual);
}
@ -664,7 +664,7 @@ test "readRtc is 12 hours" {
.century = 2000,
.day_of_week = 5,
};
const actual = readRtc();
const actual = getDateTime();
expectEqual(expected, actual);
}