Initial commit

This commit is contained in:
John Stefanelli 2022-09-24 22:30:25 -04:00
commit 58de4d6c32
Signed by: jstefanelli
GPG key ID: 60EDE2437640D2AA
18 changed files with 760 additions and 0 deletions

BIN
.DS_Store vendored Normal file

Binary file not shown.

2
.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
build/
.idea/

5
.vscode/settings.json vendored Normal file
View file

@ -0,0 +1,5 @@
{
"cmake.configureArgs": [
"-DCMAKE_TOOLCHAIN_FILE=CMakeToolchain.txt"
]
}

8
CMakeLists.txt Normal file
View file

@ -0,0 +1,8 @@
cmake_minimum_required(VERSION 3.21)
project(os3 C ASM_NASM)
set(CMAKE_C_STANDARD 17)
add_subdirectory(mbr)
add_subdirectory(libfat)
add_subdirectory(rawimg)

30
CMakeToolchain.txt Normal file
View file

@ -0,0 +1,30 @@
# Tag as cross-compiler for no specific system
set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_SYSTEM_PROCESSOR i686)
# Find compilers
set(CMAKE_C_COMPILER i686-elf-gcc)
set(CMAKE_CXX_COMPILER i686-elf-g++)
set(CMAKE_ASM_COMPILER nasm)
set(CMAKE_C_LINK_EXECUTABLE "i686-elf-ld <CMAKE_C_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
set(CMAKE_CXX_LINK_EXECUTABLE "i686-elf-ld <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
set(CMAKE_ASM_NASM_LINK_EXECUTABLE "i686-elf-ld <CMAKE_ASM_NASM_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
# Set language flags
set(CMAKE_C_FLAGS "-Wall -mtune=i386 -gdwarf -m32 -oS")
set(CMAKE_ASM_FLAGS "-felf32 -F dwarf -g")
set(CMAKE_ASM_NASM_OBJECT_FORMAT elf32)
set(CMAKE_STATIC_LINKER_FLAGS "")
set(CMAKE_EXE_LINKER_FLAGS "-m elf_i386 --nmagic -nostdlib")
# Locate i686 sysroot?
set(CMAKE_FIND_ROOT_PATH $ENV{I686_CROSS_ROOT})
# adjust the default behavior of the FIND_XXX() commands:
# search programs in the host environment
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
# search headers and libraries in the target environment
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

6
host/CMakeLists.txt Normal file
View file

@ -0,0 +1,6 @@
cmake_minimum_required(VERSION 3.21)
project(os3_host C)
add_subdirectory(../libfat ${CMAKE_CURRENT_BINARY_DIR}/libfat)
add_subdirectory(mbrcopy)

View file

@ -0,0 +1,2 @@
add_executable(mbrcopy mbrcopy.c)
target_link_libraries(mbrcopy libfat)

96
host/mbrcopy/mbrcopy.c Normal file
View file

@ -0,0 +1,96 @@
#include "libfat.h"
#include "stdio.h"
#include "stdlib.h"
os_u32 readRoutine(os_u32 amount, void* buffer, void* user_data) {
if (user_data == 0) {
return 0;
}
FILE** f = (FILE**)user_data;
os_u32 read_bytes = fread(buffer, 1, amount, *f);
return read_bytes;
}
os_u32 writeRoutine(os_u32 amount, void* buffer, void* user_data) {
if (user_data == 0) {
return 0;
}
FILE** f = (FILE**)user_data;
os_u32 written_bytes = fwrite(buffer, 1, amount, *f);
return written_bytes;
}
os_bool seekRoutine(os_u32 offset, os_u32 direction, void* user_data) {
if (user_data == 0) {
return OS_FALSE;
}
FILE** f = (FILE**)user_data;
int seek_dir = SEEK_SET;
switch(direction) {
case LIBFAT_SEEK_ORIGIN:
seek_dir = SEEK_SET;
break;
case LIBFAT_SEEK_CURRENT:
seek_dir = SEEK_CUR;
break;
case LIBFAT_SEEK_END:
seek_dir = SEEK_END;
break;
}
int result = fseek(*f, offset, seek_dir);
return result == 0 ? OS_TRUE : OS_FALSE;
}
os_u32 tellRoutine(void* user_data) {
if (user_data == 0) {
return 0;
}
FILE** f = (FILE**)user_data;
os_u32 result = ftell(*f);
return result;
}
void printRoutine(os_s8* data, os_u16 size) {
if (size == 0) {
printf("%s\n", data);
return;
}
for(os_u16 s = 0; s < size; s++) {
printf("%c", *data);
data++;
}
printf("\n");
}
void printNumber(os_u32 number) {
printf("%#x\n", number);
}
int main(int argc, char** argv) {
if (argc < 2) {
printf("No file provided\n");
return 1;
}
FILE* f = fopen(argv[1], "rb");
FileHandle h;
h.read = readRoutine;
h.write = writeRoutine;
h.seek = seekRoutine;
h.tell = tellRoutine;
h.user_data = (void*)&f;
libfat_test(h, printRoutine, printNumber);
fclose(f);
return 0;
}

3
libfat/CMakeLists.txt Normal file
View file

@ -0,0 +1,3 @@
add_library(libfat libfat.c include/libfat.h)
target_include_directories(libfat PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include")
target_include_directories(libfat PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/../os3_common/")

147
libfat/include/libfat.h Normal file
View file

@ -0,0 +1,147 @@
#ifndef __OS3_LIBFAT_H
#define __OS3_LIBFAT_H
#include "datatypes.h"
#include "packing.h"
#define LIBFAT_SEEK_ORIGIN 0
#define LIBFAT_SEEK_CURRENT 1
#define LIBFAT_SEEK_END 2
typedef os_u32 (*ReadRoutine)(os_u32 amount, void* buffer, void* user_data);
typedef os_u32 (*WriteRoutine)(os_u32 amount, void* buffer, void* user_data);
typedef os_bool (*SeekRoutine)(os_u32 offset, os_u32 direction, void* user_data);
typedef os_u32 (*TellRoutine)(void* user_data);
typedef void (*PrintNumber)(os_u32 number);
typedef void (*PrintRoutine)(os_s8* data, os_u16 size);
typedef struct _FileHandle {
ReadRoutine read;
WriteRoutine write;
SeekRoutine seek;
TellRoutine tell;
void* user_data;
} FileHandle;
OS_PACK_START
struct _FatHeader_12 {
os_u8 jump[3];
os_s8 oem[8];
os_u16 bytes_per_sector;
os_u8 sectors_per_cluster;
os_u16 reserved_sectors;
os_u8 number_of_fats;
os_u16 root_dir_entries;
os_u16 logical_sectors;
os_u8 media_descriptor;
os_u16 sectors_per_fat;
os_u16 sectors_per_track;
os_u16 num_heads;
os_u16 hidden_sectors;
} OS_PACK_MID;
OS_PACK_END
typedef struct _FatHeader_12 FatHeader_12;
OS_PACK_START
struct _FatHeader_16 {
FatHeader_12 base;
os_u16 hidden_sectors_high;
os_u32 total_sectors;
os_u8 drive_number;
os_u8 reserved;
os_u8 extended_signature; //0x28 / 0x29
os_u32 serial;
os_s8 volume_label[11];
os_s8 fat_type[8];
} OS_PACK_END;
OS_PACK_END
typedef struct _FatHeader_16 FatHeader_16;
OS_PACK_START
struct _FatHeader_32 {
FatHeader_12 base;
os_u16 hidden_sectors_high;
os_u32 total_sectors;
os_u32 sectors_per_fat_32;
os_u16 mirror_flags;
os_u16 fs_version;
os_u32 first_root_cluster;
os_u16 fsinfo_sector;
os_u16 backup_boot_location;
os_u8 reserved_fat32[12];
os_u8 logical_drive_number;
os_u8 reserved_winnt;
os_u8 extended_sig_fat32; //0x29
os_u32 serial_number;
os_s8 volume_label[11];
os_s8 fat_type[8];
} OS_PACK_MID;
OS_PACK_END;
#define FAT_READONLY_BIT 1
#define FAT_HIDDEN_BIT 2
#define FAT_SYSTEM_BIT 4
#define FAT_VOLUME_BIT 8
#define FAT_SUBDIRECTORY_BIT 16
#define FAT_ARCHIVE_BIT 32
#define FAT_LAST_CLUSTER_32 0xFFFFFFF8
OS_PACK_START
struct _FatDirectoryEntry {
os_s8 file_name[8];
os_s8 extension[3];
os_s8 attribute;
os_u8 reserved[8];
os_u16 start_cluster_high;
os_u16 time;
os_u16 date;
os_u16 start_cluster;
os_u32 file_size;
} OS_PACK_MID;
OS_PACK_END
typedef struct _FatDirectoryEntry FatDirectoryEntry;
typedef struct _FatHeader_32 FatHeader_32;
typedef struct _FatControlBlock {
FileHandle handle;
FatHeader_32 header;
os_u32 first_loaded_cluster;
os_u32* loaded_fat_segment;
os_u32 loaded_fat_cluster_amount;
} FatControlBlock;
typedef struct _LibFatFile {
FatControlBlock* fat;
FatDirectoryEntry file_entry;
os_u32 current_cluster;
os_u32 position;
os_u32 in_cluster_position;
os_u32 fat_data_offset;
os_u32 fat_cluster_size;
} LibFatFile;
typedef struct _LibFatDirectory {
FatControlBlock* fat;
os_u32 fat_cluster_size;
os_u32 base_cluster;
os_u32 current_cluster;
os_u32 position_in_cluster;
os_bool done;
} LibFatDirectory;
extern os_bool libfat_init(FileHandle handle, void* buffer, os_u32 buffer_size, FatControlBlock* result);
extern os_bool libfat_open_read(FatControlBlock* fat, FatDirectoryEntry* entry, LibFatFile* result);
extern os_u32 libfat_read(LibFatFile* file, void* buffer, os_u32 buffer_size);
extern os_u32 libfat_tell(LibFatFile* file);
extern os_bool libfat_open_directory(FatControlBlock* fat, FatDirectoryEntry* entry, LibFatDirectory* result);
extern void libfat_test(FileHandle image_file, PrintRoutine print, PrintNumber rintNumber);
#endif //!__OS3_LIBFAT_H

272
libfat/libfat.c Normal file
View file

@ -0,0 +1,272 @@
#include "libfat.h"
os_u32 loaded_fat_segment[512];
#define DIRECTORY_BUFFER_SIZE 32
FatDirectoryEntry directory_buffer[DIRECTORY_BUFFER_SIZE];
os_bool libfat_read_header_12(FileHandle handle, FatHeader_12* result) {
handle.seek(0, LIBFAT_SEEK_END, handle.user_data);
os_u32 size = handle.tell(handle.user_data);
if (size < sizeof(FatHeader_12)) {
return OS_FALSE;
}
handle.seek(0, LIBFAT_SEEK_ORIGIN, handle.user_data);
handle.read(sizeof(FatHeader_12), (void*)result, handle.user_data);
return OS_TRUE;
}
os_bool libfat_read_header_32(FileHandle handle, FatHeader_32* result) {
handle.seek(0, LIBFAT_SEEK_END, handle.user_data);
os_u32 size = handle.tell(handle.user_data);
if (size < sizeof(FatHeader_32)) {
return OS_FALSE;
}
handle.seek(0, LIBFAT_SEEK_ORIGIN, handle.user_data);
handle.read(sizeof(FatHeader_32), (void*)result, handle.user_data);
return OS_TRUE;
}
os_bool libfat_img_write_mbr(FileHandle image_file, FileHandle mbr_file) {
return OS_TRUE;
}
os_u32 libfat_img_copy_file(FileHandle image_file, FileHandle file, os_s8* name) {
return 0;
}
os_bool libfat_load_fat_cluster(FatControlBlock* fat, os_u32 target_cluster, os_bool force) {
if (fat->first_loaded_cluster > target_cluster ||
fat->first_loaded_cluster + fat->loaded_fat_cluster_amount <= target_cluster ||
force != OS_FALSE) {
os_u32 fat_size = fat->header.sectors_per_fat_32 * fat->header.base.bytes_per_sector;
os_u32 fat_offset = (fat->header.base.bytes_per_sector * fat->header.base.reserved_sectors) + fat_size;
fat->handle.seek(fat_offset, LIBFAT_SEEK_ORIGIN, fat->handle.user_data);
os_u32 fat_clusters = fat_size / sizeof(os_u32);
if (target_cluster >= fat_clusters) {
return OS_FALSE;
}
os_u32 base_cluster = target_cluster - (target_cluster % fat->loaded_fat_cluster_amount);
os_u32 final_offset = fat_offset + (base_cluster * sizeof(os_u32));
fat->handle.read(fat->loaded_fat_cluster_amount * sizeof(os_u32), (void*)fat->loaded_fat_segment, fat->handle.user_data);
return OS_TRUE;
}
return OS_TRUE;
}
os_u32 libfat_read_cluster(FatControlBlock* fat, os_u32 cluster) {
if(libfat_load_fat_cluster(fat, cluster, OS_FALSE) == OS_FALSE) {
return 0;
}
return fat->loaded_fat_segment[cluster - fat->first_loaded_cluster];
}
os_u32 libfat_load_cluster(FatControlBlock* fat, os_u32 cluster, void* buffer, os_u32 buffer_size, os_u32 offset_in_cluster) {
os_u32 cluster_size = fat->header.base.bytes_per_sector * fat->header.base.sectors_per_cluster;
os_u32 data_offset = (fat->header.base.reserved_sectors + (fat->header.sectors_per_fat_32 * fat->header.base.number_of_fats)) * fat->header.base.bytes_per_sector;
if (offset_in_cluster >= cluster_size) {
return 0;
}
os_u32 cluster_offset = data_offset + ((cluster - 2) * cluster_size) + offset_in_cluster;
os_u32 amount_to_read = cluster_size - offset_in_cluster > buffer_size ? buffer_size : cluster_size - offset_in_cluster;
if(!fat->handle.seek(cluster_offset, LIBFAT_SEEK_ORIGIN, fat->handle.user_data)) {
return 0;
}
os_u32 read = fat->handle.read(amount_to_read, buffer, fat->handle.user_data);
return read;
}
os_bool libfat_open_read(FatControlBlock* fat, FatDirectoryEntry* entry, LibFatFile* result) {
if(result == 0 || fat == 0 || entry == 0) {
return OS_FALSE;
}
if ((entry->attribute & FAT_SYSTEM_BIT) != 0 ||
(entry->attribute & FAT_VOLUME_BIT) != 0) {
return OS_FALSE;
}
result->fat = fat;
result->file_entry = *entry;
result->fat_cluster_size = fat->header.base.sectors_per_cluster * fat->header.base.bytes_per_sector;
result->fat_data_offset = (fat->header.base.reserved_sectors + (fat->header.sectors_per_fat_32 * fat->header.base.number_of_fats)) * fat->header.base.bytes_per_sector;
result->position = 0;
result->current_cluster = (((os_u32)entry->start_cluster_high) << 16) + entry->start_cluster;
result->in_cluster_position = 0;
return OS_TRUE;
}
os_bool libfat_open_directory(FatControlBlock* fat, FatDirectoryEntry* entry, LibFatDirectory* result) {
if (fat == 0 || result == 0) {
return OS_FALSE;
}
if (entry != 0 && (entry->attribute & FAT_SUBDIRECTORY_BIT) == 0) {
return OS_FALSE;
}
result->fat = fat;
result->fat_cluster_size = fat->header.base.sectors_per_cluster * fat->header.base.bytes_per_sector;
result->current_cluster = entry == 0 ? fat->header.first_root_cluster : (((os_u32)entry->start_cluster_high) << 16) + entry->start_cluster;
result->base_cluster = result->current_cluster;
result->position_in_cluster = 0;
result->done = 0;
return OS_TRUE;
}
os_bool libfat_read_directory(LibFatDirectory* dir, FatDirectoryEntry* entry) {
if (dir == 0 || entry == 0) {
return OS_FALSE;
}
if (dir->done == OS_TRUE) {
return OS_FALSE;
}
FatDirectoryEntry my_entry;
os_u32 read = libfat_load_cluster(dir->fat, dir->current_cluster, &my_entry, sizeof(FatDirectoryEntry), dir->position_in_cluster);
dir->position_in_cluster += read;
if (dir->position_in_cluster == dir->fat_cluster_size) {
os_u32 next_cluster = libfat_read_cluster(dir->fat, dir->current_cluster);
if (next_cluster >= FAT_LAST_CLUSTER_32) {
dir->done = OS_TRUE;
}
}
if (my_entry.file_name[0] == '\0') {
dir->done = OS_TRUE;
return OS_FALSE;
}
*entry = my_entry;
return OS_TRUE;
}
os_u32 libfat_read(LibFatFile* file, void* buffer, os_u32 buffer_size) {
os_u32 read = 0;
os_bool eof = file->position >= file->file_entry.file_size ? OS_TRUE : OS_FALSE;
while(read < buffer_size && eof != OS_TRUE) {
os_u32 amount_left = file->file_entry.file_size - file->position;
os_u32 amount_to_read = (buffer_size - read) > amount_left ? amount_left : buffer_size - read;
os_u32 local_read;
if (file->in_cluster_position + amount_to_read >= file->fat_cluster_size) {
local_read = file->fat_cluster_size - file->in_cluster_position;
} else {
local_read = amount_to_read;
}
os_u32 r = libfat_load_cluster(file->fat, file->current_cluster, buffer, local_read, file->in_cluster_position);
read += r;
buffer += r;
file->position += r;
file->in_cluster_position += r;
if (file->in_cluster_position == file->fat_cluster_size) {
file->current_cluster = libfat_read_cluster(file->fat, file->current_cluster);
file->in_cluster_position = 0;
}
if (file->position == file->file_entry.file_size) {
eof = OS_TRUE;
}
}
return read;
}
os_u32 libfat_tell(LibFatFile* file) {
if(file == 0) {
return 0;
}
return file->position;
}
os_bool libfat_init(FileHandle file, void* buffer, os_u32 buffer_size, FatControlBlock* result) {
if(libfat_read_header_32(file, &result->header) != OS_TRUE) {
return OS_FALSE;
}
result->handle = file;
result->loaded_fat_segment = (os_u32*)buffer;
result->loaded_fat_cluster_amount = buffer_size / sizeof(os_u32);
result->first_loaded_cluster = 0;
if(libfat_load_fat_cluster(result, 2, OS_TRUE) != OS_TRUE) {
return OS_FALSE;
}
return OS_TRUE;
}
void libfat_test(FileHandle handle, PrintRoutine print, PrintNumber printNumber) {
FatControlBlock cb;
if (libfat_init(handle, loaded_fat_segment, 512 * sizeof(os_u32), &cb) != OS_TRUE) {
print("Failed to init FAT.", 0);
return;
}
LibFatDirectory dir;
if (libfat_open_directory(&cb, 0, &dir) != OS_TRUE) {
print("Failecd to open directory.", 0);
return;
}
FatDirectoryEntry entry;
while(libfat_read_directory(&dir, &entry) == OS_TRUE) {
if ((entry.attribute & (os_s8)FAT_HIDDEN_BIT) != 0 ||
(entry.attribute & (os_s8)FAT_VOLUME_BIT) != 0 ||
(entry.attribute & (os_s8)FAT_SYSTEM_BIT) != 0) {
continue;
}
print("Entry name: ", 0);
print(entry.file_name, 11);
os_u32 cluster = (((os_u32)entry.start_cluster_high) << 16) + entry.start_cluster;
print("Cluster: ", 0);
printNumber(cluster);
print("Size: ", 0);
printNumber(entry.file_size);
os_u32 effective_size = entry.file_size > 512 ? 512 : entry.file_size;
if(effective_size > 0) {
LibFatFile f;
if (libfat_open_read(&cb, &entry, &f) == OS_TRUE) {
char buffer[512];
os_u32 amount = libfat_read(&f, buffer, 512);
print("Content: ", 0);
print(buffer, amount);
}
}
print("--------", 0);
}
}

3
mbr/CMakeLists.txt Normal file
View file

@ -0,0 +1,3 @@
add_executable(mbr mbr.asm linker.ld)
target_link_options(mbr PRIVATE -T${CMAKE_CURRENT_SOURCE_DIR}/linker.ld)

16
mbr/linker.ld Normal file
View file

@ -0,0 +1,16 @@
ENTRY(_main)
SECTIONS
{
. = 0x7C00;
.text : AT(0x7c00){
*.o(.text);
*.o(.data);
}
.sig : AT(0x7DFE){
SHORT(0xaa55);
}
. = 0x7E00;
.eh_frame : AT(0x7E00){
*.o(.eh_frame);
}
}

125
mbr/mbr.asm Normal file
View file

@ -0,0 +1,125 @@
USE16
NULL equ 0
section .text
global _main
_main:
JMP entry
; FAT32 Header.
global fat_header
fat_header: times 87 db 0
; function READ_SECTORS_EXTENDED: Read sectors from disk
; Uses INT 13h AH=42h from: http://www.ctyme.com/intr/rb-0708.htm
; Stack Parameters (in order of PUSH):
; - BYTE: Drive number
; - WORD: Number of blocks to transfer
; - DWORD: Transfer buffer
; - DWORD: Partial LBA of first block to transfer
; - WORD: RETURN ADDRESS
; Returns:
; AX: 0 = Ok, Other = Error
;
;
; SP + 0: Old BP
; SP + 2: Old SI
; SP + 4: Old DX
; SP + 6: return address
; SP + 8: LBA
; SP + 12: Transfer buffer
; SP + 16: Block
; SP + 18: Drive number
read_sectors_extended:
PUSH DX ; save DX
PUSH SI ; save SI
PUSH BP ; save BP
MOV BP, SP ; estabilish stack frame
MOV AX, [BP + 10] ; load first part of LBA address
MOV [packet_lba], AX ; write fist part of LBA to packet
MOV AX, [BP + 8] ; load second part of LBA to packet
MOV [packet_lba + 2], AX ; write second part of LBA to packet
MOV AX, [BP + 14] ; load first part of transfer buffer
MOV [packet_buffer], AX ; write first part of transfer buffer
MOV AX, [BP + 12] ; load second part of transfer buffer
MOV [packet_buffer + 2], AX ; write second part of transfer buffer
MOV AX, [BP + 16] ; load number of blocks
MOV [packet_blocks], AX ; write number of blocks
MOV DX, 0 ; zero-out DX
MOV DL, [BP + 18] ; load drive number
MOV SI, read_sectors_packet ; load address of packet
MOV AX, 4200h ; set AH to 42h, AL to 0h
INT 13h ; call interrupt 13H, AH=42h
JNC read_sectors_extended_exit ; exit if no error
read_sectors_extended_error: ; save error if it happened
MOV AL, AH ; move error to Al
MOV AH, 0 ; zero-out AH
read_sectors_extended_exit: ; leave function
POP BP ; restore BP
POP SI ; restore SI
POP DX ; restore DX
; function PRINT: teletype to display
; uses INT 10h AH=0Eh from: http://www.ctyme.com/intr/rb-0106.htm
; parameters (in order of PUSH):
; - WORD: address of string
; - WORD: size of string
; returns:
; AX: 0
print:
PUSH BX ; save BX
PUSH CX ; save CX
PUSH BP ; save BP (can change due to scrolling)
MOV BP, SP ; set up stack frame
MOV AH, 0Eh ; load INT 10h parameter
MOV BX, 0 ; zero-out BX (extra parameters)
entry:
; Set up stack and segments
MOV AX, 0 ; set up stack segment
MOV SS, AX ; ^^^
MOV SP, 0x7C00 ; set up stack pointer (0x6c00-x7BFF)
; Sp HAS TO be set in the instruction after settings SS
; as setting SS disables interrupts for the next instruction
; Not doing this may cause an interrupt to use an old SP and new SS
MOV DS, AX ; set up segment registers
MOV ES, AX ; ^^^
MOV FS, AX ; ^^^
MOV GS, AX ; ^^^
PUSH DX ; save drive number (DL)
; Load drive parameters
MOV AX, 4800h ; load AH=48h, AL=0h
MOV SI, disk_info_packet ; load address of Disk_Info_Packet
INT 13H ; INT 14h AH=48h: get drive parameters
section .data
disk_info_packet:
info_size dw 0x1A
info_flags dw 0x0
info_cyls dd 0x0
info_heads dd 0x0
info_sectors dd 0x0
info_total_sec dq 0x0
info_bps dw 0x0
read_sectors_packet:
packet_size db 10h
packet_reserved db 0h
packet_blocks dw 0h
packet_buffer dd 0h
packet_lba dq 0h
build_settings:
build_settings_magic_0 dd 0x49494949
build_settings_bytes dw 0x0
build_settings_magic_1 dd 0x49494949

17
os3_common/datatypes.h Normal file
View file

@ -0,0 +1,17 @@
#ifndef __OS3_DATATYPES_H
#define __OS3_DATATYPES_H
typedef char os_s8;
typedef unsigned char os_u8;
typedef short os_s16;
typedef unsigned short os_u16;
typedef int os_s32;
typedef unsigned int os_u32;
typedef long long os_s64;
typedef unsigned long long os_u64;
typedef int os_bool;
#define OS_FALSE 0
#define OS_TRUE 1
#endif //!__OS3_DATAYPES_H

13
os3_common/packing.h Normal file
View file

@ -0,0 +1,13 @@
#ifndef __OS3_PACKING_H
#define __OS3_PACKING_H
#ifdef __MSC_VER
#define OS_PACK_START #pragma pack(push, 1)
#define OS_PACK_MID
#define OS_PACK_END #pragma pack(pop)
#else
#define OS_PACK_START
#define OS_PACK_MID __attribute__((packed))
#define OS_PACK_END
#endif
#endif //!__OS3_PACKING_H

9
rawimg/CMakeLists.txt Normal file
View file

@ -0,0 +1,9 @@
set(IMAGE_TARGET ${CMAKE_CURRENT_BINARY_DIR}/raw.img)
if (CMAKE_HOST_APPLE)
set(IMAGE_GEN_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/mkimg_macos.sh)
elseif (CMAKE_HOST_UNIX)
set(IMAGE_GEN_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/mkimg_linux.sh)
endif (CMAKE_HOST_APPLE)
add_custom_target(raw_img COMMAND sh ${IMAGE_GEN_SCRIPT} ${IMAGE_TARGET} BYPRODUCTS ${IMAGE_TARGET})

6
rawimg/mkimg_macos.sh Normal file
View file

@ -0,0 +1,6 @@
#!/bin/bash
echo "Generating image $1...."
qemu-img create $1 512M
disk_id=$(hdiutil attach -nomount $1)
newfs_msdos -F 32 -v OS3_BOOT $disk_id
hdiutil detach $disk_id