feat: extend ata with Bitmap
This commit is contained in:
1 parent
ece1767ac9
commit
0c36d813e5
3 files changed
+127
No files matched your search
@@ -0,0 +1,34 @@
|
||||
#ifndef FROSTBYTE_ATA_H
|
||||
#define FROSTBYTE_ATA_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
/*
|
||||
* ATA PIO driver (primary bus, master drive only, LBA28 addressing).
|
||||
*
|
||||
* This talks to real IDE hardware registers (0x1F0-0x1F7 + the 0x3F6
|
||||
* alternate-status/device-control port) using polling, not IRQ14: ataInit
|
||||
* disables the drive's interrupt line (nIEN) up front, so every command is
|
||||
* driven by busy-waiting on the status register. That keeps the driver
|
||||
* usable from the in-kernel test harness, which runs before the scheduler
|
||||
* and with interrupts disabled.
|
||||
*
|
||||
* All polling loops are bounded (ataPollTimeout iterations): a missing or
|
||||
* wedged drive returns false/failure instead of hanging the kernel forever.
|
||||
*/
|
||||
|
||||
#define ataSectorSize 512
|
||||
|
||||
bool ataInit(void);
|
||||
bool ataPresent(void);
|
||||
uint64 ataSectorCount(void);
|
||||
const char* ataModelString(void);
|
||||
|
||||
/* count is a sector count in [0, 255]; 0 trivially succeeds without
|
||||
touching hardware. Both fail (return false) if no drive was found by
|
||||
ataInit, if the request runs past ataSectorCount(), or if the drive
|
||||
reports an error/timeout mid-transfer. */
|
||||
bool ataReadSectors(uint64 lba, uint32 count, void* buffer);
|
||||
bool ataWriteSectors(uint64 lba, uint32 count, const void* buffer);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,37 @@
|
||||
#ifndef FROSTBYTE_BMP_H
|
||||
#define FROSTBYTE_BMP_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
/*
|
||||
* Bitmap: general-purpose fixed-size bitmap over caller-supplied 64-bit
|
||||
* word storage. No heap dependency (the pmm frame allocator uses its own
|
||||
* private copy of this same idea and predates this generic version; this
|
||||
* one is for any other subsystem that needs a bit-indexed set).
|
||||
*/
|
||||
|
||||
typedef struct Bitmap {
|
||||
uint64* words;
|
||||
usize bitCount;
|
||||
} Bitmap;
|
||||
|
||||
/* backingWords must hold at least (bitCount + 63) / 64 uint64 words. */
|
||||
void bmpInit(Bitmap* b, uint64* backingWords, usize bitCount);
|
||||
|
||||
void bmpSet(Bitmap* b, usize index);
|
||||
void bmpClear(Bitmap* b, usize index);
|
||||
bool bmpTest(const Bitmap* b, usize index);
|
||||
|
||||
void bmpSetRange(Bitmap* b, usize start, usize count);
|
||||
void bmpClearRange(Bitmap* b, usize start, usize count);
|
||||
|
||||
void bmpSetAll(Bitmap* b);
|
||||
void bmpClearAll(Bitmap* b);
|
||||
|
||||
usize bmpCountSet(const Bitmap* b);
|
||||
|
||||
/* Returns the index of the first clear/set bit, or -1 if none exists. */
|
||||
isize bmpFindFirstClear(const Bitmap* b);
|
||||
isize bmpFindFirstSet(const Bitmap* b);
|
||||
|
||||
#endif
|
||||
@@ -33,4 +33,60 @@ typedef struct Elf64ProgramHeader {
|
||||
|
||||
uint64 elfLoad(const void* image, uint64 imageSize);
|
||||
|
||||
/* Maps one ELF64 program header's p_flags (segmentFlags: standard PF_X=1/
|
||||
PF_W=2/PF_R=4 bit values) onto the extra paging.h leaf-PTE bits
|
||||
(pageWrite, pageNoExecute) elfLoad passes to pagingMapUserRangeExact for
|
||||
that segment -- real per-segment W^X (a binary's own .text/.rodata ends
|
||||
up read-only+executable, its .data/.bss read-write+non-executable)
|
||||
instead of one blanket writable+executable range for the whole image.
|
||||
Pure address-flag arithmetic, no paging/scheduler/VFS state touched, so
|
||||
it is fully unit-testable (elfTest.c) the same way elfSlotBase and
|
||||
friends already are. */
|
||||
uint64 elfSegmentPagingFlags(uint32 segmentFlags);
|
||||
|
||||
/* Every userspace binary in this kernel is linked (Makefile --defsym
|
||||
USER_BASE=...) at a fixed, elfSlotSize-aligned base of its own, since
|
||||
there is one shared address space system-wide (no per-process page
|
||||
tables/CR3) and no relocation support (-fno-pic): two binaries must
|
||||
simply never overlap. kmain.c's boot-time spawnUser calls hardcode each
|
||||
binary's stack/brk address following the same base+offset pattern by
|
||||
hand; elfSlotStackTop/elfSlotBrkStart let syscall.c's exec()/spawn()
|
||||
(a path resolved at runtime, not known at kmain.c's compile time)
|
||||
derive the same addresses purely from the ELF's own entry point. */
|
||||
#define elfSlotSize 0x10000000ull
|
||||
#define elfSlotStackOffset 0x08000000ull
|
||||
#define elfSlotBrkOffset 0x04000000ull
|
||||
|
||||
uint64 elfSlotBase(uint64 entry);
|
||||
uint64 elfSlotStackTop(uint64 entry);
|
||||
uint64 elfSlotBrkStart(uint64 entry);
|
||||
|
||||
/* Ceiling on argv entries any single exec()/spawn()/boot launch can pass
|
||||
(syscall.c's copyUserArgv enforces the same bound while copying them out
|
||||
of userspace). Chosen together with the 256-byte per-argument cap
|
||||
syscall.c already uses for path-like strings so that
|
||||
elfMaxArgs*256 + a few hundred bytes of pointers/argc never comes close
|
||||
to execStackSize (syscall.c) or kmain.c's userStackSize -- both far
|
||||
larger than any realistic argv list this kernel's own binaries pass. */
|
||||
#define elfMaxArgs 16
|
||||
|
||||
/* Lays out a process's very first stack frame the way a real x86_64 SysV
|
||||
process entry looks (used by user/crt.S's _start): from stackTop down,
|
||||
the argument strings themselves, then (16-byte aligned per the ABI)
|
||||
argc, argv[0..argc-1], and a NULL argv terminator -- *outRsp is where
|
||||
_start should start executing with, pointing at argc.
|
||||
argv/argc are already kernel-side data (copyUserArgv, doExec/doSpawn in
|
||||
syscall.c, or a literal array for kmain.c's boot spawnUser) by the time
|
||||
this runs; this function only ever writes into [stackTop-stackSize,
|
||||
stackTop), which the caller must have already mapped (pagingMapUserRange)
|
||||
-- same contract as elfLoad's segment writes.
|
||||
Returns false, writing nothing, if argc is out of [0, elfMaxArgs] or the
|
||||
strings plus the fixed-size argv/argc area do not fit in stackSize bytes
|
||||
-- unreachable for every call site in this kernel today given the bound
|
||||
above, but checked rather than assumed so a future caller with a bigger
|
||||
argv (or a deliberately tiny stack in elfTest.c) fails cleanly instead of
|
||||
silently writing before stackTop-stackSize. */
|
||||
bool elfBuildInitialStack(uint64 stackTop, uint64 stackSize, const char* const* argv,
|
||||
int argc, uint64* outRsp);
|
||||
|
||||
#endif
|
||||
Reference in new issue
Block a user