diff --git a/Cargo.lock b/Cargo.lock index d042e5c8a..0108916fc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -390,7 +390,7 @@ dependencies = [ [[package]] name = "hbbytecode" version = "0.1.0" -source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#c133c2dbe71b3f1e1142bacef200775ae0c1d22d" +source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#254d5ed96234c8291770d84b2ac11ef7dd403b28" [[package]] name = "hbbytecode" @@ -400,7 +400,7 @@ source = "git+https://git.ablecorp.us/ableos/holey-bytes#c133c2dbe71b3f1e1142bac [[package]] name = "hblang" version = "0.1.0" -source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#c133c2dbe71b3f1e1142bacef200775ae0c1d22d" +source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#254d5ed96234c8291770d84b2ac11ef7dd403b28" dependencies = [ "hbvm 0.1.0 (git+https://git.ablecorp.us/AbleOS/holey-bytes.git)", ] @@ -408,7 +408,7 @@ dependencies = [ [[package]] name = "hbvm" version = "0.1.0" -source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#c133c2dbe71b3f1e1142bacef200775ae0c1d22d" +source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#254d5ed96234c8291770d84b2ac11ef7dd403b28" dependencies = [ "hbbytecode 0.1.0 (git+https://git.ablecorp.us/AbleOS/holey-bytes.git)", ] diff --git a/sysdata/libraries/stn/src/acs.hb b/sysdata/libraries/stn/src/acs.hb new file mode 100644 index 000000000..4ec12ca26 --- /dev/null +++ b/sysdata/libraries/stn/src/acs.hb @@ -0,0 +1,8 @@ +//! This is a reserved file for use with the AbleOS Clustering System + +HostID := int +// A DeviceID points to a specific device in the ACS. +DeviceID := struct { + host_id: HostID, + id: int, +} \ No newline at end of file diff --git a/sysdata/libraries/stn/src/file_io.hb b/sysdata/libraries/stn/src/file_io.hb new file mode 100644 index 000000000..2e28998d7 --- /dev/null +++ b/sysdata/libraries/stn/src/file_io.hb @@ -0,0 +1,27 @@ +// TODO: This is a bad path struct and should be better thoughtout. +Path := struct {length: u8, data: ^u8} + +FileID := struct { + host_id: int, + id: int, +} + +open := fn(file_path: Path): FileID { +} +close := fn(file_id: FileID): int { +} +// This reads in page_count of pages out of the file. If file_size is less than an exact multiple of pages do something. +// TODO: Figureout how to encode errors. +read_pages := fn(file_id: FileID, offset: int, page_count: int): void { +} + +// This writes out page_count of pages out of the file. +write_pages := fn(file_id: FileID, offset: int, page_count: int): void { +} + +// This reads out byte_count of bytes from the file. +read_bytes := fn(file_id: FileID, offset: int, byte_count: int): void { +} + +write_bytes := fn(file_id: FileID, offset: int, byte_count: int): void { +} \ No newline at end of file diff --git a/sysdata/libraries/stn/src/lib.hb b/sysdata/libraries/stn/src/lib.hb index be4dac204..5babcf70d 100644 --- a/sysdata/libraries/stn/src/lib.hb +++ b/sysdata/libraries/stn/src/lib.hb @@ -1,7 +1,10 @@ +acs := @use("rel:acs.hb") + string := @use("rel:string.hb") log := @use("rel:log.hb") memory := @use("rel:memory.hb") buffer := @use("rel:buffer.hb") math := @use("rel:math.hb") random := @use("rel:random.hb") -pci := @use("rel:pci.hb") \ No newline at end of file +pci := @use("rel:pci.hb") +file := @use("rel:file_io.hb") \ No newline at end of file diff --git a/sysdata/programs/filesystem_fat32/README.md b/sysdata/programs/filesystem_fat32/README.md new file mode 100644 index 000000000..e2be580e9 --- /dev/null +++ b/sysdata/programs/filesystem_fat32/README.md @@ -0,0 +1 @@ +# filesystem_fat32 \ No newline at end of file diff --git a/sysdata/programs/filesystem_fat32/meta.toml b/sysdata/programs/filesystem_fat32/meta.toml new file mode 100644 index 000000000..fcf5c328a --- /dev/null +++ b/sysdata/programs/filesystem_fat32/meta.toml @@ -0,0 +1,11 @@ +[package] +name = "filesystem_fat32" +authors = [""] + +[dependants.libraries] + +[dependants.binaries] +hblang.version = "1.0.0" + +[build] +command = "hblang src/main.hb" diff --git a/sysdata/programs/filesystem_fat32/protocol/fat32.aldi b/sysdata/programs/filesystem_fat32/protocol/fat32.aldi new file mode 100644 index 000000000..e69de29bb diff --git a/sysdata/programs/filesystem_fat32/src/attributes.hb b/sysdata/programs/filesystem_fat32/src/attributes.hb new file mode 100644 index 000000000..2c5c3ca08 --- /dev/null +++ b/sysdata/programs/filesystem_fat32/src/attributes.hb @@ -0,0 +1,7 @@ +READ_ONLY := 0x1 +HIDDEN := 0x2 +SYSTEM := 0x4 +VOLUME_ID := 0x8 +DIRECTORY := 0x10 +ARCHIVE := 0x20 +LFN := READ_ONLY | HIDDEN | SYSTEM | VOLUME_ID \ No newline at end of file diff --git a/sysdata/programs/filesystem_fat32/src/bios_parameter_block.hb b/sysdata/programs/filesystem_fat32/src/bios_parameter_block.hb new file mode 100644 index 000000000..afb56a220 --- /dev/null +++ b/sysdata/programs/filesystem_fat32/src/bios_parameter_block.hb @@ -0,0 +1,165 @@ +stn := @use("../../../libraries/stn/src/lib.hb"); +.{string, memory, buffer, log} := stn + +VALID_JUMP_BYTES := [u8].(0xEB, 0x3C, 0x90) + +OemIdent := struct { + dos_version: [u8; 8], + dos_version_name: [u8; 8], +} + +new_oem_ident := fn(major: int, minor: int): OemIdent { + ver := [u8].(0, 0, 0, 0, 0, 0, 0, 0) + return OemIdent.(ver, ver) +} + +BiosParameterBlock := struct { + jump_bytes: [u8; 3], + oem_ident: OemIdent, + bytes_per_sector: u16, + sectors_per_cluster: u8, + reserved_sectors: u16, + // The amount of FileAllocationTables on the disk. Often 2. + fat_count: u8, + root_directory_count: u16, + // if 0 then refer to large_sector_count + total_sectors: u16, + media_type: u8, + // if 0 refer to sectors_per_fat in the ExtendedBootRecord + sectors_per_fat: u16, + sectors_per_track: u16, + head_count: u16, + hidden_sectors: u32, + large_sector_count: u32, +} + +bpb_sanity_check := fn(bpb: BiosParameterBlock): int { + return 0 +} + +new_bpb := fn(): BiosParameterBlock { + oem := new_oem_ident(0, 0) + + return BiosParameterBlock.(VALID_JUMP_BYTES, oem, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) +} + +sector_count := fn(bpb: BiosParameterBlock): u32 { + if bpb.total_sectors == 0 { + return bpb.large_sector_count + } else { + return bpb.total_sectors + } +} + +FatVersionNumber := struct { + major_version: u8, + minor_version: u8, +} + +FormatReservation := [u8; 12] + +// Padded with spaces. +VolumeName := [u8; 11] + +SystemIdentifierString := [u8; 8] +VALID_SYSTEM_IDENTIFIER_STRING := [u8].(46, 41, 54, 33, 32, 20, 20, 20) +BOOTABLE_PARTITION_SIGNATURE := 0xAA55 + +BootCode := [u8; 420] + +ExtendedBootRecord := struct { + sectors_per_fat: u32, + flags: u16, + fat_version_number: FatVersionNumber, + // Typically set to 2. + root_directory_cluster_number: u32, + fsinfo_structure: u16, + backup_boot_sector: u16, + // When a volume is formated these bytes should be zero. As a sanity check I guess? + format_reserved: FormatReservation, + // 0x00 floppy or 0x80 hard disk + drive_number: u8, + nt_reserved: u8, + // must be 0x28 or 0x29 + signature: u8, + volume_id_serial: u32, + volume_id_name: VolumeName, + // The spec says this is always FAT32. Untrustworthy and another sanity check I guess. + system_identifier_string: SystemIdentifierString, + boot_code: BootCode, + partition_signature: u16, +} + +ebr_sanity_check := fn(ebr: ExtendedBootRecord): int { + ret := 0 + if ebr.drive_number != 0x0 | ebr.drive_number != 0x80 { + log.warn("EBR-Drive-Number sanity check failed\0") + } + + if ebr.signature != 0x28 | ebr.signature != 0x29 { + log.warn("EBR-Signature sanity check failed\0") + } + + if ebr.system_identifier_string != VALID_SYSTEM_IDENTIFIER_STRING { + log.warn("EBR-Signature-Identifier-String sanity check failed\0") + } + return 0 +} + +new_ebr := fn(): ExtendedBootRecord { + version := FatVersionNumber.(0, 0) + fmt_res := FormatReservation.(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) + vol_name := @as([u8; 11], idk) + boot_code := @as([u8; 420], idk) + + return ExtendedBootRecord.( + 0, + 0, + version, + 0, + 0, + 0, + fmt_res, + 0, + 0, + 0, + 0, + vol_name, + VALID_SYSTEM_IDENTIFIER_STRING, + boot_code, + 0, + ) +} + +VALID_LEAD_FS_INFO := 0x41615252 +VALID_TRAIL_FS_INFO := 0xAA550000 + +FSInfo := struct { + // Must be 0x41615252 to indicate a valid FSInfo structure + lead_signature: u32, + lead_reserved: [u8; 480], + // If the value is 0xFFFFFFFF, then the free count is unknown and must be computed. However, this value might be incorrect and should at least be range checked (<= volume cluster count) + last_known_free_cluster_count: u32, + last_known_avalible_cluster: u32, + trail_reserved: [u8; 12], + trail_signature: u32, +} + +fs_info_sanity_check := fn(fs_info: FSInfo): int { + ret := 0 + if fs_info.last_known_free_cluster_count == 0xFFFFFFFF { + ret &= 1 + log.warn("Last known free cluster count unknown\0") + } + if fs_info.last_known_avalible_cluster == 0xFFFFFFFF { + ret &= 2 + log.warn("Last known avalible cluster count unknown\0") + } + return ret +} + +new_fs_info := fn(): FSInfo { + lead_reserved := @as([u8; 480], idk) + trail_reserved := @as([u8; 12], idk) + return FSInfo.(0, lead_reserved, 0, 0, trail_reserved, 0) +} \ No newline at end of file diff --git a/sysdata/programs/filesystem_fat32/src/datetime.hb b/sysdata/programs/filesystem_fat32/src/datetime.hb new file mode 100644 index 000000000..fa6b589a6 --- /dev/null +++ b/sysdata/programs/filesystem_fat32/src/datetime.hb @@ -0,0 +1,25 @@ +Date := struct { + year: u16, + month: u16, + day: u16, +} +Time := struct { + hour: u16, + minutes: u16, + seconds: u16, +} + +compress_date := fn(year: u16, month: u16, day: u16): u16 { + return 0 +} +decompress_date := fn(date: u16): Date { + return Date.(0, 0, 0) +} + +compress_time := fn(hour: u16, minutes: u16, seconds: u16): u16 { + return 0 +} + +decompress_time := fn(time: u16): Time { + return Time.(0, 0, 0) +} \ No newline at end of file diff --git a/sysdata/programs/filesystem_fat32/src/file.hb b/sysdata/programs/filesystem_fat32/src/file.hb new file mode 100644 index 000000000..aa0e3e765 --- /dev/null +++ b/sysdata/programs/filesystem_fat32/src/file.hb @@ -0,0 +1,21 @@ +attributes := @use("rel:attributes.hb") +datetime := @use("rel:datetime.hb") + +FileName := [u8; 11] + +// This is the File Allocation Table entry that tells us where on disk the File is. +FileEntry := struct { + file_name: FileName, + attributes: u8, + // We could use this byte for something but we likely will not + nt_reserved: u8, + hundredths_seconds_creation: u8, + creation_time: datetime.time, + creation_date: datetime.date, + last_accessed_date: datetime.date, + high_cluster_number: u16, + last_modification_time: datetime.time, + last_modification_date: datetime.date, + low_cluster_number: u16, + file_size: u32, +} \ No newline at end of file diff --git a/sysdata/programs/filesystem_fat32/src/main.hb b/sysdata/programs/filesystem_fat32/src/main.hb new file mode 100644 index 000000000..3d7162023 --- /dev/null +++ b/sysdata/programs/filesystem_fat32/src/main.hb @@ -0,0 +1,47 @@ +stn := @use("../../../libraries/stn/src/lib.hb"); +.{string, memory, buffer, log} := stn + +attributes := @use("rel:attributes.hb") +datetime := @use("rel:datetime.hb") +directory := @use("rel:file.hb") +bios_parameter_block := @use("rel:bios_parameter_block.hb"); +.{bpb_sanity_check, ebr_sanity_check, fs_info_sanity_check} := bios_parameter_block; +.{new_bpb, new_ebr, new_fs_info} := bios_parameter_block + +FAT12_THRESHOLD := 4085 +FAT16_THRESHOLD := 65525 + +ExFAT := 0 +FAT12 := 1 +FAT16 := 2 +FAT32 := 3 + +calculate_fat_type := fn(sector_size: int, total_clusters: int): int { + if sector_size == 0 { + return ExFAT + } else if total_clusters < 4085 { + return FAT12 + } else if total_clusters < 65525 { + return FAT16 + } else { + return FAT32 + } +} + +main := fn(): int { + bpb := new_bpb() + ebr := new_ebr() + fsi := new_fs_info() + + fat_type := calculate_fat_type(1, 100) + + if fat_type != FAT32 { + log.warn("filesystem_fat32 driver only supports Fat32.\0") + } + + bpb_sanity_check(bpb) + ebr_sanity_check(ebr) + fs_info_sanity_check(fsi) + + return 0 +} \ No newline at end of file diff --git a/sysdata/system_config.toml b/sysdata/system_config.toml index f8f4fbb95..f14b3a2b8 100644 --- a/sysdata/system_config.toml +++ b/sysdata/system_config.toml @@ -44,5 +44,5 @@ resolution = "1024x768x24" [boot.limine.ableos.modules.svga_driver] path = "boot:///svga_driver.hbf" -[boot.limine.ableos.modules.pumpkin_print] -path = "boot:///pumpkin_print.hbf" +[boot.limine.ableos.modules.filesystem_fat32] +path = "boot:///filesystem_fat32.hbf"