Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9d4323ca53 | ||
|
|
dd3bb1e016 |
No files matched your search
@@ -17,6 +17,7 @@ steps:
|
|||||||
|
|
||||||
- name: compile
|
- name: compile
|
||||||
image: t3hn3rd/asuro-build:latest
|
image: t3hn3rd/asuro-build:latest
|
||||||
|
pull: always
|
||||||
depends_on:
|
depends_on:
|
||||||
- build-image
|
- build-image
|
||||||
commands:
|
commands:
|
||||||
|
|||||||
+4
-1
@@ -15,9 +15,12 @@ localenv.json
|
|||||||
dockerout.txt
|
dockerout.txt
|
||||||
AGENTS.md
|
AGENTS.md
|
||||||
lessons_learnt.md
|
lessons_learnt.md
|
||||||
/plan.md
|
|
||||||
*.log
|
*.log
|
||||||
wasuro
|
wasuro
|
||||||
src/core/core.version.pas
|
src/core/core.version.pas
|
||||||
site/*
|
site/*
|
||||||
!site/.gitkeep
|
!site/.gitkeep
|
||||||
|
/src/boot/dangling_units.inc
|
||||||
|
/lib/dangling/
|
||||||
|
.moderne
|
||||||
|
CLAUDE.md
|
||||||
+3
-3
@@ -1,4 +1,5 @@
|
|||||||
FROM ubuntu:latest
|
ARG RECIPES_IMAGE=t3hn3rd/moderne-asuro-recipes:0.1.1@sha256:eaf54188053511dad9c620a8fb98b0f50c41770cd49a0b3d71a0538386522011
|
||||||
|
FROM ${RECIPES_IMAGE}
|
||||||
|
|
||||||
VOLUME ["/code"]
|
VOLUME ["/code"]
|
||||||
|
|
||||||
@@ -7,7 +8,7 @@ RUN dpkg --add-architecture i386
|
|||||||
RUN apt-get update && apt-get install -y \
|
RUN apt-get update && apt-get install -y \
|
||||||
curl dos2unix wget git make nasm binutils xorriso grub-pc-bin gcc gcc-multilib \
|
curl dos2unix wget git make nasm binutils xorriso grub-pc-bin gcc gcc-multilib \
|
||||||
python3 python3-pip python3-pil && \
|
python3 python3-pip python3-pil && \
|
||||||
apt-get clean my room
|
apt-get clean && rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
RUN pip3 install --no-cache-dir --break-system-packages "mkdocs>=1.6,<2" mkdocs-material
|
RUN pip3 install --no-cache-dir --break-system-packages "mkdocs>=1.6,<2" mkdocs-material
|
||||||
|
|
||||||
@@ -20,6 +21,5 @@ RUN curl -sL https://sourceforge.net/projects/freepascal/files/Linux/$FPC_VERSIO
|
|||||||
ADD https://raw.githubusercontent.com/fsaintjacques/semver-tool/master/src/semver /usr/bin/semver
|
ADD https://raw.githubusercontent.com/fsaintjacques/semver-tool/master/src/semver /usr/bin/semver
|
||||||
RUN chmod +x /usr/bin/semver
|
RUN chmod +x /usr/bin/semver
|
||||||
WORKDIR /code
|
WORKDIR /code
|
||||||
RUN find . -type f -print0 | xargs -0 dos2unix
|
|
||||||
ENTRYPOINT ["/bin/bash", "-c"]
|
ENTRYPOINT ["/bin/bash", "-c"]
|
||||||
CMD ["find toolchain -name '*.sh' -exec dos2unix {} + 2>/dev/null; find toolchain -name '*.sh' -exec chmod +x {} +; bash toolchain/compile.sh"]
|
CMD ["find toolchain -name '*.sh' -exec dos2unix {} + 2>/dev/null; find toolchain -name '*.sh' -exec chmod +x {} +; bash toolchain/compile.sh"]
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
**/.git
|
||||||
|
**/.gradle
|
||||||
|
**/build
|
||||||
|
**/.moderne
|
||||||
|
wasuro
|
||||||
|
site
|
||||||
|
lib
|
||||||
|
release
|
||||||
@@ -1,68 +1,49 @@
|
|||||||
# USB mass storage
|
# driver.storage.ctl.usb
|
||||||
|
|
||||||
`driver.storage.ctl.usb` implements SCSI transparent commands over USB Mass
|
USB Mass Storage Class driver stub.
|
||||||
Storage Bulk-Only Transport (interface class/subclass/protocol `08/06/50`).
|
|
||||||
|
|
||||||
It probes INQUIRY, TEST UNIT READY and READ CAPACITY(10), registers LUN 0 with
|
## Overview
|
||||||
the storage manager, and exposes READ(10), WRITE(10), REQUEST SENSE and
|
|
||||||
SYNCHRONIZE CACHE(10). Existing partition discovery and filesystem mounting
|
|
||||||
apply to the resulting USB disk. Writes complete only after cache synchronization.
|
|
||||||
|
|
||||||
## Execution and ownership
|
This unit registers a USB class driver with the driver manager (`driver.mgr`) to claim USB Mass Storage Class interfaces (class `$08`, subclass `$06` SCSI, protocol `$50` Bulk-Only). When the USB stack enumerates a matching interface, the `load` callback is invoked. Currently the callback only logs a detection message; no I/O infrastructure is established.
|
||||||
|
|
||||||
An attachment task probes and registers each disk after scheduling starts; boot
|
Full Bulk-Only Transport (BOT) support — including Max LUN query, endpoint setup, CBW/CSW command exchange, and `driver.storage.mgr` device registration — is planned but not yet implemented.
|
||||||
initialization never waits on a worker that cannot run yet.
|
|
||||||
|
|
||||||
Storage dispatch only publishes a request. One persistent `usb.storage` worker
|
## Boot Registration
|
||||||
performs I/O in task context, with one command active per device and a reusable,
|
|
||||||
page-aligned 4 KiB bounce buffer. Caller buffers are never submitted for DMA.
|
|
||||||
Commands are split at the bounce-buffer boundary; all LBA/count and buffer-end
|
|
||||||
arithmetic is checked before submission. CBW/CSW wire sizes, tags, status,
|
|
||||||
residue, and actual transfer lengths are validated.
|
|
||||||
|
|
||||||
OHCI batches bulk data into spans of at most 4 KiB per transfer descriptor,
|
Registered with `boot.mgr` as `driver.storage.ctl.usb` at the `device` barrier. The barrier order places `device` after `bus`, ensuring `driver.bus.usb.core.init` has run before the storage class driver registers with the driver manager.
|
||||||
using the endpoint's hardware toggle carry across packets. A 4 KiB full-speed
|
|
||||||
read uses one data descriptor instead of 64. Short packets still halt the chain
|
|
||||||
and report the actual byte count; interrupt endpoint packet sizing is unchanged.
|
|
||||||
|
|
||||||
The worker performs reset recovery (class reset, clear bulk-IN halt, clear
|
## Dependencies
|
||||||
bulk-OUT halt) after malformed status or phase errors. Failed SCSI commands
|
|
||||||
request sense and return storage errors, including write protection.
|
|
||||||
|
|
||||||
On disconnect the disk is marked removed immediately. Accepted requests are
|
- `boot.mgr`
|
||||||
completed with errors, and idle volumes are invalidated/unmounted by the worker;
|
|
||||||
busy volumes are retried. Storage-manager records remain stable tombstones.
|
|
||||||
Class-driver buffers and context are freed after pending hardware work drains.
|
|
||||||
|
|
||||||
Host controllers currently have no cancellation API. A timed-out transfer is
|
- `driver.mgr`
|
||||||
therefore quarantined with its private device snapshot and DMA memory. No further
|
- `memory.heap`
|
||||||
commands are issued to that device. If hardware never completes, those allocations
|
- `driver.storage.types`
|
||||||
remain retained until reboot; freeing them would permit DMA into reused memory.
|
- `io.syslog`
|
||||||
The timeout uses the PIT's actual frequency and a bounded polling fallback.
|
- `debug.tracer`
|
||||||
|
- `driver.bus.usb.core`
|
||||||
|
- `driver.bus.usb.types`
|
||||||
|
- `core.util`, `arch.x86.util`
|
||||||
|
|
||||||
## Supported scope
|
## Constants
|
||||||
|
|
||||||
- LUN 0 on a single-interface device with one bulk-IN and one bulk-OUT endpoint.
|
| Constant | Value | Description |
|
||||||
- Direct-access disks with power-of-two sectors from 512 through 4096 bytes.
|
|---|---|---|
|
||||||
- Capacity representable by the existing 32-bit storage-sector API; the
|
| `USB_CLASS_MASS_STORAGE` | `$08` | USB interface class for mass storage |
|
||||||
READ CAPACITY(16) sentinel is rejected.
|
| `USB_SC_SCSI` | `$06` | SCSI transparent command set subclass |
|
||||||
- OHCI, EHCI and xHCI bulk transfers. OHCI/EHCI report actual data lengths and
|
| `USB_PROTO_BBB` | `$50` | Bulk-Only (BOT) transport protocol |
|
||||||
terminate bulk reads on short packets.
|
|
||||||
|
|
||||||
UAS, additional LUNs, composite/alternate-setting interfaces, UHCI storage,
|
## Functions and Procedures
|
||||||
optical devices, and media replacement without USB reconnect are not supported.
|
|
||||||
The current xHCI driver lacks endpoint-ring reset support: a halted bulk endpoint
|
|
||||||
fails the device closed rather than attempting an unsafe ring reuse.
|
|
||||||
|
|
||||||
## Validation
|
### init
|
||||||
|
|
||||||
`UnitTest` is called by the boot test suite and is available as `USBMSCTEST`.
|
```pascal
|
||||||
Tests use a memory-only mock host controller: wire layout, byte order, capacity
|
procedure init;
|
||||||
limits, reads, writes, sense errors, short transfers, status stalls, reset ordering,
|
```
|
||||||
and request bounds. They perform no disk I/O.
|
|
||||||
|
|
||||||
For hardware/VM checks, boot with a disposable USB disk, confirm `USBMSC` discovery
|
Constructs a `TDeviceIdentifier` matching any USB device with `bInterfaceClass = $08`, `bInterfaceSubClass = $06`, `bInterfaceProtocol = $50`, and registers the `load` callback with `driver.mgr`.
|
||||||
and filesystem mounting, test file read/write/read-back, then unplug while idle
|
|
||||||
and during I/O. Do not run destructive disk tests against a disk containing data.
|
|
||||||
|
|
||||||
Protocol: [USB-IF Bulk-Only Transport 1.0](https://www.usb.org/sites/default/files/usbmassbulk_10.pdf).
|
## Notes
|
||||||
|
|
||||||
|
- The `load` callback currently returns true unconditionally after logging a detection message.
|
||||||
|
- Once full BOT support is implemented, `load` should query the Max LUN, allocate endpoint structures, and call `driver.storage.mgr.register_device` for each logical unit.
|
||||||
@@ -14,7 +14,7 @@ The I/O model operates as follows:
|
|||||||
- `storage_read` / `storage_write` are convenience wrappers that build a stack-local `TIORequest` and call `submit_io_wait`.
|
- `storage_read` / `storage_write` are convenience wrappers that build a stack-local `TIORequest` and call `submit_io_wait`.
|
||||||
- `storage_read_async` / `storage_write_async` build and submit a request with a caller-supplied callback, returning immediately.
|
- `storage_read_async` / `storage_write_async` build and submit a request with a caller-supplied callback, returning immediately.
|
||||||
|
|
||||||
Blocking callers use `storage_read` / `storage_write` and check the returned `TError`.
|
Legacy `storage_read_legacy` / `storage_write_legacy` procedure wrappers are retained for callers not yet migrated to the function-returning API.
|
||||||
|
|
||||||
## Dependencies
|
## Dependencies
|
||||||
|
|
||||||
@@ -205,42 +205,17 @@ function storage_write_async(device : PStorage_Device; addr : uint32; sectors :
|
|||||||
|
|
||||||
Non-blocking write. Analogous to `storage_read_async`.
|
Non-blocking write. Analogous to `storage_read_async`.
|
||||||
|
|
||||||
|
### storage_read_legacy / storage_write_legacy
|
||||||
|
|
||||||
|
```pascal
|
||||||
|
procedure storage_read_legacy(device : PStorage_Device; addr : uint32; sectors : uint32; buffer : puint32);
|
||||||
|
procedure storage_write_legacy(device : PStorage_Device; addr : uint32; sectors : uint32; buffer : puint32);
|
||||||
|
```
|
||||||
|
|
||||||
|
Drop-in procedure replacements for callers using the old void-returning API. Forward to `storage_read` / `storage_write` and discard the error code. Marked for removal once all callers are migrated.
|
||||||
|
|
||||||
## Notes
|
## Notes
|
||||||
|
|
||||||
- `dispatch_next` is an internal procedure called with interrupts disabled. It dequeues the head of the CFIFO, allocates a heap copy via `ioreq_copy` (for ISR safety), and invokes the appropriate `dispatchRead` or `dispatchWrite` on the device. If neither dispatch pointer is set, the request is failed with `eDeviceNotFound`.
|
- `dispatch_next` is an internal procedure called with interrupts disabled. It dequeues the head of the CFIFO, allocates a heap copy via `ioreq_copy` (for ISR safety), and invokes the appropriate `dispatchRead` or `dispatchWrite` on the device. If neither dispatch pointer is set, the request is failed with `eDeviceNotFound`.
|
||||||
- The blocking path relies on pointer-dereferenced spin (`puint32(@wait.Done)^`) to prevent FPC from caching the `Done` flag in a register across the `hlt` instruction.
|
- The blocking path relies on pointer-dereferenced spin (`puint32(@wait.Done)^`) to prevent FPC from caching the `Done` flag in a register across the `hlt` instruction.
|
||||||
- Devices without `dispatchRead`/`dispatchWrite` set (i.e., drivers not yet migrated to Phase 2) will have `submit_io` return `eDeviceNotFound`. Legacy drivers must be migrated before they can use the new I/O path.
|
- Devices without `dispatchRead`/`dispatchWrite` set (i.e., drivers not yet migrated to Phase 2) will have `submit_io` return `eDeviceNotFound`. Legacy drivers must be migrated before they can use the new I/O path.
|
||||||
|
|
||||||
|
|
||||||
## Bounded performance path
|
|
||||||
|
|
||||||
The manager merges up to 32 consecutive queued requests when operation, device,
|
|
||||||
LBA range, and virtual buffer range are contiguous. It never searches past the
|
|
||||||
queue head or delays a lone request to create a merge. Drivers opt in through
|
|
||||||
`mergeMaxSectors`; SATA AHCI advertises 65,536 sectors, while other drivers default
|
|
||||||
to zero (disabled). A merged command delivers one completion to each original
|
|
||||||
request, in FIFO order. A command error fails every member conservatively.
|
|
||||||
|
|
||||||
`storage_get_stats` takes an interrupt-protected snapshot of the device counters.
|
|
||||||
`DISK info <index>` displays accepted/completed/failed logical requests, hardware
|
|
||||||
commands, merged requests, queue-full rejections, queue and active high-water
|
|
||||||
marks, successful read/write sectors, request-size buckets, queue/service ticks,
|
|
||||||
and FAT metadata cache hits/misses. Queue ticks are accumulated per logical
|
|
||||||
request; service ticks are accumulated per hardware command. Tick values use
|
|
||||||
`Counters.c32`, not milliseconds. Counters are unsigned 32-bit values, start at
|
|
||||||
device registration, and wrap; use snapshot differences over bounded benchmark
|
|
||||||
intervals. Size buckets are <=8, 9..256, and >256 sectors.
|
|
||||||
|
|
||||||
FAT32 blocking and async reads share a pooled transfer engine with batches of up
|
|
||||||
to four outstanding reads, capped by device queue depth. Destination slices are
|
|
||||||
disjoint. On any error, the engine drains every accepted request before releasing
|
|
||||||
its context and reports only the contiguous successful byte prefix. Unaligned
|
|
||||||
edges and odd DMA addresses use the context's private scratch sector. Writes
|
|
||||||
remain sequential. Run maps store cumulative file-cluster offsets; an open-file
|
|
||||||
cursor handles sequential locality and binary search handles random seeks.
|
|
||||||
|
|
||||||
`STORPERF` runs memory-backed regression checks (also included in boot unit tests)
|
|
||||||
for reverse completion order, failures, unaligned reads, run lookup, queue
|
|
||||||
rejection, merging limits, and callback accounting. It does not access real disks
|
|
||||||
or measure hardware throughput. Compare counters alongside `STORBENCH` and file
|
|
||||||
benchmarks on contiguous and fragmented files for actual performance validation.
|
|
||||||
@@ -58,111 +58,3 @@ Registers the `STORTEST` and `DISKTEST` shell commands with `io.stdio`. Must be
|
|||||||
- `run_tests` exercises `makeAbsolutePathFrom`, `resolvePathFrom`, `changeDirectoryFrom`, `GetDirectoryListingFrom`, `newVirtualDirectory`, and `PathValid` including `.` and `..` traversal.
|
- `run_tests` exercises `makeAbsolutePathFrom`, `resolvePathFrom`, `changeDirectoryFrom`, `GetDirectoryListingFrom`, `newVirtualDirectory`, and `PathValid` including `.` and `..` traversal.
|
||||||
- `run_disk_tests` is destructive and will irreversibly wipe the partition table of disk 0. It is never called automatically.
|
- `run_disk_tests` is destructive and will irreversibly wipe the partition table of disk 0. It is never called automatically.
|
||||||
- The `Assert` helper used in both procedures increments `passed` or `failed` counters and logs the test name on failure; passing tests produce no output to avoid noise.
|
- The `Assert` helper used in both procedures increments `passed` or `failed` counters and logs the test name on failure; passing tests produce no output to avoid noise.
|
||||||
|
|
||||||
|
|
||||||
## Raw read benchmark
|
|
||||||
|
|
||||||
`STORBENCH` is implemented and registered by `driver.storage.bench`. It performs
|
|
||||||
read-only raw-device I/O; it does not invoke the destructive `DISKTEST` path.
|
|
||||||
|
|
||||||
```text
|
|
||||||
STORBENCH [disk] [MiB]
|
|
||||||
STORBENCH list
|
|
||||||
STORBENCH run [disk] [MiB] [KiB/request] [depth] [seq|random] [start_lba]
|
|
||||||
STORBENCH compare [disk] [MiB]
|
|
||||||
STORBENCH help
|
|
||||||
```
|
|
||||||
|
|
||||||
Manual (`run`) defaults are disk 0, 128 MiB, 1024 KiB/request, sequential reads, and a depth of
|
|
||||||
`min(4, hardware depth)` (at least one). Examples:
|
|
||||||
|
|
||||||
```text
|
|
||||||
STORBENCH 0 128 64 4
|
|
||||||
STORBENCH 0 128 4 16 random
|
|
||||||
STORBENCH 0 256 1024 1 seq 2048
|
|
||||||
STORBENCH compare 0 128
|
|
||||||
```
|
|
||||||
|
|
||||||
The comparison runs sequential reads at 4, 64, and 1024 KiB/request, each at depths
|
|
||||||
1, 4, 16, and 32. The MiB argument applies to each of the twelve cases. Queue depth
|
|
||||||
may exceed hardware depth to expose software queuing and request merging.
|
|
||||||
|
|
||||||
Limits are 1..16384 MiB, 1..1024 KiB/request, and depth 1..32. Request size must be
|
|
||||||
an exact number of device sectors. Buffers are allocated once per case, with a
|
|
||||||
separate slice for every outstanding request and a maximum total size of 32 MiB.
|
|
||||||
The transfer range is clamped to the device. Without an explicit LBA, reads start
|
|
||||||
at sector 2048 when the full requested range fits there; otherwise they start at
|
|
||||||
zero. Random mode uses a fixed xorshift seed and samples that range with replacement,
|
|
||||||
so total bytes read are bounded but unique coverage is not guaranteed.
|
|
||||||
|
|
||||||
Reports include successful bytes, elapsed microseconds, MiB/s, IOPS, accepted and
|
|
||||||
completed request counts, peak outstanding requests, average/p95/max completion
|
|
||||||
latency, and per-run storage-counter deltas. Latencies are measured from submission
|
|
||||||
to callback. The p95 is an upper bound from logarithmic microsecond buckets, not an exact
|
|
||||||
microsecond percentile. Runs shorter than 10 ms are excluded from suite speed comparisons.
|
|
||||||
No console output occurs inside the measured loop. Any failure stops new work;
|
|
||||||
already accepted DMA is drained before buffers are freed, and failed requests
|
|
||||||
contribute no bytes or successful IOPS.
|
|
||||||
|
|
||||||
Timing prefers the Hyper-V-compatible VM reference counter (100 ns ticks), detected
|
|
||||||
through its Hv#1 interface and reference-counter privilege. It needs no calibration.
|
|
||||||
Other platforms use an invariant TSC calibrated against two complete RTC seconds,
|
|
||||||
with up to three attempts to tolerate transient RTC updates or scheduling delays.
|
|
||||||
Calibration requires agreement within 1%; failures include the specific reason.
|
|
||||||
Unlike delivered timer interrupts, this clock advances while interrupts are masked.
|
|
||||||
Queue submission restores interrupts between requests. Filesystem caches are
|
|
||||||
bypassed, but drive and virtual-machine/host caches may still affect results.
|
|
||||||
Virtual or sparse disks can report throughput above physical-media speed.
|
|
||||||
Device counter deltas may include concurrent I/O from other processes;
|
|
||||||
benchmark-owned byte, request, and latency counters do not.
|
|
||||||
|
|
||||||
`driver.storage.bench.UnitTest` runs memory-only parser, arithmetic, range,
|
|
||||||
queue-depth, completion-order, and error-accounting tests at boot. It never reads
|
|
||||||
or writes a real disk. The clock tests also verify that an advertised VM reference
|
|
||||||
counter advances with interrupts masked; they never calibrate the RTC at boot.
|
|
||||||
|
|
||||||
|
|
||||||
### Automatic suite and table output
|
|
||||||
|
|
||||||
`STORBENCH` without arguments, or `STORBENCH auto [disk] [MiB]`, runs six
|
|
||||||
read-only profiles. Auto defaults to disk 0 and **32 MiB per profile** (up to
|
|
||||||
192 MiB total before device-size clamping). One or two numeric arguments select the auto suite: `STORBENCH 2 512` tests
|
|
||||||
disk 2 with 512 MiB per profile. `STORBENCH list` lists disk indices, capacities,
|
|
||||||
controllers, sector sizes, and hardware queue depths. Three or more numeric
|
|
||||||
arguments retain the legacy manual syntax; `run` selects manual mode explicitly.
|
|
||||||
|
|
||||||
| Profile | Request size | Queue depth |
|
|
||||||
| --- | --- | --- |
|
|
||||||
| Seq large | 1024 KiB | 1 |
|
|
||||||
| Seq queued | 1024 KiB | queued |
|
|
||||||
| Seq medium | 64 KiB | queued |
|
|
||||||
| Random small | 4 KiB | 1 |
|
|
||||||
| Random queued | 4 KiB | queued |
|
|
||||||
| Random medium | 64 KiB | queued |
|
|
||||||
|
|
||||||
Queued depth is the device hardware depth clamped to 4..16, allowing software
|
|
||||||
queue testing even on serial devices. A request smaller than a device sector is
|
|
||||||
increased to one sector. Each profile samples the same byte-span size, with the
|
|
||||||
existing fixed random seed and range clamping rules.
|
|
||||||
|
|
||||||
Auto and compare modes print an aligned ASCII table with request KiB, queue
|
|
||||||
depth, MiB/s, IOPS, average latency, p95 latency upper bound, and status. Rows are
|
|
||||||
printed outside the measured loop. Successful runs shorter than 10 ms show `-` metrics and
|
|
||||||
`SHORT`, and are excluded from best-result and queue-gain summaries. Errors show
|
|
||||||
`FAILED`, stop the suite after accepted DMA has drained, and leave remaining
|
|
||||||
profiles unrun. The summary includes successful profiles, bytes actually read,
|
|
||||||
measured time, best sequential throughput, peak random IOPS, and (in auto mode)
|
|
||||||
queued/QD1 throughput ratios. These ratios describe the measured cases, including
|
|
||||||
any controller-cache effects; they are not a hardware rating.
|
|
||||||
|
|
||||||
```text
|
|
||||||
STORBENCH
|
|
||||||
STORBENCH list
|
|
||||||
STORBENCH 2 512
|
|
||||||
STORBENCH auto 0 64
|
|
||||||
STORBENCH compare 0 32
|
|
||||||
```
|
|
||||||
|
|
||||||
Profiles reuse the same raw device range. Host/drive caches are not flushed, so
|
|
||||||
later profiles may read warm data. These results are observed raw read throughput,
|
|
||||||
not a claim of uncached physical-media performance.
|
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
# Automatic boot-unit inclusion
|
||||||
|
|
||||||
|
Run the usual `docker compose build builder` and `docker compose run builder`
|
||||||
|
from Asuro. Only this repository is required. Compose and Drone use the same
|
||||||
|
Dockerfile and repository build context, producing `t3hn3rd/asuro-build:latest`.
|
||||||
|
The Dockerfile inherits the published `t3hn3rd/moderne-asuro-recipes:0.1.1` image,
|
||||||
|
pinned by digest. It already includes Java, Moderne CLI, the Pascal LST generator,
|
||||||
|
and the registered recipe. The Asuro layer installs FPC and the kernel build tools.
|
||||||
|
|
||||||
|
To upgrade tooling, publish the upstream images first and update `RECIPES_IMAGE`
|
||||||
|
in the Dockerfile to the new tag and digest. Local tooling image testing can use
|
||||||
|
`docker compose build --build-arg RECIPES_IMAGE=<local-tag> builder`.
|
||||||
|
|
||||||
|
`ASURO_ARCH` selects the source architecture, defaulting to `x86`. For example:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
export ASURO_ARCH=x86
|
||||||
|
docker compose run --rm builder
|
||||||
|
```
|
||||||
|
|
||||||
|
Compose forwards this variable to the builder; Drone inherits it from its compile
|
||||||
|
environment. Only `src/arch/$ASURO_ARCH` is added to FPC's unit search paths.
|
||||||
|
Other architecture folders are excluded from LST generation and from the recipe's
|
||||||
|
dependency graph and results. Common units outside `src/arch` remain eligible.
|
||||||
|
The selected architecture folder must exist. This source selection does not
|
||||||
|
change the existing i386 compiler target, assembly stub, or linker settings;
|
||||||
|
an x86_64 port still needs those platform-specific changes.
|
||||||
|
|
||||||
|
`compile_dangling.sh` runs after Wasuro synchronization and before FPC. It copies
|
||||||
|
only `src/` and `compat/` into an isolated temporary analysis repository, generates
|
||||||
|
LSTs with rewrite-pascal, runs the standalone Moderne recipe, exports its
|
||||||
|
datatable, and writes `src/boot/dangling_units.inc`. Wasuro is not parsed.
|
||||||
|
Datatable conversion is provided by the standalone project's Java exporter.
|
||||||
|
Parse errors, recipe failures, and malformed datatables stop the build. The
|
||||||
|
generated include is ignored by Git and removed before each generation attempt.
|
||||||
|
|
||||||
|
Use `{$DEFINE NOT_DANGLING}` near a unit declaration to exclude an experimental
|
||||||
|
or legacy unit from automatic inclusion. It can still be referenced normally.
|
||||||
|
This is a file-level marker; conditional definitions are not evaluated. The
|
||||||
|
analysis follows both interface and implementation uses, without expanding
|
||||||
|
includes or evaluating conditional compilation.
|
||||||
|
|
||||||
|
Moderne runs through its CLI normally; any license or tenant configuration
|
||||||
|
required by your CLI installation must be provided to the container separately.
|
||||||
|
No host credentials are copied into the image.
|
||||||
@@ -1,5 +1,8 @@
|
|||||||
services:
|
services:
|
||||||
builder:
|
builder:
|
||||||
|
image: t3hn3rd/asuro-build:latest
|
||||||
build: .
|
build: .
|
||||||
|
environment:
|
||||||
|
ASURO_ARCH: ${ASURO_ARCH:-x86}
|
||||||
volumes:
|
volumes:
|
||||||
- .:/code
|
- .:/code
|
||||||
@@ -283,6 +283,7 @@ nav:
|
|||||||
- Version Generation: toolchain/compile_vergen.md
|
- Version Generation: toolchain/compile_vergen.md
|
||||||
- LVGL Compilation: toolchain/compile_lvgl.md
|
- LVGL Compilation: toolchain/compile_lvgl.md
|
||||||
- Wasuro Pull: toolchain/compile_wasuro.md
|
- Wasuro Pull: toolchain/compile_wasuro.md
|
||||||
|
- Automatic Boot Units: toolchain/dangling_units.md
|
||||||
- Source List: toolchain/compile_sourcelist.md
|
- Source List: toolchain/compile_sourcelist.md
|
||||||
- Source Compilation: toolchain/compile_sources.md
|
- Source Compilation: toolchain/compile_sources.md
|
||||||
- Checksum: toolchain/compile_checksum.md
|
- Checksum: toolchain/compile_checksum.md
|
||||||
|
|||||||
@@ -28,7 +28,8 @@ We welcome everyone to give building/breaking/fixing/shooting Asuro a go, feel f
|
|||||||
4. Install Git for Windows.
|
4. Install Git for Windows.
|
||||||
5. Install VSCode & the listed plugins.
|
5. Install VSCode & the listed plugins.
|
||||||
6. Install VirtualBox (v7+).
|
6. Install VirtualBox (v7+).
|
||||||
7. Clone this repository.
|
7. Clone this repository. The builder inherits the published Moderne/Pascal
|
||||||
|
tooling image; see [boot-unit generation](doc/toolchain/dangling_units.md).
|
||||||
8. Run the following command in the root of the repo to build the docker image:
|
8. Run the following command in the root of the repo to build the docker image:
|
||||||
```powershell
|
```powershell
|
||||||
docker compose build builder
|
docker compose build builder
|
||||||
|
|||||||
@@ -150,7 +150,6 @@ var
|
|||||||
device : PStorage_Device;
|
device : PStorage_Device;
|
||||||
volCount : uint32;
|
volCount : uint32;
|
||||||
freeSec : uint32;
|
freeSec : uint32;
|
||||||
stats : TStorageStats;
|
|
||||||
begin
|
begin
|
||||||
if paramCount(params) < 2 then begin
|
if paramCount(params) < 2 then begin
|
||||||
println('Usage: DISK info <disk>');
|
println('Usage: DISK info <disk>');
|
||||||
@@ -192,16 +191,6 @@ begin
|
|||||||
else
|
else
|
||||||
volCount := 0;
|
volCount := 0;
|
||||||
print('Partitions: '); printint(volCount); println('');
|
print('Partitions: '); printint(volCount); println('');
|
||||||
storage_get_stats(device,stats);
|
|
||||||
print('I/O submitted/completed/failed: '); printint(stats.Submitted); print(' / '); printint(stats.Completed); print(' / '); printint(stats.Failed); println('');
|
|
||||||
print('Commands / merged requests: '); printint(stats.Commands); print(' / '); printint(stats.Merged); println('');
|
|
||||||
print('Queue peak / active peak / queue full: '); printint(stats.QueuePeak); print(' / '); printint(stats.ActivePeak); print(' / '); printint(stats.QueueFull); println('');
|
|
||||||
print('Read / written sectors: '); printint(stats.ReadSectors); print(' / '); printint(stats.WriteSectors); println('');
|
|
||||||
print('Requests <=8 / <=256 / >256 sectors: '); printint(stats.SmallRequests); print(' / '); printint(stats.MediumRequests); print(' / '); printint(stats.LargeRequests); println('');
|
|
||||||
print('Queue ticks total / max: '); printint(stats.QueueTicks); print(' / '); printint(stats.MaxQueueTicks); println('');
|
|
||||||
print('Service ticks total / max: '); printint(stats.ServiceTicks); print(' / '); printint(stats.MaxServiceTicks); println('');
|
|
||||||
print('FAT cache hits / misses: '); printint(stats.FatCacheHits); print(' / '); printint(stats.FatCacheMisses); println('');
|
|
||||||
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ ---------- DISK WIPE ---------- }
|
{ ---------- DISK WIPE ---------- }
|
||||||
|
|||||||
+163
-638
File diff suppressed because it is too large.
Load diff
@@ -195,7 +195,6 @@ procedure do_refresh_load(state: PFileBrowserState); forward;
|
|||||||
procedure do_refresh_build(state: PFileBrowserState); forward;
|
procedure do_refresh_build(state: PFileBrowserState); forward;
|
||||||
procedure schedule_refresh(state: PFileBrowserState); forward;
|
procedure schedule_refresh(state: PFileBrowserState); forward;
|
||||||
procedure fb_refresh_poll_cb(tmr: Plv_timer); cdecl; forward;
|
procedure fb_refresh_poll_cb(tmr: Plv_timer); cdecl; forward;
|
||||||
function fb_error_name(err : TError) : pchar; forward;
|
|
||||||
procedure fb_collect_cb(key: pchar; data: void; ud: void); forward;
|
procedure fb_collect_cb(key: pchar; data: void; ud: void); forward;
|
||||||
procedure do_refresh(state: PFileBrowserState); forward;
|
procedure do_refresh(state: PFileBrowserState); forward;
|
||||||
procedure navigate_to(state: PFileBrowserState; newDir: pchar); forward;
|
procedure navigate_to(state: PFileBrowserState; newDir: pchar); forward;
|
||||||
@@ -583,51 +582,6 @@ begin
|
|||||||
puint32(@state^.refresh_pending)^ := 1;
|
puint32(@state^.refresh_pending)^ := 1;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function fb_error_name(err : TError) : pchar;
|
|
||||||
begin
|
|
||||||
case err of
|
|
||||||
eNone: fb_error_name := 'eNone';
|
|
||||||
eUnknown: fb_error_name := 'eUnknown';
|
|
||||||
eNotSupported: fb_error_name := 'eNotSupported';
|
|
||||||
eOutOfMemory: fb_error_name := 'eOutOfMemory';
|
|
||||||
eInvalidArgument: fb_error_name := 'eInvalidArgument';
|
|
||||||
eFileInUse: fb_error_name := 'eFileInUse';
|
|
||||||
eFileDoesNotExist: fb_error_name := 'eFileDoesNotExist';
|
|
||||||
eInvalidFileName: fb_error_name := 'eInvalidFileName';
|
|
||||||
eInvalidFileExtension: fb_error_name := 'eInvalidFileExtension';
|
|
||||||
eFilenameTooLong: fb_error_name := 'eFilenameTooLong';
|
|
||||||
eDirectoryDoesNotExist: fb_error_name := 'eDirectoryDoesNotExist';
|
|
||||||
eDirectoryAlreadyExists: fb_error_name := 'eDirectoryAlreadyExists';
|
|
||||||
eDirectoryNotEmpty: fb_error_name := 'eDirectoryNotEmpty';
|
|
||||||
eDirectoryFull: fb_error_name := 'eDirectoryFull';
|
|
||||||
eNotADirectory: fb_error_name := 'eNotADirectory';
|
|
||||||
eWriteOnly: fb_error_name := 'eWriteOnly';
|
|
||||||
eReadOnly: fb_error_name := 'eReadOnly';
|
|
||||||
ePermissionDenied: fb_error_name := 'ePermissionDenied';
|
|
||||||
eInvalidPath: fb_error_name := 'eInvalidPath';
|
|
||||||
eTooManyOpenFiles: fb_error_name := 'eTooManyOpenFiles';
|
|
||||||
eInvalidHandle: fb_error_name := 'eInvalidHandle';
|
|
||||||
eFileNotLoaded: fb_error_name := 'eFileNotLoaded';
|
|
||||||
eAlreadyExists: fb_error_name := 'eAlreadyExists';
|
|
||||||
eDiskFull: fb_error_name := 'eDiskFull';
|
|
||||||
eIOError: fb_error_name := 'eIOError';
|
|
||||||
eIOTimeout: fb_error_name := 'eIOTimeout';
|
|
||||||
eIOCancelled: fb_error_name := 'eIOCancelled';
|
|
||||||
eDeviceNotReady: fb_error_name := 'eDeviceNotReady';
|
|
||||||
eDeviceRemoved: fb_error_name := 'eDeviceRemoved';
|
|
||||||
eDeviceNotFound: fb_error_name := 'eDeviceNotFound';
|
|
||||||
eQueueFull: fb_error_name := 'eQueueFull';
|
|
||||||
eNoFreeSlot: fb_error_name := 'eNoFreeSlot';
|
|
||||||
eCorruptFilesystem: fb_error_name := 'eCorruptFilesystem';
|
|
||||||
eBadSector: fb_error_name := 'eBadSector';
|
|
||||||
eAlreadyMounted: fb_error_name := 'eAlreadyMounted';
|
|
||||||
eNotMounted: fb_error_name := 'eNotMounted';
|
|
||||||
eUnsupportedFilesystem: fb_error_name := 'eUnsupportedFilesystem';
|
|
||||||
eInvalidPartitionTable: fb_error_name := 'eInvalidPartitionTable';
|
|
||||||
eVolumeNotFound: fb_error_name := 'eVolumeNotFound';
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
{ fb_refresh_poll_cb — 50ms LVGL poll timer; when rd_ready=1, build UI }
|
{ fb_refresh_poll_cb — 50ms LVGL poll timer; when rd_ready=1, build UI }
|
||||||
procedure fb_refresh_poll_cb(tmr: Plv_timer); cdecl;
|
procedure fb_refresh_poll_cb(tmr: Plv_timer); cdecl;
|
||||||
var
|
var
|
||||||
@@ -650,12 +604,9 @@ begin
|
|||||||
case state^.wop_kind of
|
case state^.wop_kind of
|
||||||
1: lv_msgbox_add_text(mbox, 'Could not create folder.');
|
1: lv_msgbox_add_text(mbox, 'Could not create folder.');
|
||||||
2: lv_msgbox_add_text(mbox, 'Could not rename item.');
|
2: lv_msgbox_add_text(mbox, 'Could not rename item.');
|
||||||
3: lv_msgbox_add_text(mbox, 'Could not create file.');
|
|
||||||
4: lv_msgbox_add_text(mbox, 'Could not delete item.');
|
|
||||||
else
|
else
|
||||||
lv_msgbox_add_text(mbox, 'Operation failed.');
|
lv_msgbox_add_text(mbox, 'Operation failed.');
|
||||||
end;
|
end;
|
||||||
lv_msgbox_add_text(mbox, fb_error_name(state^.wop_result));
|
|
||||||
ok_b := lv_msgbox_add_footer_button(mbox, 'OK');
|
ok_b := lv_msgbox_add_footer_button(mbox, 'OK');
|
||||||
lv_obj_add_event_cb(ok_b, @fb_mbox_close_cb, LV_EVENT_CLICKED, mbox);
|
lv_obj_add_event_cb(ok_b, @fb_mbox_close_cb, LV_EVENT_CLICKED, mbox);
|
||||||
end;
|
end;
|
||||||
@@ -668,8 +619,8 @@ begin
|
|||||||
kfree(void(state^.wop_path2));
|
kfree(void(state^.wop_path2));
|
||||||
state^.wop_path2 := nil;
|
state^.wop_path2 := nil;
|
||||||
end;
|
end;
|
||||||
{ For rename/delete, clear selection }
|
{ For rename, clear selection }
|
||||||
if (state^.wop_kind = 2) or (state^.wop_kind = 4) then
|
if state^.wop_kind = 2 then
|
||||||
clear_selection(state);
|
clear_selection(state);
|
||||||
schedule_refresh(state);
|
schedule_refresh(state);
|
||||||
end;
|
end;
|
||||||
@@ -1640,16 +1591,15 @@ begin
|
|||||||
@fb_delete_done, state);
|
@fb_delete_done, state);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ Async completion callback — runs outside the LVGL thread, so only set flags. }
|
{ Async completion callback — runs in ISR/worker context, defer to LVGL }
|
||||||
procedure fb_delete_done(error: TError; userdata: pointer);
|
procedure fb_delete_done(error: TError; userdata: pointer);
|
||||||
var
|
var
|
||||||
state: PFileBrowserState;
|
state: PFileBrowserState;
|
||||||
begin
|
begin
|
||||||
state := PFileBrowserState(userdata);
|
state := PFileBrowserState(userdata);
|
||||||
if state = nil then exit;
|
if state = nil then exit;
|
||||||
state^.wop_kind := 4;
|
state^.op_err := error;
|
||||||
state^.wop_result := error;
|
lv_timer_create(@fb_delete_done_timer, 1, state);
|
||||||
puint32(@state^.wop_done)^ := 1;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ Deferred UI update after delete }
|
{ Deferred UI update after delete }
|
||||||
@@ -1910,20 +1860,15 @@ begin
|
|||||||
if (error = eNone) and (nfctx^.handle <> 0) then begin
|
if (error = eNone) and (nfctx^.handle <> 0) then begin
|
||||||
{ WriteFileAsync needs a non-nil buffer; Length=0 so it is never read }
|
{ WriteFileAsync needs a non-nil buffer; Length=0 so it is never read }
|
||||||
driver.storage.vfs.WriteFileAsync(nfctx^.handle, 0,
|
driver.storage.vfs.WriteFileAsync(nfctx^.handle, 0,
|
||||||
puint8(@nfctx^.err), 0, nil, @fb_newfile_written, nfctx);
|
puint8(@nfctx^.err), 0, @fb_newfile_written, nfctx);
|
||||||
end else begin
|
end else begin
|
||||||
if nfctx^.handle <> 0 then
|
if nfctx^.handle <> 0 then
|
||||||
driver.storage.vfs.CloseFile(nfctx^.handle);
|
driver.storage.vfs.CloseFile(nfctx^.handle);
|
||||||
if nfctx^.state <> nil then begin
|
lv_timer_create(@fb_newfile_done_timer, 1, nfctx);
|
||||||
nfctx^.state^.wop_kind := 3;
|
|
||||||
nfctx^.state^.wop_result := nfctx^.err;
|
|
||||||
puint32(@nfctx^.state^.wop_done)^ := 1;
|
|
||||||
end;
|
|
||||||
kfree(void(nfctx));
|
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ Async step 2: write complete — close handle and defer UI work via poll flags }
|
{ Async step 2: write complete — close handle and schedule UI refresh }
|
||||||
procedure fb_newfile_written(error: TError; userdata: pointer);
|
procedure fb_newfile_written(error: TError; userdata: pointer);
|
||||||
var
|
var
|
||||||
nfctx : PNewFileCtx;
|
nfctx : PNewFileCtx;
|
||||||
@@ -1933,12 +1878,7 @@ begin
|
|||||||
if error <> eNone then nfctx^.err := error;
|
if error <> eNone then nfctx^.err := error;
|
||||||
if nfctx^.handle <> 0 then
|
if nfctx^.handle <> 0 then
|
||||||
driver.storage.vfs.CloseFile(nfctx^.handle);
|
driver.storage.vfs.CloseFile(nfctx^.handle);
|
||||||
if nfctx^.state <> nil then begin
|
lv_timer_create(@fb_newfile_done_timer, 1, nfctx);
|
||||||
nfctx^.state^.wop_kind := 3;
|
|
||||||
nfctx^.state^.wop_result := nfctx^.err;
|
|
||||||
puint32(@nfctx^.state^.wop_done)^ := 1;
|
|
||||||
end;
|
|
||||||
kfree(void(nfctx));
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure fb_newfile_done_timer(tmr: Plv_timer); cdecl;
|
procedure fb_newfile_done_timer(tmr: Plv_timer); cdecl;
|
||||||
|
|||||||
File diff suppressed because it is too large.
Load diff
+1
-2
@@ -26,7 +26,7 @@ uses
|
|||||||
boot.mgr,
|
boot.mgr,
|
||||||
debug.tracer, io.stdio, proc.mgr,
|
debug.tracer, io.stdio, proc.mgr,
|
||||||
//progs
|
//progs
|
||||||
app.base64, app.md5sum, app.dhclient, app.vbeinfo, app.testcmd, app.ping, app.meminfo, app.setres, app.iotest,
|
app.base64, app.md5sum, app.dhclient, app.vbeinfo, app.testcmd, app.ping, app.meminfo, app.setres,
|
||||||
//drivers
|
//drivers
|
||||||
driver.storage.ctl.ram, driver.mgr,
|
driver.storage.ctl.ram, driver.mgr,
|
||||||
//network
|
//network
|
||||||
@@ -92,7 +92,6 @@ begin
|
|||||||
app.bsod.init();
|
app.bsod.init();
|
||||||
app.vterminal.init;
|
app.vterminal.init;
|
||||||
app.filebrowser.init();
|
app.filebrowser.init();
|
||||||
app.iotest.init();
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
Initialization
|
Initialization
|
||||||
|
|||||||
+8
-17
@@ -288,9 +288,7 @@ begin
|
|||||||
if bootrecord <> nil then begin
|
if bootrecord <> nil then begin
|
||||||
if bootrecord^.boot_sector <> $AA55 then begin
|
if bootrecord^.boot_sector <> $AA55 then begin
|
||||||
println('No valid mbr found, initialising disk...');
|
println('No valid mbr found, initialising disk...');
|
||||||
if driver.storage.vol.mgr.init_disk(device) <> eNone then begin
|
driver.storage.vol.mgr.init_disk(device);
|
||||||
println('Error: disk initialization failed.'); exit;
|
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
kfree(puint32(bootrecord));
|
kfree(puint32(bootrecord));
|
||||||
end;
|
end;
|
||||||
@@ -337,9 +335,7 @@ begin
|
|||||||
|
|
||||||
driver.storage.vol.mbr.setup_partition(@part, lba, sectors);
|
driver.storage.vol.mbr.setup_partition(@part, lba, sectors);
|
||||||
part.system_id := 0;
|
part.system_id := 0;
|
||||||
if driver.storage.vol.mgr.add_partition(device, slot, part) <> eNone then begin
|
driver.storage.vol.mgr.add_partition(device, slot, part);
|
||||||
println('Error: partition creation failed.'); exit;
|
|
||||||
end;
|
|
||||||
|
|
||||||
print('Partition added in slot ');
|
print('Partition added in slot ');
|
||||||
printint(slot);
|
printint(slot);
|
||||||
@@ -411,9 +407,7 @@ begin
|
|||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if driver.storage.vol.mgr.remove_partition(device, slot) <> eNone then begin
|
driver.storage.vol.mgr.remove_partition(device, slot);
|
||||||
println('Error: partition removal failed.'); exit;
|
|
||||||
end;
|
|
||||||
|
|
||||||
print('Partition slot ');
|
print('Partition slot ');
|
||||||
printint(slot);
|
printint(slot);
|
||||||
@@ -529,14 +523,11 @@ begin
|
|||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
i := 0;
|
vol^.filesystem := fs;
|
||||||
while i < driver.storage.vol.mgr.get_volume_count() do begin
|
fs^.createCallback(vol, vol^.sectorCount, vol^.sectorStart, nil);
|
||||||
if driver.storage.vol.mgr.get_volume(i) = vol then break;
|
|
||||||
Inc(i);
|
{ Re-probe filesystem so identify picks up the new signature }
|
||||||
end;
|
driver.storage.fs.mgr.probe_volume(vol);
|
||||||
if not driver.storage.vol.mgr.format_volume(device, i, fsName, nil) then begin
|
|
||||||
println('Error: format failed; the volume was not reported ready.'); exit;
|
|
||||||
end;
|
|
||||||
|
|
||||||
print('Partition ');
|
print('Partition ');
|
||||||
printint(slot);
|
printint(slot);
|
||||||
|
|||||||
@@ -44,7 +44,6 @@ function inl(port : uint16) : uint32;
|
|||||||
procedure io_wait;
|
procedure io_wait;
|
||||||
|
|
||||||
procedure __SSE_128_memcpy(source : uint32; dest : uint32);
|
procedure __SSE_128_memcpy(source : uint32; dest : uint32);
|
||||||
procedure __REP_MOVSB_memcpy(source : uint32; dest : uint32; size : uint32);
|
|
||||||
|
|
||||||
procedure halt_and_catch_fire();
|
procedure halt_and_catch_fire();
|
||||||
procedure halt_and_dont_catch_fire();
|
procedure halt_and_dont_catch_fire();
|
||||||
@@ -114,19 +113,6 @@ asm
|
|||||||
MOVAPS [EAX], XMM1
|
MOVAPS [EAX], XMM1
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure __REP_MOVSB_memcpy(source : uint32; dest : uint32; size : uint32); assembler;
|
|
||||||
asm
|
|
||||||
push esi
|
|
||||||
push edi
|
|
||||||
cld
|
|
||||||
mov esi, source
|
|
||||||
mov edi, dest
|
|
||||||
mov ecx, size
|
|
||||||
rep movsb
|
|
||||||
pop edi
|
|
||||||
pop esi
|
|
||||||
end;
|
|
||||||
|
|
||||||
function getESP : uint32;
|
function getESP : uint32;
|
||||||
var
|
var
|
||||||
tmp: uint32;
|
tmp: uint32;
|
||||||
|
|||||||
@@ -27,10 +27,6 @@ uses
|
|||||||
arch.x86.isr.mgr,
|
arch.x86.isr.mgr,
|
||||||
arch.x86.idt;
|
arch.x86.idt;
|
||||||
|
|
||||||
const
|
|
||||||
PIT_INPUT_HZ = 1193182;
|
|
||||||
PIT_DIVISOR = 149;
|
|
||||||
|
|
||||||
procedure register();
|
procedure register();
|
||||||
procedure hook(hook_method : uint32);
|
procedure hook(hook_method : uint32);
|
||||||
procedure unhook(hook_method : uint32);
|
procedure unhook(hook_method : uint32);
|
||||||
@@ -58,7 +54,7 @@ procedure register();
|
|||||||
begin
|
begin
|
||||||
if not registered then begin
|
if not registered then begin
|
||||||
asm
|
asm
|
||||||
mov ax, PIT_DIVISOR
|
mov ax, 149
|
||||||
out $40, al
|
out $40, al
|
||||||
mov al, ah
|
mov al, ah
|
||||||
out $40, al
|
out $40, al
|
||||||
|
|||||||
@@ -19,6 +19,8 @@
|
|||||||
}
|
}
|
||||||
unit arch.x86.isr.tmr1;
|
unit arch.x86.isr.tmr1;
|
||||||
|
|
||||||
|
{$DEFINE NOT_DANGLING} { Unused legacy timer ISR; not part of the kernel boot sequence. }
|
||||||
|
|
||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
|
|||||||
Loaded 20 of 72 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user