Compare commits
304 Commits
578e9934d8
...
fat_v2
| Author | SHA1 | Date | |
|---|---|---|---|
| 4a944bc493 | |||
| 137735431a | |||
| 6caaf6aa6d | |||
| 1e9de446f0 | |||
| 5f2ca55af7 | |||
| 11656c2827 | |||
| f87f88a0dc | |||
| 7baa53178a | |||
| 8002d1cb54 | |||
| d8a89cfd2b | |||
| 6c402b5c4f | |||
| a3c9897291 | |||
| 831d45c33c | |||
| 918e94689f | |||
| 8d2cde0a31 | |||
| 8d3788a76e | |||
| 4a27e09872 | |||
| 59bc1afb7c | |||
| 8b0b73d8a4 | |||
| 803be58c10 | |||
| 528e3d69fe | |||
| 51bd250925 | |||
| 460165a8d1 | |||
| 935cbd1089 | |||
| 7f1b4fa632 | |||
| 14f6788a22 | |||
| 526c3e7ea5 | |||
| 721ff2e62d | |||
| a50af35abd | |||
| 7cd6baa74d | |||
| 40fa4062ce | |||
| a8b24c7b01 | |||
| 58fc4a08dd | |||
| 3da2af2d2d | |||
| 75d77e92e1 | |||
| 8e6c823a00 | |||
| fca8a5d573 | |||
| f341a50b78 | |||
| ef22bc9cd3 | |||
| 507a05949f | |||
| caed66a243 | |||
| d5cd8d6c45 | |||
| b0f118b139 | |||
| 71d50cdbd8 | |||
| 3c654b1be0 | |||
| 0d90b3efd6 | |||
| b08605f295 | |||
| aa0efe5ff8 | |||
| 700148a2f6 | |||
| 14ef0151ca | |||
| 1d696371d2 | |||
| d30abe7a27 | |||
| d6f6076d45 | |||
| 4e05efaa6b | |||
| 7cc0b4a392 | |||
| 9a6fea658d | |||
| 891bff9509 | |||
| 1e181bc22c | |||
| 68c8200aa4 | |||
| 766c67c041 | |||
| 49d82be0e8 | |||
| 69bd7d8f56 | |||
| 875527aa98 | |||
| c0d47d4db0 | |||
| 81a3442ac5 | |||
| 3ec55f5a39 | |||
| 9493aefa68 | |||
| 6f2fc627be | |||
| 20c715fadd | |||
| 920c623a93 | |||
| af8e7d74d3 | |||
| fde7abc544 | |||
| 69223a1ad2 | |||
| 130cd22ff1 | |||
| 4e5112b45b | |||
| 66e8e3c7fc | |||
| b0bd4b27b0 | |||
| cd316afdd1 | |||
| 9a478aa4d4 | |||
| 31d05c35e5 | |||
| 534e04ef34 | |||
| f58bf93507 | |||
| b5ae11f850 | |||
| b9b3e92632 | |||
| 5fac10f02c | |||
| fa4524aa59 | |||
| 01ec6da0cc | |||
| 2e2b4f991d | |||
| d7b29d9113 | |||
| 69d82dc0c2 | |||
| a53534acd2 | |||
| c3871d2b7d | |||
| d824493ba2 | |||
| cb089681cf | |||
| d868008726 | |||
| 935427509a | |||
| f5e4927d70 | |||
| b106eae066 | |||
| f2657fdc01 | |||
| 86d966811b | |||
| c10394a0cd | |||
| 28b23b9ce2 | |||
| 105ceb8b8b | |||
| 7fd5b9b85d | |||
| a618a837d4 | |||
| 930d49c353 | |||
| 06d00d02e2 | |||
| 61379e8116 | |||
| 828428e73b | |||
| 402bf9974d | |||
| 5dfc3533d9 | |||
| d9225718c2 | |||
| 8a6730bc9c | |||
| 67523208b3 | |||
| ffe887b6a9 | |||
| c45e62ecc2 | |||
| d7c50575cf | |||
| 39148869bc | |||
| 81e6b6e835 | |||
| 63c5e0d00e | |||
| 29a2a598ba | |||
| 47b18de37e | |||
| 8129a71fdd | |||
| ef42ae084b | |||
| 8d5996566e | |||
| b2c5a6bf46 | |||
| 531f4fa25f | |||
| aa181bbae4 | |||
| ddd3f35a8b | |||
|
ce73226eee
|
|||
|
d6e8a2a923
|
|||
|
9918f2367e
|
|||
| 56b86fe12e | |||
| 37eb87239c | |||
| 63a1a1beea | |||
| 3bdef99939 | |||
| 4535b89eaf | |||
| ee9fd9b684 | |||
| 6ff9a2307f | |||
| d98786072c | |||
| b7e2a8e886 | |||
| 94c2a1626d | |||
| 48f0de8f7b | |||
| b606e28958 | |||
| 45aeb9b3d0 | |||
| 046821ff7a | |||
| 520f877b05 | |||
| 508bf1aa55 | |||
| ccf846909a | |||
| 4708c78d54 | |||
| 6942c4dbb4 | |||
| 9d4479bd86 | |||
| 496a389ba4 | |||
| 2b3ab1dc3a | |||
| 85a8f0da1c | |||
| b5cc1c9ec1 | |||
| e12ea89fda | |||
| e33f010f73 | |||
| c9f4b18d2b | |||
| e680620148 | |||
| fb54c65caf | |||
| 7f6436297e | |||
| 5159ef8a7c | |||
| 56e8081118 | |||
| 50b08f6b72 | |||
| a97e3bea9b | |||
| aa8c7b67ab | |||
| b4621a7fb8 | |||
| 5f9567d44e | |||
| 2020408e8d | |||
| 405a5ff20e | |||
| 4660882edb | |||
| f683b8fd17 | |||
| 56c18d8457 | |||
| cfda93048b | |||
| c49de28a15 | |||
| 4a013b4a59 | |||
| cd833184da | |||
| 7617b11199 | |||
| 86564b2356 | |||
| 5ba7801926 | |||
| 35e9aec059 | |||
| 736aad85e5 | |||
| f51d8b4142 | |||
| 3693eca940 | |||
| a383f7cfb4 | |||
| c1a9d449df | |||
| ce6240249a | |||
| 963dec5281 | |||
| 3d1877d7fe | |||
| eb97aac673 | |||
| c60bad1066 | |||
| 050f90517a | |||
| 555cf1271b | |||
| 8fea1f0a06 | |||
| b49b2bae68 | |||
| 5abbfa4d15 | |||
| 83aa7d1147 | |||
| ac6ad77249 | |||
| bc89850c00 | |||
| 12fc8a1e37 | |||
| baa146bef5 | |||
| d1217182d4 | |||
| 5a74cd86ad | |||
| 69c068f6be | |||
| 63421661a7 | |||
| 9cde0333e6 | |||
| 6ff96deabc | |||
| 96de8cd9c7 | |||
| daa6337285 | |||
| d73a4eea6c | |||
| 5703bad704 | |||
| a3f0684c85 | |||
| a8da6eef72 | |||
| d9e46f5571 | |||
| 0250d9351d | |||
| e8fb22c826 | |||
| df3b8dfc0c | |||
| 3a819a685a | |||
| 5ccd2fb12f | |||
| ccb82f29fc | |||
| f665d7fcaa | |||
| 94034eb7bf | |||
| ab21f9c838 | |||
| 2f391a0fc2 | |||
| d88b1bcb70 | |||
| 13ff42a7d1 | |||
| 61f27cabd7 | |||
| 6643e3c990 | |||
| 09d33086a0 | |||
| 8e05e071e8 | |||
| ca195e6048 | |||
| db45a5cf8b | |||
| aac964c378 | |||
| 3c40190f23 | |||
| 39e977ea2c | |||
| 7e0cd2a931 | |||
| 4c4c3b0e27 | |||
| f5f5a330cd | |||
| 446dd451be | |||
| 64f2453d61 | |||
| 867232890e | |||
| bcb9fc2176 | |||
| a0df1cb100 | |||
| 6b2b1d2fc9 | |||
| aae0d6b5b3 | |||
| db1d0295c5 | |||
| c1c6b25e6e | |||
| ecd858f030 | |||
| e45f1cb27d | |||
| a6a774484f | |||
| 438b784f2d | |||
| abd8cba080 | |||
| d0635f4f3a | |||
| 4e7a9e00d7 | |||
| e3f0d34336 | |||
| 60ad0d71e0 | |||
| d16323bac1 | |||
| 339216f6a2 | |||
| f8585889f1 | |||
| 51d77eda6f | |||
| 91c37df3d0 | |||
| e03322b129 | |||
| 7fbb9b13e2 | |||
| 3f72d5ad31 | |||
| 09366afbdf | |||
| 269e90a122 | |||
| 768260540f | |||
| d2194ab835 | |||
| 94ed76be82 | |||
| 9080533175 | |||
| a3af2a5825 | |||
| 0c36f9f1fd | |||
| 3804f1c4be | |||
| a6835df63e | |||
| 18bb9a5691 | |||
| cbd7244e87 | |||
| f3de54fa9d | |||
| e057dbdbe3 | |||
| b654e900ed | |||
| d813b03de9 | |||
| 8a3b12774f | |||
| 60a10e41e0 | |||
| 20c18ac4ec | |||
| e859f5da13 | |||
| 2a1b0f3b09 | |||
| ee65b6acc5 | |||
| dafac41102 | |||
|
9cb9a6664f
|
|||
|
bd47648ad0
|
|||
|
7b3ed7e1de
|
|||
|
333b176793
|
|||
|
4b0e0abd9b
|
|||
| bd1492593b | |||
|
0868cf41cc
|
|||
|
d7bd565279
|
|||
|
bb6d943047
|
|||
|
df8c959bb4
|
|||
|
91ec2ad898
|
|||
| ad192db2a6 | |||
| 1a1b7a279d | |||
| e78074e190 | |||
|
|
4a37274e58 | ||
|
|
967a13de7e |
40
.gitea/workflows/onpush.yaml
Normal file
40
.gitea/workflows/onpush.yaml
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
name: Daily Build and trunk tester
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ $default-branch ]
|
||||||
|
pull_request:
|
||||||
|
branches: [ $default-branch ]
|
||||||
|
schedule:
|
||||||
|
- cron: "0 7 * * *" # daily 07:00
|
||||||
|
workflow_dispatch: {}
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
debian_update:
|
||||||
|
runs-on: debian-trixie
|
||||||
|
steps:
|
||||||
|
- name: Checkout (if needed)
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Install CHTM apt cache endpoint into container
|
||||||
|
run: |
|
||||||
|
echo 'Acquire::http::Proxy "http://chtm-aptcache-01.lan.chtm.me:3142";' | tee /etc/apt/apt.conf.d/01aptproxy
|
||||||
|
|
||||||
|
- name: Ensure image is up to date and install build tools and deps
|
||||||
|
run: |
|
||||||
|
bash -c "apt update && apt upgrade -y"
|
||||||
|
apt install -y build-essential nasm mtools fdisk dosfstools
|
||||||
|
|
||||||
|
- name: Build stevia
|
||||||
|
run: make
|
||||||
|
|
||||||
|
- name: Upload build artifacts
|
||||||
|
if: always() # still keep logs/artifacts even if build fails
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: stevia-${{ github.run_number }}
|
||||||
|
path: |
|
||||||
|
build/output/artifacts.tar.gz
|
||||||
|
build/output/disk.img.gz
|
||||||
|
build/output/part.img.gz
|
||||||
|
if-no-files-found: error
|
||||||
|
retention-days: 30 # override server default if you like
|
||||||
35
.github/workflows/daily.yaml
vendored
Normal file
35
.github/workflows/daily.yaml
vendored
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
name: Daily Build and trunk tester
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ $default-branch ]
|
||||||
|
schedule:
|
||||||
|
- cron: "0 7 * * 1" # mondays at 07:00
|
||||||
|
workflow_dispatch: {}
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
debian_update:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout (if needed)
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Update and install build tools and deps
|
||||||
|
run: |
|
||||||
|
sudo bash -c "apt update && apt upgrade -y"
|
||||||
|
sudo apt install -y build-essential nasm mtools fdisk dosfstools
|
||||||
|
|
||||||
|
- name: Build stevia
|
||||||
|
run: make
|
||||||
|
|
||||||
|
- name: Upload build artifacts
|
||||||
|
if: always() # still keep logs/artifacts even if build fails
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: stevia-${{ github.run_number }}
|
||||||
|
path: |
|
||||||
|
build/output/artifacts.tar.gz
|
||||||
|
build/output/disk.img.gz
|
||||||
|
build/output/part.img.gz
|
||||||
|
if-no-files-found: error
|
||||||
|
retention-days: 7 # override server default if you like
|
||||||
|
|
||||||
7
.gitignore
vendored
7
.gitignore
vendored
@@ -1,9 +1,14 @@
|
|||||||
out/*
|
|
||||||
build/*
|
build/*
|
||||||
|
build/output/*
|
||||||
*.img
|
*.img
|
||||||
*.img.gz
|
*.img.gz
|
||||||
|
*.img.gz
|
||||||
*.elf
|
*.elf
|
||||||
bx_enh_dbg.ini
|
bx_enh_dbg.ini
|
||||||
stevia-log
|
stevia-log
|
||||||
.vscode/
|
.vscode/
|
||||||
*.map
|
*.map
|
||||||
|
compose-dev.yaml
|
||||||
|
eth_null-tx.log
|
||||||
|
eth_null-txdump.txt
|
||||||
|
*.log
|
||||||
674
COPYING
Normal file
674
COPYING
Normal file
@@ -0,0 +1,674 @@
|
|||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
Version 3, 29 June 2007
|
||||||
|
|
||||||
|
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The GNU General Public License is a free, copyleft license for
|
||||||
|
software and other kinds of works.
|
||||||
|
|
||||||
|
The licenses for most software and other practical works are designed
|
||||||
|
to take away your freedom to share and change the works. By contrast,
|
||||||
|
the GNU General Public License is intended to guarantee your freedom to
|
||||||
|
share and change all versions of a program--to make sure it remains free
|
||||||
|
software for all its users. We, the Free Software Foundation, use the
|
||||||
|
GNU General Public License for most of our software; it applies also to
|
||||||
|
any other work released this way by its authors. You can apply it to
|
||||||
|
your programs, too.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom, not
|
||||||
|
price. Our General Public Licenses are designed to make sure that you
|
||||||
|
have the freedom to distribute copies of free software (and charge for
|
||||||
|
them if you wish), that you receive source code or can get it if you
|
||||||
|
want it, that you can change the software or use pieces of it in new
|
||||||
|
free programs, and that you know you can do these things.
|
||||||
|
|
||||||
|
To protect your rights, we need to prevent others from denying you
|
||||||
|
these rights or asking you to surrender the rights. Therefore, you have
|
||||||
|
certain responsibilities if you distribute copies of the software, or if
|
||||||
|
you modify it: responsibilities to respect the freedom of others.
|
||||||
|
|
||||||
|
For example, if you distribute copies of such a program, whether
|
||||||
|
gratis or for a fee, you must pass on to the recipients the same
|
||||||
|
freedoms that you received. You must make sure that they, too, receive
|
||||||
|
or can get the source code. And you must show them these terms so they
|
||||||
|
know their rights.
|
||||||
|
|
||||||
|
Developers that use the GNU GPL protect your rights with two steps:
|
||||||
|
(1) assert copyright on the software, and (2) offer you this License
|
||||||
|
giving you legal permission to copy, distribute and/or modify it.
|
||||||
|
|
||||||
|
For the developers' and authors' protection, the GPL clearly explains
|
||||||
|
that there is no warranty for this free software. For both users' and
|
||||||
|
authors' sake, the GPL requires that modified versions be marked as
|
||||||
|
changed, so that their problems will not be attributed erroneously to
|
||||||
|
authors of previous versions.
|
||||||
|
|
||||||
|
Some devices are designed to deny users access to install or run
|
||||||
|
modified versions of the software inside them, although the manufacturer
|
||||||
|
can do so. This is fundamentally incompatible with the aim of
|
||||||
|
protecting users' freedom to change the software. The systematic
|
||||||
|
pattern of such abuse occurs in the area of products for individuals to
|
||||||
|
use, which is precisely where it is most unacceptable. Therefore, we
|
||||||
|
have designed this version of the GPL to prohibit the practice for those
|
||||||
|
products. If such problems arise substantially in other domains, we
|
||||||
|
stand ready to extend this provision to those domains in future versions
|
||||||
|
of the GPL, as needed to protect the freedom of users.
|
||||||
|
|
||||||
|
Finally, every program is threatened constantly by software patents.
|
||||||
|
States should not allow patents to restrict development and use of
|
||||||
|
software on general-purpose computers, but in those that do, we wish to
|
||||||
|
avoid the special danger that patents applied to a free program could
|
||||||
|
make it effectively proprietary. To prevent this, the GPL assures that
|
||||||
|
patents cannot be used to render the program non-free.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and
|
||||||
|
modification follow.
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
0. Definitions.
|
||||||
|
|
||||||
|
"This License" refers to version 3 of the GNU General Public License.
|
||||||
|
|
||||||
|
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||||
|
works, such as semiconductor masks.
|
||||||
|
|
||||||
|
"The Program" refers to any copyrightable work licensed under this
|
||||||
|
License. Each licensee is addressed as "you". "Licensees" and
|
||||||
|
"recipients" may be individuals or organizations.
|
||||||
|
|
||||||
|
To "modify" a work means to copy from or adapt all or part of the work
|
||||||
|
in a fashion requiring copyright permission, other than the making of an
|
||||||
|
exact copy. The resulting work is called a "modified version" of the
|
||||||
|
earlier work or a work "based on" the earlier work.
|
||||||
|
|
||||||
|
A "covered work" means either the unmodified Program or a work based
|
||||||
|
on the Program.
|
||||||
|
|
||||||
|
To "propagate" a work means to do anything with it that, without
|
||||||
|
permission, would make you directly or secondarily liable for
|
||||||
|
infringement under applicable copyright law, except executing it on a
|
||||||
|
computer or modifying a private copy. Propagation includes copying,
|
||||||
|
distribution (with or without modification), making available to the
|
||||||
|
public, and in some countries other activities as well.
|
||||||
|
|
||||||
|
To "convey" a work means any kind of propagation that enables other
|
||||||
|
parties to make or receive copies. Mere interaction with a user through
|
||||||
|
a computer network, with no transfer of a copy, is not conveying.
|
||||||
|
|
||||||
|
An interactive user interface displays "Appropriate Legal Notices"
|
||||||
|
to the extent that it includes a convenient and prominently visible
|
||||||
|
feature that (1) displays an appropriate copyright notice, and (2)
|
||||||
|
tells the user that there is no warranty for the work (except to the
|
||||||
|
extent that warranties are provided), that licensees may convey the
|
||||||
|
work under this License, and how to view a copy of this License. If
|
||||||
|
the interface presents a list of user commands or options, such as a
|
||||||
|
menu, a prominent item in the list meets this criterion.
|
||||||
|
|
||||||
|
1. Source Code.
|
||||||
|
|
||||||
|
The "source code" for a work means the preferred form of the work
|
||||||
|
for making modifications to it. "Object code" means any non-source
|
||||||
|
form of a work.
|
||||||
|
|
||||||
|
A "Standard Interface" means an interface that either is an official
|
||||||
|
standard defined by a recognized standards body, or, in the case of
|
||||||
|
interfaces specified for a particular programming language, one that
|
||||||
|
is widely used among developers working in that language.
|
||||||
|
|
||||||
|
The "System Libraries" of an executable work include anything, other
|
||||||
|
than the work as a whole, that (a) is included in the normal form of
|
||||||
|
packaging a Major Component, but which is not part of that Major
|
||||||
|
Component, and (b) serves only to enable use of the work with that
|
||||||
|
Major Component, or to implement a Standard Interface for which an
|
||||||
|
implementation is available to the public in source code form. A
|
||||||
|
"Major Component", in this context, means a major essential component
|
||||||
|
(kernel, window system, and so on) of the specific operating system
|
||||||
|
(if any) on which the executable work runs, or a compiler used to
|
||||||
|
produce the work, or an object code interpreter used to run it.
|
||||||
|
|
||||||
|
The "Corresponding Source" for a work in object code form means all
|
||||||
|
the source code needed to generate, install, and (for an executable
|
||||||
|
work) run the object code and to modify the work, including scripts to
|
||||||
|
control those activities. However, it does not include the work's
|
||||||
|
System Libraries, or general-purpose tools or generally available free
|
||||||
|
programs which are used unmodified in performing those activities but
|
||||||
|
which are not part of the work. For example, Corresponding Source
|
||||||
|
includes interface definition files associated with source files for
|
||||||
|
the work, and the source code for shared libraries and dynamically
|
||||||
|
linked subprograms that the work is specifically designed to require,
|
||||||
|
such as by intimate data communication or control flow between those
|
||||||
|
subprograms and other parts of the work.
|
||||||
|
|
||||||
|
The Corresponding Source need not include anything that users
|
||||||
|
can regenerate automatically from other parts of the Corresponding
|
||||||
|
Source.
|
||||||
|
|
||||||
|
The Corresponding Source for a work in source code form is that
|
||||||
|
same work.
|
||||||
|
|
||||||
|
2. Basic Permissions.
|
||||||
|
|
||||||
|
All rights granted under this License are granted for the term of
|
||||||
|
copyright on the Program, and are irrevocable provided the stated
|
||||||
|
conditions are met. This License explicitly affirms your unlimited
|
||||||
|
permission to run the unmodified Program. The output from running a
|
||||||
|
covered work is covered by this License only if the output, given its
|
||||||
|
content, constitutes a covered work. This License acknowledges your
|
||||||
|
rights of fair use or other equivalent, as provided by copyright law.
|
||||||
|
|
||||||
|
You may make, run and propagate covered works that you do not
|
||||||
|
convey, without conditions so long as your license otherwise remains
|
||||||
|
in force. You may convey covered works to others for the sole purpose
|
||||||
|
of having them make modifications exclusively for you, or provide you
|
||||||
|
with facilities for running those works, provided that you comply with
|
||||||
|
the terms of this License in conveying all material for which you do
|
||||||
|
not control copyright. Those thus making or running the covered works
|
||||||
|
for you must do so exclusively on your behalf, under your direction
|
||||||
|
and control, on terms that prohibit them from making any copies of
|
||||||
|
your copyrighted material outside their relationship with you.
|
||||||
|
|
||||||
|
Conveying under any other circumstances is permitted solely under
|
||||||
|
the conditions stated below. Sublicensing is not allowed; section 10
|
||||||
|
makes it unnecessary.
|
||||||
|
|
||||||
|
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||||
|
|
||||||
|
No covered work shall be deemed part of an effective technological
|
||||||
|
measure under any applicable law fulfilling obligations under article
|
||||||
|
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||||
|
similar laws prohibiting or restricting circumvention of such
|
||||||
|
measures.
|
||||||
|
|
||||||
|
When you convey a covered work, you waive any legal power to forbid
|
||||||
|
circumvention of technological measures to the extent such circumvention
|
||||||
|
is effected by exercising rights under this License with respect to
|
||||||
|
the covered work, and you disclaim any intention to limit operation or
|
||||||
|
modification of the work as a means of enforcing, against the work's
|
||||||
|
users, your or third parties' legal rights to forbid circumvention of
|
||||||
|
technological measures.
|
||||||
|
|
||||||
|
4. Conveying Verbatim Copies.
|
||||||
|
|
||||||
|
You may convey verbatim copies of the Program's source code as you
|
||||||
|
receive it, in any medium, provided that you conspicuously and
|
||||||
|
appropriately publish on each copy an appropriate copyright notice;
|
||||||
|
keep intact all notices stating that this License and any
|
||||||
|
non-permissive terms added in accord with section 7 apply to the code;
|
||||||
|
keep intact all notices of the absence of any warranty; and give all
|
||||||
|
recipients a copy of this License along with the Program.
|
||||||
|
|
||||||
|
You may charge any price or no price for each copy that you convey,
|
||||||
|
and you may offer support or warranty protection for a fee.
|
||||||
|
|
||||||
|
5. Conveying Modified Source Versions.
|
||||||
|
|
||||||
|
You may convey a work based on the Program, or the modifications to
|
||||||
|
produce it from the Program, in the form of source code under the
|
||||||
|
terms of section 4, provided that you also meet all of these conditions:
|
||||||
|
|
||||||
|
a) The work must carry prominent notices stating that you modified
|
||||||
|
it, and giving a relevant date.
|
||||||
|
|
||||||
|
b) The work must carry prominent notices stating that it is
|
||||||
|
released under this License and any conditions added under section
|
||||||
|
7. This requirement modifies the requirement in section 4 to
|
||||||
|
"keep intact all notices".
|
||||||
|
|
||||||
|
c) You must license the entire work, as a whole, under this
|
||||||
|
License to anyone who comes into possession of a copy. This
|
||||||
|
License will therefore apply, along with any applicable section 7
|
||||||
|
additional terms, to the whole of the work, and all its parts,
|
||||||
|
regardless of how they are packaged. This License gives no
|
||||||
|
permission to license the work in any other way, but it does not
|
||||||
|
invalidate such permission if you have separately received it.
|
||||||
|
|
||||||
|
d) If the work has interactive user interfaces, each must display
|
||||||
|
Appropriate Legal Notices; however, if the Program has interactive
|
||||||
|
interfaces that do not display Appropriate Legal Notices, your
|
||||||
|
work need not make them do so.
|
||||||
|
|
||||||
|
A compilation of a covered work with other separate and independent
|
||||||
|
works, which are not by their nature extensions of the covered work,
|
||||||
|
and which are not combined with it such as to form a larger program,
|
||||||
|
in or on a volume of a storage or distribution medium, is called an
|
||||||
|
"aggregate" if the compilation and its resulting copyright are not
|
||||||
|
used to limit the access or legal rights of the compilation's users
|
||||||
|
beyond what the individual works permit. Inclusion of a covered work
|
||||||
|
in an aggregate does not cause this License to apply to the other
|
||||||
|
parts of the aggregate.
|
||||||
|
|
||||||
|
6. Conveying Non-Source Forms.
|
||||||
|
|
||||||
|
You may convey a covered work in object code form under the terms
|
||||||
|
of sections 4 and 5, provided that you also convey the
|
||||||
|
machine-readable Corresponding Source under the terms of this License,
|
||||||
|
in one of these ways:
|
||||||
|
|
||||||
|
a) Convey the object code in, or embodied in, a physical product
|
||||||
|
(including a physical distribution medium), accompanied by the
|
||||||
|
Corresponding Source fixed on a durable physical medium
|
||||||
|
customarily used for software interchange.
|
||||||
|
|
||||||
|
b) Convey the object code in, or embodied in, a physical product
|
||||||
|
(including a physical distribution medium), accompanied by a
|
||||||
|
written offer, valid for at least three years and valid for as
|
||||||
|
long as you offer spare parts or customer support for that product
|
||||||
|
model, to give anyone who possesses the object code either (1) a
|
||||||
|
copy of the Corresponding Source for all the software in the
|
||||||
|
product that is covered by this License, on a durable physical
|
||||||
|
medium customarily used for software interchange, for a price no
|
||||||
|
more than your reasonable cost of physically performing this
|
||||||
|
conveying of source, or (2) access to copy the
|
||||||
|
Corresponding Source from a network server at no charge.
|
||||||
|
|
||||||
|
c) Convey individual copies of the object code with a copy of the
|
||||||
|
written offer to provide the Corresponding Source. This
|
||||||
|
alternative is allowed only occasionally and noncommercially, and
|
||||||
|
only if you received the object code with such an offer, in accord
|
||||||
|
with subsection 6b.
|
||||||
|
|
||||||
|
d) Convey the object code by offering access from a designated
|
||||||
|
place (gratis or for a charge), and offer equivalent access to the
|
||||||
|
Corresponding Source in the same way through the same place at no
|
||||||
|
further charge. You need not require recipients to copy the
|
||||||
|
Corresponding Source along with the object code. If the place to
|
||||||
|
copy the object code is a network server, the Corresponding Source
|
||||||
|
may be on a different server (operated by you or a third party)
|
||||||
|
that supports equivalent copying facilities, provided you maintain
|
||||||
|
clear directions next to the object code saying where to find the
|
||||||
|
Corresponding Source. Regardless of what server hosts the
|
||||||
|
Corresponding Source, you remain obligated to ensure that it is
|
||||||
|
available for as long as needed to satisfy these requirements.
|
||||||
|
|
||||||
|
e) Convey the object code using peer-to-peer transmission, provided
|
||||||
|
you inform other peers where the object code and Corresponding
|
||||||
|
Source of the work are being offered to the general public at no
|
||||||
|
charge under subsection 6d.
|
||||||
|
|
||||||
|
A separable portion of the object code, whose source code is excluded
|
||||||
|
from the Corresponding Source as a System Library, need not be
|
||||||
|
included in conveying the object code work.
|
||||||
|
|
||||||
|
A "User Product" is either (1) a "consumer product", which means any
|
||||||
|
tangible personal property which is normally used for personal, family,
|
||||||
|
or household purposes, or (2) anything designed or sold for incorporation
|
||||||
|
into a dwelling. In determining whether a product is a consumer product,
|
||||||
|
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||||
|
product received by a particular user, "normally used" refers to a
|
||||||
|
typical or common use of that class of product, regardless of the status
|
||||||
|
of the particular user or of the way in which the particular user
|
||||||
|
actually uses, or expects or is expected to use, the product. A product
|
||||||
|
is a consumer product regardless of whether the product has substantial
|
||||||
|
commercial, industrial or non-consumer uses, unless such uses represent
|
||||||
|
the only significant mode of use of the product.
|
||||||
|
|
||||||
|
"Installation Information" for a User Product means any methods,
|
||||||
|
procedures, authorization keys, or other information required to install
|
||||||
|
and execute modified versions of a covered work in that User Product from
|
||||||
|
a modified version of its Corresponding Source. The information must
|
||||||
|
suffice to ensure that the continued functioning of the modified object
|
||||||
|
code is in no case prevented or interfered with solely because
|
||||||
|
modification has been made.
|
||||||
|
|
||||||
|
If you convey an object code work under this section in, or with, or
|
||||||
|
specifically for use in, a User Product, and the conveying occurs as
|
||||||
|
part of a transaction in which the right of possession and use of the
|
||||||
|
User Product is transferred to the recipient in perpetuity or for a
|
||||||
|
fixed term (regardless of how the transaction is characterized), the
|
||||||
|
Corresponding Source conveyed under this section must be accompanied
|
||||||
|
by the Installation Information. But this requirement does not apply
|
||||||
|
if neither you nor any third party retains the ability to install
|
||||||
|
modified object code on the User Product (for example, the work has
|
||||||
|
been installed in ROM).
|
||||||
|
|
||||||
|
The requirement to provide Installation Information does not include a
|
||||||
|
requirement to continue to provide support service, warranty, or updates
|
||||||
|
for a work that has been modified or installed by the recipient, or for
|
||||||
|
the User Product in which it has been modified or installed. Access to a
|
||||||
|
network may be denied when the modification itself materially and
|
||||||
|
adversely affects the operation of the network or violates the rules and
|
||||||
|
protocols for communication across the network.
|
||||||
|
|
||||||
|
Corresponding Source conveyed, and Installation Information provided,
|
||||||
|
in accord with this section must be in a format that is publicly
|
||||||
|
documented (and with an implementation available to the public in
|
||||||
|
source code form), and must require no special password or key for
|
||||||
|
unpacking, reading or copying.
|
||||||
|
|
||||||
|
7. Additional Terms.
|
||||||
|
|
||||||
|
"Additional permissions" are terms that supplement the terms of this
|
||||||
|
License by making exceptions from one or more of its conditions.
|
||||||
|
Additional permissions that are applicable to the entire Program shall
|
||||||
|
be treated as though they were included in this License, to the extent
|
||||||
|
that they are valid under applicable law. If additional permissions
|
||||||
|
apply only to part of the Program, that part may be used separately
|
||||||
|
under those permissions, but the entire Program remains governed by
|
||||||
|
this License without regard to the additional permissions.
|
||||||
|
|
||||||
|
When you convey a copy of a covered work, you may at your option
|
||||||
|
remove any additional permissions from that copy, or from any part of
|
||||||
|
it. (Additional permissions may be written to require their own
|
||||||
|
removal in certain cases when you modify the work.) You may place
|
||||||
|
additional permissions on material, added by you to a covered work,
|
||||||
|
for which you have or can give appropriate copyright permission.
|
||||||
|
|
||||||
|
Notwithstanding any other provision of this License, for material you
|
||||||
|
add to a covered work, you may (if authorized by the copyright holders of
|
||||||
|
that material) supplement the terms of this License with terms:
|
||||||
|
|
||||||
|
a) Disclaiming warranty or limiting liability differently from the
|
||||||
|
terms of sections 15 and 16 of this License; or
|
||||||
|
|
||||||
|
b) Requiring preservation of specified reasonable legal notices or
|
||||||
|
author attributions in that material or in the Appropriate Legal
|
||||||
|
Notices displayed by works containing it; or
|
||||||
|
|
||||||
|
c) Prohibiting misrepresentation of the origin of that material, or
|
||||||
|
requiring that modified versions of such material be marked in
|
||||||
|
reasonable ways as different from the original version; or
|
||||||
|
|
||||||
|
d) Limiting the use for publicity purposes of names of licensors or
|
||||||
|
authors of the material; or
|
||||||
|
|
||||||
|
e) Declining to grant rights under trademark law for use of some
|
||||||
|
trade names, trademarks, or service marks; or
|
||||||
|
|
||||||
|
f) Requiring indemnification of licensors and authors of that
|
||||||
|
material by anyone who conveys the material (or modified versions of
|
||||||
|
it) with contractual assumptions of liability to the recipient, for
|
||||||
|
any liability that these contractual assumptions directly impose on
|
||||||
|
those licensors and authors.
|
||||||
|
|
||||||
|
All other non-permissive additional terms are considered "further
|
||||||
|
restrictions" within the meaning of section 10. If the Program as you
|
||||||
|
received it, or any part of it, contains a notice stating that it is
|
||||||
|
governed by this License along with a term that is a further
|
||||||
|
restriction, you may remove that term. If a license document contains
|
||||||
|
a further restriction but permits relicensing or conveying under this
|
||||||
|
License, you may add to a covered work material governed by the terms
|
||||||
|
of that license document, provided that the further restriction does
|
||||||
|
not survive such relicensing or conveying.
|
||||||
|
|
||||||
|
If you add terms to a covered work in accord with this section, you
|
||||||
|
must place, in the relevant source files, a statement of the
|
||||||
|
additional terms that apply to those files, or a notice indicating
|
||||||
|
where to find the applicable terms.
|
||||||
|
|
||||||
|
Additional terms, permissive or non-permissive, may be stated in the
|
||||||
|
form of a separately written license, or stated as exceptions;
|
||||||
|
the above requirements apply either way.
|
||||||
|
|
||||||
|
8. Termination.
|
||||||
|
|
||||||
|
You may not propagate or modify a covered work except as expressly
|
||||||
|
provided under this License. Any attempt otherwise to propagate or
|
||||||
|
modify it is void, and will automatically terminate your rights under
|
||||||
|
this License (including any patent licenses granted under the third
|
||||||
|
paragraph of section 11).
|
||||||
|
|
||||||
|
However, if you cease all violation of this License, then your
|
||||||
|
license from a particular copyright holder is reinstated (a)
|
||||||
|
provisionally, unless and until the copyright holder explicitly and
|
||||||
|
finally terminates your license, and (b) permanently, if the copyright
|
||||||
|
holder fails to notify you of the violation by some reasonable means
|
||||||
|
prior to 60 days after the cessation.
|
||||||
|
|
||||||
|
Moreover, your license from a particular copyright holder is
|
||||||
|
reinstated permanently if the copyright holder notifies you of the
|
||||||
|
violation by some reasonable means, this is the first time you have
|
||||||
|
received notice of violation of this License (for any work) from that
|
||||||
|
copyright holder, and you cure the violation prior to 30 days after
|
||||||
|
your receipt of the notice.
|
||||||
|
|
||||||
|
Termination of your rights under this section does not terminate the
|
||||||
|
licenses of parties who have received copies or rights from you under
|
||||||
|
this License. If your rights have been terminated and not permanently
|
||||||
|
reinstated, you do not qualify to receive new licenses for the same
|
||||||
|
material under section 10.
|
||||||
|
|
||||||
|
9. Acceptance Not Required for Having Copies.
|
||||||
|
|
||||||
|
You are not required to accept this License in order to receive or
|
||||||
|
run a copy of the Program. Ancillary propagation of a covered work
|
||||||
|
occurring solely as a consequence of using peer-to-peer transmission
|
||||||
|
to receive a copy likewise does not require acceptance. However,
|
||||||
|
nothing other than this License grants you permission to propagate or
|
||||||
|
modify any covered work. These actions infringe copyright if you do
|
||||||
|
not accept this License. Therefore, by modifying or propagating a
|
||||||
|
covered work, you indicate your acceptance of this License to do so.
|
||||||
|
|
||||||
|
10. Automatic Licensing of Downstream Recipients.
|
||||||
|
|
||||||
|
Each time you convey a covered work, the recipient automatically
|
||||||
|
receives a license from the original licensors, to run, modify and
|
||||||
|
propagate that work, subject to this License. You are not responsible
|
||||||
|
for enforcing compliance by third parties with this License.
|
||||||
|
|
||||||
|
An "entity transaction" is a transaction transferring control of an
|
||||||
|
organization, or substantially all assets of one, or subdividing an
|
||||||
|
organization, or merging organizations. If propagation of a covered
|
||||||
|
work results from an entity transaction, each party to that
|
||||||
|
transaction who receives a copy of the work also receives whatever
|
||||||
|
licenses to the work the party's predecessor in interest had or could
|
||||||
|
give under the previous paragraph, plus a right to possession of the
|
||||||
|
Corresponding Source of the work from the predecessor in interest, if
|
||||||
|
the predecessor has it or can get it with reasonable efforts.
|
||||||
|
|
||||||
|
You may not impose any further restrictions on the exercise of the
|
||||||
|
rights granted or affirmed under this License. For example, you may
|
||||||
|
not impose a license fee, royalty, or other charge for exercise of
|
||||||
|
rights granted under this License, and you may not initiate litigation
|
||||||
|
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||||
|
any patent claim is infringed by making, using, selling, offering for
|
||||||
|
sale, or importing the Program or any portion of it.
|
||||||
|
|
||||||
|
11. Patents.
|
||||||
|
|
||||||
|
A "contributor" is a copyright holder who authorizes use under this
|
||||||
|
License of the Program or a work on which the Program is based. The
|
||||||
|
work thus licensed is called the contributor's "contributor version".
|
||||||
|
|
||||||
|
A contributor's "essential patent claims" are all patent claims
|
||||||
|
owned or controlled by the contributor, whether already acquired or
|
||||||
|
hereafter acquired, that would be infringed by some manner, permitted
|
||||||
|
by this License, of making, using, or selling its contributor version,
|
||||||
|
but do not include claims that would be infringed only as a
|
||||||
|
consequence of further modification of the contributor version. For
|
||||||
|
purposes of this definition, "control" includes the right to grant
|
||||||
|
patent sublicenses in a manner consistent with the requirements of
|
||||||
|
this License.
|
||||||
|
|
||||||
|
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||||
|
patent license under the contributor's essential patent claims, to
|
||||||
|
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||||
|
propagate the contents of its contributor version.
|
||||||
|
|
||||||
|
In the following three paragraphs, a "patent license" is any express
|
||||||
|
agreement or commitment, however denominated, not to enforce a patent
|
||||||
|
(such as an express permission to practice a patent or covenant not to
|
||||||
|
sue for patent infringement). To "grant" such a patent license to a
|
||||||
|
party means to make such an agreement or commitment not to enforce a
|
||||||
|
patent against the party.
|
||||||
|
|
||||||
|
If you convey a covered work, knowingly relying on a patent license,
|
||||||
|
and the Corresponding Source of the work is not available for anyone
|
||||||
|
to copy, free of charge and under the terms of this License, through a
|
||||||
|
publicly available network server or other readily accessible means,
|
||||||
|
then you must either (1) cause the Corresponding Source to be so
|
||||||
|
available, or (2) arrange to deprive yourself of the benefit of the
|
||||||
|
patent license for this particular work, or (3) arrange, in a manner
|
||||||
|
consistent with the requirements of this License, to extend the patent
|
||||||
|
license to downstream recipients. "Knowingly relying" means you have
|
||||||
|
actual knowledge that, but for the patent license, your conveying the
|
||||||
|
covered work in a country, or your recipient's use of the covered work
|
||||||
|
in a country, would infringe one or more identifiable patents in that
|
||||||
|
country that you have reason to believe are valid.
|
||||||
|
|
||||||
|
If, pursuant to or in connection with a single transaction or
|
||||||
|
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||||
|
covered work, and grant a patent license to some of the parties
|
||||||
|
receiving the covered work authorizing them to use, propagate, modify
|
||||||
|
or convey a specific copy of the covered work, then the patent license
|
||||||
|
you grant is automatically extended to all recipients of the covered
|
||||||
|
work and works based on it.
|
||||||
|
|
||||||
|
A patent license is "discriminatory" if it does not include within
|
||||||
|
the scope of its coverage, prohibits the exercise of, or is
|
||||||
|
conditioned on the non-exercise of one or more of the rights that are
|
||||||
|
specifically granted under this License. You may not convey a covered
|
||||||
|
work if you are a party to an arrangement with a third party that is
|
||||||
|
in the business of distributing software, under which you make payment
|
||||||
|
to the third party based on the extent of your activity of conveying
|
||||||
|
the work, and under which the third party grants, to any of the
|
||||||
|
parties who would receive the covered work from you, a discriminatory
|
||||||
|
patent license (a) in connection with copies of the covered work
|
||||||
|
conveyed by you (or copies made from those copies), or (b) primarily
|
||||||
|
for and in connection with specific products or compilations that
|
||||||
|
contain the covered work, unless you entered into that arrangement,
|
||||||
|
or that patent license was granted, prior to 28 March 2007.
|
||||||
|
|
||||||
|
Nothing in this License shall be construed as excluding or limiting
|
||||||
|
any implied license or other defenses to infringement that may
|
||||||
|
otherwise be available to you under applicable patent law.
|
||||||
|
|
||||||
|
12. No Surrender of Others' Freedom.
|
||||||
|
|
||||||
|
If conditions are imposed on you (whether by court order, agreement or
|
||||||
|
otherwise) that contradict the conditions of this License, they do not
|
||||||
|
excuse you from the conditions of this License. If you cannot convey a
|
||||||
|
covered work so as to satisfy simultaneously your obligations under this
|
||||||
|
License and any other pertinent obligations, then as a consequence you may
|
||||||
|
not convey it at all. For example, if you agree to terms that obligate you
|
||||||
|
to collect a royalty for further conveying from those to whom you convey
|
||||||
|
the Program, the only way you could satisfy both those terms and this
|
||||||
|
License would be to refrain entirely from conveying the Program.
|
||||||
|
|
||||||
|
13. Use with the GNU Affero General Public License.
|
||||||
|
|
||||||
|
Notwithstanding any other provision of this License, you have
|
||||||
|
permission to link or combine any covered work with a work licensed
|
||||||
|
under version 3 of the GNU Affero General Public License into a single
|
||||||
|
combined work, and to convey the resulting work. The terms of this
|
||||||
|
License will continue to apply to the part which is the covered work,
|
||||||
|
but the special requirements of the GNU Affero General Public License,
|
||||||
|
section 13, concerning interaction through a network will apply to the
|
||||||
|
combination as such.
|
||||||
|
|
||||||
|
14. Revised Versions of this License.
|
||||||
|
|
||||||
|
The Free Software Foundation may publish revised and/or new versions of
|
||||||
|
the GNU General Public License from time to time. Such new versions will
|
||||||
|
be similar in spirit to the present version, but may differ in detail to
|
||||||
|
address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the
|
||||||
|
Program specifies that a certain numbered version of the GNU General
|
||||||
|
Public License "or any later version" applies to it, you have the
|
||||||
|
option of following the terms and conditions either of that numbered
|
||||||
|
version or of any later version published by the Free Software
|
||||||
|
Foundation. If the Program does not specify a version number of the
|
||||||
|
GNU General Public License, you may choose any version ever published
|
||||||
|
by the Free Software Foundation.
|
||||||
|
|
||||||
|
If the Program specifies that a proxy can decide which future
|
||||||
|
versions of the GNU General Public License can be used, that proxy's
|
||||||
|
public statement of acceptance of a version permanently authorizes you
|
||||||
|
to choose that version for the Program.
|
||||||
|
|
||||||
|
Later license versions may give you additional or different
|
||||||
|
permissions. However, no additional obligations are imposed on any
|
||||||
|
author or copyright holder as a result of your choosing to follow a
|
||||||
|
later version.
|
||||||
|
|
||||||
|
15. Disclaimer of Warranty.
|
||||||
|
|
||||||
|
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||||
|
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||||
|
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||||
|
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||||
|
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||||
|
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
16. Limitation of Liability.
|
||||||
|
|
||||||
|
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||||
|
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||||
|
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||||
|
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||||
|
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||||
|
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||||
|
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||||
|
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||||
|
SUCH DAMAGES.
|
||||||
|
|
||||||
|
17. Interpretation of Sections 15 and 16.
|
||||||
|
|
||||||
|
If the disclaimer of warranty and limitation of liability provided
|
||||||
|
above cannot be given local legal effect according to their terms,
|
||||||
|
reviewing courts shall apply local law that most closely approximates
|
||||||
|
an absolute waiver of all civil liability in connection with the
|
||||||
|
Program, unless a warranty or assumption of liability accompanies a
|
||||||
|
copy of the Program in return for a fee.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
How to Apply These Terms to Your New Programs
|
||||||
|
|
||||||
|
If you develop a new program, and you want it to be of the greatest
|
||||||
|
possible use to the public, the best way to achieve this is to make it
|
||||||
|
free software which everyone can redistribute and change under these terms.
|
||||||
|
|
||||||
|
To do so, attach the following notices to the program. It is safest
|
||||||
|
to attach them to the start of each source file to most effectively
|
||||||
|
state the exclusion of warranty; and each file should have at least
|
||||||
|
the "copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
|
<one line to give the program's name and a brief idea of what it does.>
|
||||||
|
Copyright (C) <year> <name of author>
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
If the program does terminal interaction, make it output a short
|
||||||
|
notice like this when it starts in an interactive mode:
|
||||||
|
|
||||||
|
<program> Copyright (C) <year> <name of author>
|
||||||
|
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||||
|
This is free software, and you are welcome to redistribute it
|
||||||
|
under certain conditions; type `show c' for details.
|
||||||
|
|
||||||
|
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||||
|
parts of the General Public License. Of course, your program's commands
|
||||||
|
might be different; for a GUI interface, you would use an "about box".
|
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or school,
|
||||||
|
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||||
|
For more information on this, and how to apply and follow the GNU GPL, see
|
||||||
|
<https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
The GNU General Public License does not permit incorporating your program
|
||||||
|
into proprietary programs. If your program is a subroutine library, you
|
||||||
|
may consider it more useful to permit linking proprietary applications with
|
||||||
|
the library. If this is what you want to do, use the GNU Lesser General
|
||||||
|
Public License instead of this License. But first, please read
|
||||||
|
<https://www.gnu.org/licenses/why-not-lgpl.html>.
|
||||||
19
LICENSE.md
19
LICENSE.md
@@ -1,19 +0,0 @@
|
|||||||
Copyright (c) 2023 Elaina Claus
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
||||||
163
Makefile
163
Makefile
@@ -1,71 +1,120 @@
|
|||||||
include := './include'
|
# Copyright (C) 2025 Elaina Claus
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
mbr_source_files := $(wildcard src/mbr/*.nasm)
|
INCDIR := include
|
||||||
vbr_source_files := $(wildcard src/vbr/*.nasm)
|
BUILD_DIR := build
|
||||||
stage2_source_files := $(wildcard src/stage2/*.nasm)
|
IMG := $(BUILD_DIR)/disk.img
|
||||||
boottest_source_files := $(wildcard src/miniboot32/*.nasm)
|
IMGZ := $(BUILD_DIR)/disk.img.gz
|
||||||
|
DEP_DIR := $(BUILD_DIR)/deps
|
||||||
mbr_binary_files := $(patsubst src/mbr/%.nasm, build/%.bin, $(mbr_source_files))
|
|
||||||
vbr_binary_files := $(patsubst src/vbr/%.nasm, build/%.bin, $(vbr_source_files))
|
|
||||||
stage2_binary_files := $(patsubst src/stage2/%.nasm, build/%.bin, $(stage2_source_files))
|
|
||||||
boottest_binary_files := $(patsubst src/miniboot32/%.nasm, build/%.bin, $(boottest_source_files))
|
|
||||||
|
|
||||||
build_dir := 'build'
|
|
||||||
|
|
||||||
# Get current Git version (tag) and hash
|
# Get current Git version (tag) and hash
|
||||||
GIT_VERSION := $(shell git describe --tags)
|
GIT_VERSION := $(shell git describe --tags --always --dirty 2>/dev/null || echo unknown)
|
||||||
GIT_HASH := $(shell git rev-parse HEAD)
|
GIT_HASH := $(shell git rev-parse HEAD 2>/dev/null || echo unknown)
|
||||||
GIT_NASM_DEFINES := -D __GIT_VER__='"$(GIT_VERSION)"' -D __GIT_HASH__='"$(GIT_HASH)"'
|
GIT_NASM_DEFINES := -D __GIT_VER__='"$(GIT_VERSION)"' -D __GIT_HASH__='"$(GIT_HASH)"'
|
||||||
|
|
||||||
iso := '/tmp/disk.img'
|
NASMFLAGS := -Wall -f bin -i$(INCDIR)/ $(GIT_NASM_DEFINES)
|
||||||
isoz := 'disk.img.gz'
|
|
||||||
|
|
||||||
qemu_args := -L ./bin/ -bios bios.bin -cpu pentium3 -m 128 -S -s -monitor stdio -nic none
|
QEMU ?= qemu-system-i386
|
||||||
.PHONY: all mbr vbr stage2 boottest clean run run_bochs iso isoz
|
QEMU_ARGS := \
|
||||||
|
-M pc-i440fx-8.2,accel=tcg \
|
||||||
|
-cpu pentium3 \
|
||||||
|
-m 64M \
|
||||||
|
-rtc base=localtime \
|
||||||
|
-boot c \
|
||||||
|
-vga std \
|
||||||
|
-display gtk,gl=off \
|
||||||
|
-device e1000,netdev=n0,mac=52:54:00:12:34:56 \
|
||||||
|
-netdev user,id=n0 \
|
||||||
|
-device piix3-usb-uhci \
|
||||||
|
-parallel null \
|
||||||
|
-serial null -serial none -serial none -serial none \
|
||||||
|
-chardev file,id=dbg,path=bochs-e9.log,append=on \
|
||||||
|
-device isa-debugcon,iobase=0xe9,chardev=dbg \
|
||||||
|
-msg timestamp=on
|
||||||
|
|
||||||
all: $(iso) $(isoz) $(mbr_binary_files) $(vbr_binary_files) $(stage2_binary_files)
|
MBR_SRCS := $(wildcard src/mbr/*.nasm)
|
||||||
mbr: $(mbr_binary_files)
|
VBR_SRCS := $(wildcard src/vbr/*.nasm)
|
||||||
vbr: $(vbr_binary_files)
|
STAGE2_SRCS := $(wildcard src/stage2/*.nasm)
|
||||||
stage2: $(stage2_binary_files)
|
BOOTTEST_SRCS := $(wildcard src/miniboot32/*.nasm)
|
||||||
boottest: $(boottest_binary_files)
|
|
||||||
|
|
||||||
clean:
|
MBR_BINS := $(patsubst src/mbr/%.nasm, $(BUILD_DIR)/mbr/%.bin, $(MBR_SRCS))
|
||||||
@rm -rvf *.map
|
VBR_BINS := $(patsubst src/vbr/%.nasm, $(BUILD_DIR)/vbr/%.bin, $(VBR_SRCS))
|
||||||
@rm -rvf $(build_dir)/*
|
STAGE2_BINS := $(patsubst src/stage2/%.nasm, $(BUILD_DIR)/stage2/%.bin, $(STAGE2_SRCS))
|
||||||
@rm -rvf $(iso)
|
BOOTTEST_BINS := $(patsubst src/miniboot32/%.nasm, $(BUILD_DIR)/miniboot32/%.bin, $(BOOTTEST_SRCS))
|
||||||
@rm -rvf $(isoz)
|
|
||||||
|
|
||||||
run: $(iso)
|
ALL_BINS := $(MBR_BINS) $(VBR_BINS) $(STAGE2_BINS) $(BOOTTEST_BINS)
|
||||||
@sudo qemu-system-i386 $(qemu_args) -hda $(iso)
|
|
||||||
|
|
||||||
run_bochs: $(iso)
|
.DEFAULT_GOAL := all
|
||||||
|
.DELETE_ON_ERROR:
|
||||||
|
|
||||||
|
.PHONY: all mbr vbr stage2 boottest clean run run_qemu run_bochs img imgz help
|
||||||
|
all: $(IMG) $(IMGZ) $(ALL_BINS)
|
||||||
|
mbr: $(MBR_BINS)
|
||||||
|
vbr: $(VBR_BINS)
|
||||||
|
stage2: $(STAGE2_BINS)
|
||||||
|
boottest: $(BOOTTEST_BINS)
|
||||||
|
|
||||||
|
# Build Rules
|
||||||
|
|
||||||
|
$(BUILD_DIR)/mbr/%.bin: src/mbr/%.nasm | $(DEP_DIR)
|
||||||
|
@mkdir -p $(@D)
|
||||||
|
@nasm $(NASMFLAGS) -MD $(DEP_DIR)/$*.d -MT $@ $< -o $@
|
||||||
|
|
||||||
|
$(BUILD_DIR)/vbr/%.bin: src/vbr/%.nasm | $(DEP_DIR)
|
||||||
|
@mkdir -p $(@D)
|
||||||
|
@nasm $(NASMFLAGS) -MD $(DEP_DIR)/$*.d -MT $@ $< -o $@
|
||||||
|
|
||||||
|
$(BUILD_DIR)/stage2/%.bin: src/stage2/%.nasm | $(DEP_DIR)
|
||||||
|
@mkdir -p $(@D)
|
||||||
|
@nasm $(NASMFLAGS) -MD $(DEP_DIR)/$*.d -MT $@ $< -o $@
|
||||||
|
|
||||||
|
$(BUILD_DIR)/miniboot32/%.bin: src/miniboot32/%.nasm | $(DEP_DIR)
|
||||||
|
@mkdir -p $(@D)
|
||||||
|
@nasm $(NASMFLAGS) -MD $(DEP_DIR)/$*.d -MT $@ $< -o $@
|
||||||
|
|
||||||
|
|
||||||
|
$(DEP_DIR):
|
||||||
|
@mkdir -p $@
|
||||||
|
|
||||||
|
# Disk image's
|
||||||
|
|
||||||
|
$(IMG): $(ALL_BINS) | scripts/create-disk.sh
|
||||||
|
@scripts/create-disk.sh
|
||||||
|
|
||||||
|
$(IMGZ): $(IMG)
|
||||||
|
@gzip -9kc $(IMG) > $(IMGZ)
|
||||||
|
|
||||||
|
img: $(IMG)
|
||||||
|
@file $(IMG)
|
||||||
|
|
||||||
|
imgz: $(IMGZ)
|
||||||
|
@file $(IMGZ)
|
||||||
|
|
||||||
|
# Helpers
|
||||||
|
|
||||||
|
run: $(IMG)
|
||||||
|
@$(QEMU) $(QEMU_ARGS) -drive file=$(IMG),if=ide,index=0,media=disk,format=raw \
|
||||||
|
|
||||||
|
run_bochs: $(IMG)
|
||||||
@bochs -q
|
@bochs -q
|
||||||
|
|
||||||
iso: $(iso)
|
clean:
|
||||||
@file $(iso)
|
@$(RM) -rv $(BUILD_DIR)/
|
||||||
|
|
||||||
isoz: $(isoz)
|
help:
|
||||||
@file $(isoz)
|
@awk '/^[A-Za-z0-9_%-]+:/{print $$1}' $(MAKEFILE_LIST) | sed 's/:$$//' | sort -u
|
||||||
|
|
||||||
build/%.bin: src/mbr/%.nasm
|
# Include header deps
|
||||||
@mkdir -p $(shell dirname $@)
|
-include $(wildcard $(DEP_DIR)/*.d)
|
||||||
@nasm -i$(include) -Wall -f bin $(GIT_NASM_DEFINES) $< -o $@
|
|
||||||
|
|
||||||
build/%.bin: src/vbr/%.nasm
|
|
||||||
@mkdir -p $(shell dirname $@)
|
|
||||||
@nasm -i$(include) -Wall -f bin $(GIT_NASM_DEFINES) $< -o $@
|
|
||||||
|
|
||||||
build/%.bin: src/stage2/%.nasm
|
|
||||||
@mkdir -p $(shell dirname $@)
|
|
||||||
@nasm -i$(include) -Wall -f bin $(GIT_NASM_DEFINES) $< -o $@
|
|
||||||
|
|
||||||
build/%.bin: src/miniboot32/%.nasm
|
|
||||||
@mkdir -p $(shell dirname $@)
|
|
||||||
@nasm -i$(include) -Wall -f bin $(GIT_NASM_DEFINES) $< -o $@
|
|
||||||
|
|
||||||
$(iso): $(mbr_binary_files) $(vbr_binary_files) $(stage2_binary_files) $(boottest_binary_files)
|
|
||||||
@echo root access needed to create disk image...
|
|
||||||
@sudo scripts/create-disk.sh
|
|
||||||
|
|
||||||
$(isoz): $(iso)
|
|
||||||
@gzip -9kc $(iso) > $(isoz)
|
|
||||||
49
README.md
49
README.md
@@ -1,6 +1,8 @@
|
|||||||
# Stevia Bootloader
|
# Stevia Bootloader
|
||||||
|
|
||||||
Stevia is a lightweight, hobby bootloader written in Assembly and C, designed for educational purposes. It targets x86 (Pentium III era) and aims to be simple, approachable, and understandable, focusing on minimalism and core functionality.
|
Stevia is a lightweight, hobby bootloader written in Assembly (NASM) and is designed for educational purposes. It targets 686+ and aims to be simple, approachable, and understandable, focusing on minimalism and core functionality.
|
||||||
|
|
||||||
|
Please note: **Most development currently takes place in Bochs (and maybe is tested on QEMU), due to this, the code in this repo has not been tested throughly aginist real hardware. As with most projects of this nature, there is a risk of damage due to improper programing of hardware, while careful effort is taken to not break the computer...accidents and mistakes can/do happen.**
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
@@ -10,18 +12,13 @@ Stevia is a lightweight, hobby bootloader written in Assembly and C, designed fo
|
|||||||
- **Stage 2 Bootloader**: Loads the kernel into memory and passes control.
|
- **Stage 2 Bootloader**: Loads the kernel into memory and passes control.
|
||||||
- **Basic Filesystem Support**: Initial filesystem recognition (details depend on implemented filesystem support).
|
- **Basic Filesystem Support**: Initial filesystem recognition (details depend on implemented filesystem support).
|
||||||
- **Memory Map Parsing**: Detects available memory regions via BIOS interrupts.
|
- **Memory Map Parsing**: Detects available memory regions via BIOS interrupts.
|
||||||
- **GDT Initialization**: Sets up the Global Descriptor Table for protected mode.
|
- **GDT Initialization**: Sets up the Global Descriptor Table for protected/unreal mode.
|
||||||
|
|
||||||
### In Progress
|
|
||||||
|
|
||||||
- **Interrupt Descriptor Table (IDT) Setup**: Setting up basic interrupt handling.
|
|
||||||
- **Basic Keyboard Input**: Initial support for capturing keystrokes.
|
|
||||||
|
|
||||||
### Planned Features
|
### Planned Features
|
||||||
|
|
||||||
- **Task Scheduling**: Basic round-robin task switching.
|
- **Interrupt Descriptor Table (IDT) Setup**: Setting up basic interrupt handling.
|
||||||
|
- **Basic Keyboard Input**: Initial support for capturing keystrokes.
|
||||||
- **Filesystem Expansion**: Support for additional filesystems.
|
- **Filesystem Expansion**: Support for additional filesystems.
|
||||||
- **More Robust Driver Support**: Additional hardware drivers, such as for storage devices.
|
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
@@ -29,42 +26,40 @@ Stevia is a lightweight, hobby bootloader written in Assembly and C, designed fo
|
|||||||
|
|
||||||
To build and run Stevia, you will need the following tools installed on your system:
|
To build and run Stevia, you will need the following tools installed on your system:
|
||||||
|
|
||||||
- **Assembler**: NASM for assembling bootloader components.
|
- **Assembler**: NASM for assembling bootloader components, you could use a compatible assembler but YMMV.
|
||||||
- **C Compiler**: GCC (cross-compiler recommended).
|
- **GNU make**: For building the project.
|
||||||
- **Emulator**: Bochs or QEMU for testing.
|
- **mtools**: To access the FAT partition
|
||||||
- **GNU Make**: For building the project.
|
- **fdisk**: To create disk images and setup partition tables
|
||||||
- **Utilities**:
|
- **dosfstools**: FAT32 creation
|
||||||
- **dd**: For creating raw disk images.
|
- **an x86 Emulator**: Bochs is the primary dev target, but stevia should run on any x86 emulator/hardware with at least a Pentium 3 and 640KiB of memory.
|
||||||
- **losetup** (Linux only): For associating loop devices with disk images.
|
|
||||||
- **sfdisk**: For creating DOS disk partitions.
|
|
||||||
- **mkfs.fat**: For formatting partitions as FAT32.
|
|
||||||
- **hdiutil** (macOS only): For attaching disk images.
|
|
||||||
- **newfs\_msdos** (macOS only): For formatting FAT32 partitions.
|
|
||||||
|
|
||||||
### Building and Running
|
### Building and Running
|
||||||
|
|
||||||
1. **Clone the repository**:
|
1. **Clone the repository**:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
git clone https://github.com/Nivirx/stevia.git
|
git clone https://github.com/Nivirx/stevia.git
|
||||||
cd stevia
|
cd stevia
|
||||||
```
|
```
|
||||||
|
|
||||||
2. **Build the bootloader and create a bootable disk image**:
|
2. **Build the bootloader and create a bootable disk image**:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
sudo make
|
make
|
||||||
```
|
```
|
||||||
|
|
||||||
3. **Run using Bochs**:
|
3. **Run using Bochs**:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
bochs -f bochsrc.txt
|
bochs -q -f bochsrc.txt
|
||||||
```
|
```
|
||||||
|
|
||||||
## Project Goals
|
## Project Goals
|
||||||
|
|
||||||
Stevia is intended to be a learning tool for those interested in low-level programming, focusing on understanding the basics of how a computer starts up and manages early system resources. Contributions and forks are welcome, especially from those interested in expanding the functionality.
|
Stevia is intended to be a learning tool for those interested in low-level programming, focusing on understanding the basics of how a computer starts up and manages early system resources.
|
||||||
|
|
||||||
## Contributing
|
You are welcome to fork/review the code base but I am generally not accepting PR's/Contributions to the code at this time.
|
||||||
|
|
||||||
We welcome contributions! Feel free to open issues for bugs or feature requests, and submit pull requests for any improvements. Please ensure that your code follows the existing style and includes appropriate comments.
|
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for more details.
|
This project is licensed under the GPLv3 License. See the [LICENSE](LICENSE.md) or [COPYING](COPYING) file for more details.
|
||||||
|
|||||||
68
bochsrc.txt
68
bochsrc.txt
@@ -1,44 +1,44 @@
|
|||||||
# configuration file generated by Bochs
|
#
|
||||||
plugin_ctrl: voodoo=false, unmapped=true, biosdev=true, speaker=true, extfpuirq=true, parallel=true, serial=true, busmouse=false, e1000=false, es1370=false, gameport=true, ne2k=false, sb16=false, usb_uhci=false, usb_ohci=false, usb_ehci=false, usb_xhci=false
|
# Bochs config
|
||||||
|
#
|
||||||
config_interface: textconfig
|
config_interface: textconfig
|
||||||
display_library: wx
|
display_library: x, options=gui_debug
|
||||||
memory: guest=64, host=64, block_size=128
|
plugin_ctrl: voodoo=false, unmapped=true, biosdev=true, speaker=true, extfpuirq=true, parallel=true, serial=true, busmouse=false, e1000=true, es1370=false, gameport=true, ne2k=false, sb16=false, usb_uhci=true, usb_ohci=false, usb_ehci=false, usb_xhci=false
|
||||||
romimage: file="/usr/share/bochs/BIOS-bochs-legacy", address=0x00000000, options=none, flash_data=none
|
print_timestamps: enabled=1
|
||||||
vgaromimage: file="/usr/share/bochs/VGABIOS-lgpl-latest"
|
|
||||||
boot: disk
|
|
||||||
floppy_bootsig_check: disabled=0
|
|
||||||
floppya: type=1_44
|
|
||||||
# no floppyb
|
|
||||||
ata0: enabled=true, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14
|
|
||||||
ata0-master: type=disk, path="./disk.img", mode=flat, cylinders=0, heads=0, spt=0, sect_size=512, model="Stevia Disk", biosdetect=auto, translation=lba
|
|
||||||
ata0-slave: type=none
|
|
||||||
ata1: enabled=false
|
|
||||||
ata1-master: type=none
|
|
||||||
ata1-slave: type=none
|
|
||||||
ata2: enabled=false
|
|
||||||
ata3: enabled=false
|
|
||||||
optromimage1: file=none
|
|
||||||
optromimage2: file=none
|
|
||||||
optromimage3: file=none
|
|
||||||
optromimage4: file=none
|
|
||||||
optramimage1: file=none
|
|
||||||
optramimage2: file=none
|
|
||||||
optramimage3: file=none
|
|
||||||
optramimage4: file=none
|
|
||||||
pci: enabled=1, chipset=i440fx, slot1=none, slot2=none, slot3=none, slot4=none, slot5=none
|
|
||||||
vga: extension=vbe, update_freq=10, realtime=1, ddc=builtin
|
|
||||||
cpu: count=1, ips=1000000, model=p3_katmai, reset_on_triple_fault=1, cpuid_limit_winnt=0, ignore_bad_msrs=1, mwait_is_nop=0
|
|
||||||
print_timestamps: enabled=0
|
|
||||||
port_e9_hack: enabled=false, all_rings=false
|
|
||||||
private_colormap: enabled=0
|
private_colormap: enabled=0
|
||||||
clock: sync=none, time0=local, rtc_sync=0
|
|
||||||
# no cmosimage
|
|
||||||
log: -
|
log: -
|
||||||
logprefix: %t%e%d
|
logprefix: %t%e%d
|
||||||
debug: action=ignore
|
debug: action=ignore
|
||||||
info: action=report
|
info: action=report
|
||||||
error: action=report
|
error: action=report
|
||||||
panic: action=ask
|
panic: action=ask
|
||||||
|
magic_break: enabled=1
|
||||||
|
port_e9_hack: enabled=1, all_rings=false
|
||||||
|
#
|
||||||
|
# Machine Spec
|
||||||
|
# 1x Pentium 3 @ (1M IPS) w/ 64MiB of System memory on the i440fx
|
||||||
|
cpu: count=1, ips=1000000, model=p3_katmai, reset_on_triple_fault=0, cpuid_limit_winnt=0, ignore_bad_msrs=1, mwait_is_nop=0
|
||||||
|
memory: guest=64, host=64, block_size=128
|
||||||
|
romimage: file="/usr/share/bochs/BIOS-bochs-legacy", address=0x00000000, options=none, flash_data=none
|
||||||
|
vgaromimage: file="/usr/share/vgabios/vgabios-stdvga.bin"
|
||||||
|
pci: enabled=1, chipset=i440fx
|
||||||
|
vga: extension=vbe, update_freq=10, realtime=1, ddc=builtin
|
||||||
|
clock: sync=none, time0=local, rtc_sync=0
|
||||||
|
#
|
||||||
|
# Disks
|
||||||
|
#
|
||||||
|
boot: disk
|
||||||
|
floppy_bootsig_check: disabled=0
|
||||||
|
floppya: type=1_44
|
||||||
|
floppyb: type=1_44
|
||||||
|
ata0: enabled=true, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14
|
||||||
|
ata0-master: type=disk, path="./build/disk.img", mode=flat, cylinders=0, heads=0, spt=0, sect_size=512, model="Stevia Disk", biosdetect=auto, translation=lba
|
||||||
|
ata0-slave: type=none
|
||||||
|
#
|
||||||
|
# Other hardware
|
||||||
|
#
|
||||||
|
usb_ehci: enabled=1, companion=ohci
|
||||||
|
e1000: enabled=1, mac=52:54:00:12:34:56, ethmod=null
|
||||||
keyboard: type=mf, serial_delay=150, paste_delay=100000, user_shortcut=none
|
keyboard: type=mf, serial_delay=150, paste_delay=100000, user_shortcut=none
|
||||||
mouse: type=none, enabled=false, toggle=ctrl+mbutton
|
mouse: type=none, enabled=false, toggle=ctrl+mbutton
|
||||||
sound: waveoutdrv=dummy, waveout=none, waveindrv=dummy, wavein=none, midioutdrv=dummy, midiout=none
|
sound: waveoutdrv=dummy, waveout=none, waveindrv=dummy, wavein=none, midioutdrv=dummy, midiout=none
|
||||||
@@ -49,5 +49,3 @@ com1: enabled=true, mode=null
|
|||||||
com2: enabled=false
|
com2: enabled=false
|
||||||
com3: enabled=false
|
com3: enabled=false
|
||||||
com4: enabled=false
|
com4: enabled=false
|
||||||
magic_break: enabled=1
|
|
||||||
port_e9_hack: enabled=1, all_rings=false
|
|
||||||
|
|||||||
@@ -207,24 +207,45 @@ Each GDT entry is 8 bytes:
|
|||||||
|
|
||||||
## **5. Memory Layout Example**
|
## **5. Memory Layout Example**
|
||||||
|
|
||||||
### **Low Memory (First MiB)**
|
### **Low Memory/Upper Memory map (<= 1MiB)**
|
||||||
|
|
||||||
| Start | End | Size | Type | Description |
|
| Start | End | Size | Type | Description |
|
||||||
|-------------|-------------|-----------------|-----------------------|----------------------------------|
|
|-------------|-------------|-----------------|----------------------|--------------------------------|
|
||||||
| 0x00000000 | 0x000003FF | 1 KiB | RAM (partially unusable) | Real Mode IVT (Interrupt Vector Table) |
|
| 0x00000000 | 0x000003FF | 1 KiB | RAM reclaimable~1~ | Real Mode IVT |
|
||||||
| 0x00000400 | 0x000004FF | 256 bytes | RAM (partially unusable) | BDA (BIOS data area) |
|
| 0x00000400 | 0x000004FF | 256 bytes | RAM reclaimable~1~ | BDA |
|
||||||
| 0x00000500 | 0x00007BFF | almost 30 KiB | RAM - free for use | Conventional memory |
|
| 0x00000500 | 0x00007BFF | 29 KiB + 767b | RAM - free | Conventional memory |
|
||||||
| 0x00007C00 | 0x00007DFF | 512 bytes | RAM (partially unusable) | OS BootSector |
|
| 0x00007C00 | 0x00007DFF | 512 bytes | RAM reclaimable~2~ | OS BootSector |
|
||||||
| 0x00007E00 | 0x0007FFFF | 480.5 KiB | RAM - free for use | Conventional memory |
|
| 0x00007E00 | 0x0007FFFF | 480.5 KiB | RAM - free | Conventional memory |
|
||||||
| 0x00080000 | 0x0009FFFF | 128 KiB | RAM (partially unusable) | EBDA (Extended BIOS Data Area) |
|
| 0x00080000 | 0x0009FFFF | 128 KiB | RAM (unusable)~1~ | EBDA (Extended BIOS Data Area) |
|
||||||
| 0x000A0000 | 0x000FFFFF | 384 KiB | various (unusable) | Video memory, ROM Area |
|
| 0x000A0000 | 0x000FFFFF | 384 KiB | Upper RAM (unusable) | Video memory, ROM Area |
|
||||||
|
|
||||||
### **Extended Memory (Above 1 MiB)**
|
1. Reclaimable in the event that you *never* need the BIOS again & once the CPU is in protected mode.
|
||||||
|
2. Reclaimable after you are done with with the MBR/VBR stages.
|
||||||
|
|
||||||
|
### **Extended Memory (> 1 MiB)**
|
||||||
|
|
||||||
|
This is only an example, you should always check the memory map.
|
||||||
|
|
||||||
| Start | End | Size | Description |
|
| Start | End | Size | Description |
|
||||||
|-------------|-------------|-----------------|------------------------|
|
|-------------|-------------|-----------------|---------------------------------------|
|
||||||
| 0x00100000 | 0x00EFFFFF | 14 MiB | RAM - free for use |
|
| 0x00100000 | 0x00EFFFFF | 14 MiB | RAM(?) - free for use |
|
||||||
| 0x00F00000 | 0x00FFFFFF | 1 MiB | Possible memory-mapped hardware (ISA) |
|
| 0x00F00000 | 0x00FFFFFF | 1 MiB | Possible memory-mapped hardware (ISA) |
|
||||||
| 0x01000000 | ? | ? | More extended memory |
|
| 0x01000000 | ? | ? | More extended memory |
|
||||||
| 0xC0000000 | 0xFFFFFFFF | 1 GiB | Memory mapped PCI devices, BIOS, etc. |
|
| 0xC0000000 | 0xFFFFFFFF | 1 GiB | Memory mapped PCI devices, BIOS, etc. |
|
||||||
| 0x0000000100000000 | ? | ? | RAM - usable in PAE/64-bit mode |
|
| 0x0000000100000000 | ? | ? | RAM(?) - usable in PAE/64-bit mode |
|
||||||
|
|
||||||
|
|
||||||
|
## **6. Stage2 Memory Layout **
|
||||||
|
|
||||||
|
Overall, Tiny (64 KiB page) Code/Data, Flat 4GiB mapping in gs/fs after unreal switch
|
||||||
|
|
||||||
|
| Start | End | Size (Bytes) | Type | Description |
|
||||||
|
|-------------|-------------|--------------|--------------------|----------------------------|
|
||||||
|
| 0x00000000 | 0x000003FF | 0x400 | RAM - (BIOS) | Real Mode IVT |
|
||||||
|
| 0x00000400 | 0x000004FF | 0x100 | RAM - (BIOS) | BDA |
|
||||||
|
| 0x00000500 | 0x000042FF | 0x3E00 | RAM - .text/.data | Code and constants/strings |
|
||||||
|
| 0x00004300 | 0x000044FF | 0x100 | RAM - .sign | EOF marker/signature |
|
||||||
|
| 0x00004500 | 0x000074FF | 0x3000 | RAM - bss | Runtime data/stack |
|
||||||
|
| 0x00007500 | 0x00007FFF | 0xB00 | RAM - reserved | Reserved |
|
||||||
|
| 0x00008000 | 0x0000DFFF | 0x6000 | RAM - heap | Conventional memory |
|
||||||
|
| 0x0000F000 | 0x0000FFFF | 0x1000 | RAM - reserved | Reserved |
|
||||||
24
docs/okteta/structures/mbr/main.osd
Normal file
24
docs/okteta/structures/mbr/main.osd
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<data>
|
||||||
|
<struct name="MBR">
|
||||||
|
<!-- 446 bytes: bootstrap code -->
|
||||||
|
<array name="bootCode" length="446">
|
||||||
|
<primitive type="UInt8"/>
|
||||||
|
</array>
|
||||||
|
|
||||||
|
<!-- 4 x 16-byte partition entries -->
|
||||||
|
<array name="partitions" length="4">
|
||||||
|
<struct name="PartitionEntry">
|
||||||
|
<primitive name="status" type="UInt8"/> <!-- 0x80=bootable -->
|
||||||
|
<array name="chsFirst" length="3"><primitive type="UInt8"/></array>
|
||||||
|
<primitive name="type" type="UInt8"/>
|
||||||
|
<array name="chsLast" length="3"><primitive type="UInt8"/></array>
|
||||||
|
<primitive name="lbaStart" type="UInt32"/>
|
||||||
|
<primitive name="lbaSectors" type="UInt32"/>
|
||||||
|
</struct>
|
||||||
|
</array>
|
||||||
|
|
||||||
|
<!-- Signature 0x55AA (little-endian UInt16 == 0xAA55 on disk) -->
|
||||||
|
<primitive name="signature" type="UInt16"/>
|
||||||
|
</struct>
|
||||||
|
</data>
|
||||||
12
docs/okteta/structures/mbr/metadata.desktop
Normal file
12
docs/okteta/structures/mbr/metadata.desktop
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
[Desktop Entry]
|
||||||
|
Icon=application-x-executable
|
||||||
|
Type=Service
|
||||||
|
ServiceTypes=KPluginInfo
|
||||||
|
Name=Stevia MBR Structure
|
||||||
|
X-KDE-PluginInfo-Author=Elaina Claus
|
||||||
|
X-KDE-PluginInfo-Name=mbr
|
||||||
|
X-KDE-PluginInfo-Version=1.0
|
||||||
|
X-KDE-PluginInfo-Website=https://chtm.me
|
||||||
|
X-KDE-PluginInfo-Category=structure
|
||||||
|
X-KDE-PluginInfo-License=MIT
|
||||||
|
X-KDE-PluginInfo-EnabledByDefault=false
|
||||||
57
docs/okteta/structures/vbr/main.osd
Normal file
57
docs/okteta/structures/vbr/main.osd
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<data>
|
||||||
|
<struct name="VBR">
|
||||||
|
<!-- 3 bytes: jmp over bpb code -->
|
||||||
|
<array name="jmpcode" length="3">
|
||||||
|
<primitive name="opcode" type="UInt8"/>
|
||||||
|
</array>
|
||||||
|
|
||||||
|
<array name="bs_ident" length="8">
|
||||||
|
<primitive type="Char"/>
|
||||||
|
</array>
|
||||||
|
|
||||||
|
<struct name="FAT32_bpb">
|
||||||
|
<primitive name="BytesPerSector" type="UInt16"/>
|
||||||
|
<primitive name="SectorsPerCluster" type="UInt8"/>
|
||||||
|
<primitive name="ReservedSectors" type="UInt16"/>
|
||||||
|
<primitive name="FatCount" type="UInt8"/>
|
||||||
|
<primitive name="RootEntryCount16" type="UInt16"/>
|
||||||
|
<primitive name="TotalSectors16" type="UInt16"/>
|
||||||
|
<primitive name="MediaDesc" type="UInt8"/>
|
||||||
|
<primitive name="FATSize16" type="UInt16"/>
|
||||||
|
<primitive name="SectorsPerTrack" type="UInt16"/>
|
||||||
|
<primitive name="HeadCount" type="UInt16"/>
|
||||||
|
<primitive name="HiddenSectors" type="UInt32"/>
|
||||||
|
<primitive name="TotalSectors32" type="UInt32"/>
|
||||||
|
</struct>
|
||||||
|
|
||||||
|
<struct name="FAT32_ebpb">
|
||||||
|
<primitive name="FATSize32" type="UInt32"/>
|
||||||
|
<primitive name="ExtFlags" type="UInt16"/>
|
||||||
|
<primitive name="FSVersion" type="UInt16"/>
|
||||||
|
<primitive name="RootDirCluster" type="UInt32"/>
|
||||||
|
<primitive name="FSInfoSector" type="UInt16"/>
|
||||||
|
<primitive name="BkBootSector" type="UInt16"/>
|
||||||
|
<array name="reserved0" length="12">
|
||||||
|
<primitive type="uint8"/>
|
||||||
|
</array>
|
||||||
|
<primitive name="DriveNumber" type="UInt8"/>
|
||||||
|
<primitive name="NtFlags" type="UInt8"/>
|
||||||
|
<primitive name="Signature" type="UInt8"/>
|
||||||
|
<primitive name="VolumeId" type="UInt32"/>
|
||||||
|
<array name="VolumeLabel" length="11">
|
||||||
|
<primitive type="Char"/>
|
||||||
|
</array>
|
||||||
|
<array name="FilesystemIdent" length="8">
|
||||||
|
<primitive type="Char"/>
|
||||||
|
</array>
|
||||||
|
</struct>
|
||||||
|
|
||||||
|
<array name="BootCode" length="420">
|
||||||
|
<primitive type="UInt8"/>
|
||||||
|
</array>
|
||||||
|
|
||||||
|
<!-- Signature 0xAA55 -->
|
||||||
|
<primitive name="signature" type="UInt16"/>
|
||||||
|
</struct>
|
||||||
|
</data>
|
||||||
12
docs/okteta/structures/vbr/metadata.desktop
Normal file
12
docs/okteta/structures/vbr/metadata.desktop
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
[Desktop Entry]
|
||||||
|
Icon=application-x-executable
|
||||||
|
Type=Service
|
||||||
|
ServiceTypes=KPluginInfo
|
||||||
|
Name=Stevia FAT32 VBR Structure
|
||||||
|
X-KDE-PluginInfo-Author=Elaina Claus
|
||||||
|
X-KDE-PluginInfo-Name=vbr32
|
||||||
|
X-KDE-PluginInfo-Version=1.0
|
||||||
|
X-KDE-PluginInfo-Website=https://chtm.me
|
||||||
|
X-KDE-PluginInfo-Category=structure
|
||||||
|
X-KDE-PluginInfo-License=MIT
|
||||||
|
X-KDE-PluginInfo-EnabledByDefault=false
|
||||||
@@ -1,22 +1,17 @@
|
|||||||
; Copyright (c) 2024 Elaina Claus
|
; Copyright (C) 2025 Elaina Claus
|
||||||
;
|
;
|
||||||
; Permission is hereby granted, free of charge, to any person obtaining a copy
|
; This program is free software: you can redistribute it and/or modify
|
||||||
; of this software and associated documentation files (the "Software"), to deal
|
; it under the terms of the GNU General Public License as published by
|
||||||
; in the Software without restriction, including without limitation the rights
|
; the Free Software Foundation, either version 3 of the License, or
|
||||||
; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
; (at your option) any later version.
|
||||||
; copies of the Software, and to permit persons to whom the Software is
|
|
||||||
; furnished to do so, subject to the following conditions:
|
|
||||||
;
|
;
|
||||||
; The above copyright notice and this permission notice shall be included in all
|
; This program is distributed in the hope that it will be useful,
|
||||||
; copies or substantial portions of the Software.
|
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
; GNU General Public License for more details.
|
||||||
;
|
;
|
||||||
; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
; You should have received a copy of the GNU General Public License
|
||||||
; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
; along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
; SOFTWARE.
|
|
||||||
|
|
||||||
%include 'BIOS/func/a20enable.nasm'
|
%include 'BIOS/func/a20enable.nasm'
|
||||||
%include 'BIOS/func/E820_memory_map.nasm'
|
%include 'BIOS/func/E820_memory_map.nasm'
|
||||||
|
|||||||
@@ -1,22 +1,17 @@
|
|||||||
; Copyright (c) 2024 Elaina Claus
|
; Copyright (C) 2025 Elaina Claus
|
||||||
;
|
;
|
||||||
; Permission is hereby granted, free of charge, to any person obtaining a copy
|
; This program is free software: you can redistribute it and/or modify
|
||||||
; of this software and associated documentation files (the "Software"), to deal
|
; it under the terms of the GNU General Public License as published by
|
||||||
; in the Software without restriction, including without limitation the rights
|
; the Free Software Foundation, either version 3 of the License, or
|
||||||
; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
; (at your option) any later version.
|
||||||
; copies of the Software, and to permit persons to whom the Software is
|
|
||||||
; furnished to do so, subject to the following conditions:
|
|
||||||
;
|
;
|
||||||
; The above copyright notice and this permission notice shall be included in all
|
; This program is distributed in the hope that it will be useful,
|
||||||
; copies or substantial portions of the Software.
|
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
; GNU General Public License for more details.
|
||||||
;
|
;
|
||||||
; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
; You should have received a copy of the GNU General Public License
|
||||||
; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
; along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
; SOFTWARE.
|
|
||||||
|
|
||||||
%ifndef __INC_E820MEMORY_MAP
|
%ifndef __INC_E820MEMORY_MAP
|
||||||
|
|
||||||
@@ -38,30 +33,27 @@ struc AddressRangeDescStruct_t
|
|||||||
.ExtType resd 1
|
.ExtType resd 1
|
||||||
endstruc
|
endstruc
|
||||||
|
|
||||||
|
; !!! this procedure changes ES !!!
|
||||||
ALIGN 4, db 0x90
|
ALIGN 4, db 0x90
|
||||||
GetMemoryMap:
|
GetMemoryMap:
|
||||||
__CDECL16_ENTRY
|
__CDECL16_PROC_ENTRY
|
||||||
push es ; save segment register
|
push es ; save segment register
|
||||||
.func:
|
.func:
|
||||||
mov dword [SteviaInfo + SteviaInfoStruct_t.MemoryMapEntries], 0
|
mov word [SteviaInfo + SteviaInfoStruct_t.u16_E820MMapEntryCount], 0
|
||||||
|
|
||||||
mov eax, 0xE820 ; select 0xE820 function
|
|
||||||
xor ebx, ebx ; Continuation value, 0 for the first call
|
xor ebx, ebx ; Continuation value, 0 for the first call
|
||||||
|
mov di, BIOSMemoryMap ; destination is es:di, es should == ds
|
||||||
lea dx, [BIOSMemoryMap]
|
mov ecx, AddressRangeDescStruct_t_size ; hard request ACPI 3.0 table versions (24 bytes)
|
||||||
shr dx, 4
|
|
||||||
mov es, dx
|
|
||||||
xor di, di ; (BIOSMemoryMap >> 4):0 makes di an index into BIOSMemoryMap
|
|
||||||
|
|
||||||
mov ecx, AddressRangeDescStruct_t_size
|
|
||||||
mov edx, 0x534D4150 ; 'SMAP' magic
|
|
||||||
.loop_L1:
|
.loop_L1:
|
||||||
int 0x15
|
mov eax, 0x0000E820 ; select 0xE820 function
|
||||||
|
mov edx, 0x534D4150 ; 'SMAP' magic
|
||||||
|
clc ; clear carry
|
||||||
|
int 0x15 ; data will be stored at es:di by e820 call
|
||||||
jc GetMemoryMap.error
|
jc GetMemoryMap.error
|
||||||
cmp eax, 0x534D4150
|
cmp eax, 0x534D4150
|
||||||
jne GetMemoryMap.no_smap_returned
|
jne GetMemoryMap.no_smap_returned
|
||||||
.no_error:
|
.no_error:
|
||||||
inc dword [SteviaInfo + SteviaInfoStruct_t.MemoryMapEntries]
|
inc word [SteviaInfo + SteviaInfoStruct_t.u16_E820MMapEntryCount]
|
||||||
|
|
||||||
cmp ecx, 20 ; TODO: maybe this could be handled better than just panicing
|
cmp ecx, 20 ; TODO: maybe this could be handled better than just panicing
|
||||||
jb GetMemoryMap.nonstandard_e820 ; non-standard entry found
|
jb GetMemoryMap.nonstandard_e820 ; non-standard entry found
|
||||||
@@ -69,9 +61,11 @@ GetMemoryMap:
|
|||||||
cmp ebx, 0
|
cmp ebx, 0
|
||||||
je GetMemoryMap.endp ; 0 in ebx means we have reached the end of memory ranges
|
je GetMemoryMap.endp ; 0 in ebx means we have reached the end of memory ranges
|
||||||
|
|
||||||
add di, AddressRangeDescStruct_t_size ; increment di to next descriptor
|
; setup for next loop, ebx is our next index and has already been set.
|
||||||
mov edx, eax ; 'SMAP' to edx
|
xor ecx, ecx
|
||||||
mov eax, 0xE820 ; select E820 function
|
mov ecx, AddressRangeDescStruct_t_size ; set ecx (requested_size) to 24 bytes
|
||||||
|
add di, cx ; increment di to next descriptor so es:di points to the next free space
|
||||||
|
|
||||||
jmp GetMemoryMap.loop_L1
|
jmp GetMemoryMap.loop_L1
|
||||||
.error:
|
.error:
|
||||||
ERROR STAGE2_MM_E820_MISC_ERR
|
ERROR STAGE2_MM_E820_MISC_ERR
|
||||||
@@ -81,8 +75,40 @@ GetMemoryMap:
|
|||||||
ERROR STAGE2_MM_E820_NO_SMAP
|
ERROR STAGE2_MM_E820_NO_SMAP
|
||||||
.endp:
|
.endp:
|
||||||
pop es
|
pop es
|
||||||
__CDECL16_EXIT
|
__CDECL16_PROC_EXIT
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
PrintMemoryMap:
|
||||||
|
__CDECL16_PROC_ENTRY
|
||||||
|
.func:
|
||||||
|
mov eax, dword [SteviaInfo + SteviaInfoStruct_t.u16_E820MMapEntryCount]
|
||||||
|
cmp eax, 0
|
||||||
|
je PrintMemoryMap.endp ; if entries == 0, exit
|
||||||
|
|
||||||
|
mov ecx, eax ; store # of entries in counter
|
||||||
|
mov eax, BIOSMemoryMap ; address to start of e820 mmap
|
||||||
|
|
||||||
|
push dword ecx
|
||||||
|
push dword eax
|
||||||
|
call FormatMemoryMapEntry
|
||||||
|
add sp, 0x8
|
||||||
|
|
||||||
|
; ax contains segment offset to string after call
|
||||||
|
; TODO: going to need an allocator for strings and stuff...
|
||||||
|
; print_string strformat_buffer
|
||||||
|
|
||||||
|
.endp:
|
||||||
|
__CDECL16_PROC_EXIT
|
||||||
|
ret
|
||||||
|
|
||||||
|
FormatMemoryMapEntry:
|
||||||
|
__CDECL16_PROC_ENTRY
|
||||||
|
.func:
|
||||||
|
; create a string buffer somewhere and return address to result string in ax
|
||||||
|
.endp:
|
||||||
|
__CDECL16_PROC_EXIT
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
%endif
|
%endif
|
||||||
%define __INC_E820MEMORY_MAP
|
%define __INC_E820MEMORY_MAP
|
||||||
@@ -1,22 +1,17 @@
|
|||||||
; Copyright (c) 2024 Elaina Claus
|
; Copyright (C) 2025 Elaina Claus
|
||||||
;
|
;
|
||||||
; Permission is hereby granted, free of charge, to any person obtaining a copy
|
; This program is free software: you can redistribute it and/or modify
|
||||||
; of this software and associated documentation files (the "Software"), to deal
|
; it under the terms of the GNU General Public License as published by
|
||||||
; in the Software without restriction, including without limitation the rights
|
; the Free Software Foundation, either version 3 of the License, or
|
||||||
; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
; (at your option) any later version.
|
||||||
; copies of the Software, and to permit persons to whom the Software is
|
|
||||||
; furnished to do so, subject to the following conditions:
|
|
||||||
;
|
;
|
||||||
; The above copyright notice and this permission notice shall be included in all
|
; This program is distributed in the hope that it will be useful,
|
||||||
; copies or substantial portions of the Software.
|
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
; GNU General Public License for more details.
|
||||||
;
|
;
|
||||||
; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
; You should have received a copy of the GNU General Public License
|
||||||
; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
; along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
; SOFTWARE.
|
|
||||||
|
|
||||||
%ifndef __INC_A20ENABLE
|
%ifndef __INC_A20ENABLE
|
||||||
;
|
;
|
||||||
@@ -69,7 +64,7 @@
|
|||||||
; Bits 6-7 - 00: HDD activity LED off; any other value is "on"
|
; Bits 6-7 - 00: HDD activity LED off; any other value is "on"
|
||||||
ALIGN 4, db 0x90
|
ALIGN 4, db 0x90
|
||||||
EnableA20:
|
EnableA20:
|
||||||
__CDECL16_ENTRY
|
__CDECL16_PROC_ENTRY
|
||||||
push ds
|
push ds
|
||||||
push es
|
push es
|
||||||
.a20_check:
|
.a20_check:
|
||||||
@@ -110,6 +105,7 @@ EnableA20:
|
|||||||
je EnableA20.endp ; A20 is already enabled
|
je EnableA20.endp ; A20 is already enabled
|
||||||
|
|
||||||
mov ax, 0x2403
|
mov ax, 0x2403
|
||||||
|
clc ; clear carry
|
||||||
int 0x15
|
int 0x15
|
||||||
jc EnableA20.do_fallback_a20 ; carry = error...not supported?
|
jc EnableA20.do_fallback_a20 ; carry = error...not supported?
|
||||||
cmp ah, 0
|
cmp ah, 0
|
||||||
@@ -126,6 +122,7 @@ EnableA20:
|
|||||||
ERROR STAGE2_A20_FAILED
|
ERROR STAGE2_A20_FAILED
|
||||||
.do_bios_a20:
|
.do_bios_a20:
|
||||||
mov ax, 0x2401
|
mov ax, 0x2401
|
||||||
|
clc ; clear carry
|
||||||
int 0x15
|
int 0x15
|
||||||
jmp EnableA20.a20_check
|
jmp EnableA20.a20_check
|
||||||
.do_fast_a20:
|
.do_fast_a20:
|
||||||
@@ -137,7 +134,7 @@ EnableA20:
|
|||||||
.endp:
|
.endp:
|
||||||
pop es
|
pop es
|
||||||
pop ds
|
pop ds
|
||||||
__CDECL16_EXIT
|
__CDECL16_PROC_EXIT
|
||||||
ret
|
ret
|
||||||
|
|
||||||
%endif
|
%endif
|
||||||
|
|||||||
@@ -1,22 +1,17 @@
|
|||||||
; Copyright (c) 2024 Elaina Claus
|
; Copyright (C) 2025 Elaina Claus
|
||||||
;
|
;
|
||||||
; Permission is hereby granted, free of charge, to any person obtaining a copy
|
; This program is free software: you can redistribute it and/or modify
|
||||||
; of this software and associated documentation files (the "Software"), to deal
|
; it under the terms of the GNU General Public License as published by
|
||||||
; in the Software without restriction, including without limitation the rights
|
; the Free Software Foundation, either version 3 of the License, or
|
||||||
; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
; (at your option) any later version.
|
||||||
; copies of the Software, and to permit persons to whom the Software is
|
|
||||||
; furnished to do so, subject to the following conditions:
|
|
||||||
;
|
;
|
||||||
; The above copyright notice and this permission notice shall be included in all
|
; This program is distributed in the hope that it will be useful,
|
||||||
; copies or substantial portions of the Software.
|
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
; GNU General Public License for more details.
|
||||||
;
|
;
|
||||||
; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
; You should have received a copy of the GNU General Public License
|
||||||
; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
; along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
; SOFTWARE.
|
|
||||||
|
|
||||||
%ifndef __INC_EXT_READ
|
%ifndef __INC_EXT_READ
|
||||||
;Offset Size Description
|
;Offset Size Description
|
||||||
@@ -36,29 +31,6 @@ struc LBAPkt_t
|
|||||||
.lower_lba resd 1
|
.lower_lba resd 1
|
||||||
.upper_lba resd 1
|
.upper_lba resd 1
|
||||||
endstruc
|
endstruc
|
||||||
; call_read_disk_raw <word segment> <word offset> <dword lba> <word count> <word drive_num>
|
|
||||||
%macro call_read_disk_raw 5
|
|
||||||
movzx ax, %5
|
|
||||||
push ax ; drive_num
|
|
||||||
|
|
||||||
movzx ax, %4
|
|
||||||
push ax ; count
|
|
||||||
|
|
||||||
movzx dword eax, %3
|
|
||||||
push dword eax ; lba
|
|
||||||
|
|
||||||
movzx ax, %2
|
|
||||||
push ax ; offset
|
|
||||||
|
|
||||||
movzx ax, %1
|
|
||||||
push ax ; segment = 0
|
|
||||||
|
|
||||||
; uint8_t read_stage2_raw(uint16_t buf_segment, uint16_t buf_offset,
|
|
||||||
; uint32_t lba,
|
|
||||||
; uint16_t count, uint16_t drive_num)
|
|
||||||
call read_disk_raw
|
|
||||||
add sp, 0xC
|
|
||||||
%endmacro
|
|
||||||
|
|
||||||
; Wrapper for AH=0x42 INT13h (Extended Read)
|
; Wrapper for AH=0x42 INT13h (Extended Read)
|
||||||
;
|
;
|
||||||
@@ -75,21 +47,17 @@ endstruc
|
|||||||
; disk address packet's block count field set to number of blocks
|
; disk address packet's block count field set to number of blocks
|
||||||
; successfully transferred
|
; successfully transferred
|
||||||
;
|
;
|
||||||
;
|
|
||||||
; uint8_t read_stage2_raw(uint16_t buf_segment, uint16_t buf_offset,
|
; uint8_t read_stage2_raw(uint16_t buf_segment, uint16_t buf_offset,
|
||||||
; uint32_t lba,
|
; uint32_t lba,
|
||||||
; uint16_t count, uint8_t drive_num)
|
; uint16_t count, uint8_t drive_num)
|
||||||
ALIGN 4, db 0x90
|
ALIGN 4, db 0x90
|
||||||
read_disk_raw:
|
BIOS_int13h_ext_read:
|
||||||
__CDECL16_ENTRY
|
__CDECL16_PROC_ENTRY
|
||||||
.func:
|
.func:
|
||||||
mov ax, LBAPkt_t_size
|
push LBAPkt_t_size ; len
|
||||||
push ax ; len
|
push 0x00 ; val = 0
|
||||||
xor ax, ax
|
push lba_packet ; dest = lba_packet address
|
||||||
push ax ; val = 0
|
call kmemset ; kmemset(dst, val, len)
|
||||||
mov ax, lba_packet
|
|
||||||
push ax ; dest = lba_packet address
|
|
||||||
call kmemset
|
|
||||||
add sp, 0x06
|
add sp, 0x06
|
||||||
|
|
||||||
mov bx, lba_packet
|
mov bx, lba_packet
|
||||||
@@ -98,19 +66,26 @@ read_disk_raw:
|
|||||||
mov ax, [bp + 12]
|
mov ax, [bp + 12]
|
||||||
mov word [bx + LBAPkt_t.xfer_size], ax
|
mov word [bx + LBAPkt_t.xfer_size], ax
|
||||||
|
|
||||||
mov eax, [bp + 8]
|
mov eax, dword [bp + 8]
|
||||||
mov dword [bx + LBAPkt_t.lower_lba], eax
|
mov dword [bx + LBAPkt_t.lower_lba], eax
|
||||||
|
|
||||||
|
; upper_lba is zero from kmemset
|
||||||
|
; TODO: possiblly support >32bit LBA addresses in the future
|
||||||
|
; this will limit us to (4GiB * sector size) of readable lba's from the disk
|
||||||
|
|
||||||
mov ax, [bp + 6]
|
mov ax, [bp + 6]
|
||||||
mov word [bx + LBAPkt_t.offset], ax
|
mov word [bx + LBAPkt_t.offset], ax
|
||||||
|
|
||||||
movzx ax, byte [bp + 4]
|
mov ax, [bp + 4]
|
||||||
mov word [bx + LBAPkt_t.segment], ax
|
mov word [bx + LBAPkt_t.segment], ax
|
||||||
|
|
||||||
|
xor ax, ax
|
||||||
|
xor dx, dx
|
||||||
mov si, bx ; ds:si LBAPkt_t
|
mov si, bx ; ds:si LBAPkt_t
|
||||||
mov ah, 0x42 ; call #
|
mov ah, 0x42 ; call #
|
||||||
mov dl, byte [bp + 14] ; drive #
|
mov dl, byte [bp + 14] ; drive #
|
||||||
|
|
||||||
|
clc ; clear carry
|
||||||
int 0x13
|
int 0x13
|
||||||
jnc .endf
|
jnc .endf
|
||||||
|
|
||||||
@@ -119,10 +94,10 @@ read_disk_raw:
|
|||||||
%elifdef __STEVIA_VBR
|
%elifdef __STEVIA_VBR
|
||||||
ERROR VBR_ERROR_DISK_READ_ERR
|
ERROR VBR_ERROR_DISK_READ_ERR
|
||||||
%else
|
%else
|
||||||
ERROR STAGE2_MBR_DISK_READ_ERROR
|
ERROR STAGE2_INT13_DISK_READ_ERR
|
||||||
%endif
|
%endif
|
||||||
.endf:
|
.endf:
|
||||||
__CDECL16_EXIT
|
__CDECL16_PROC_EXIT
|
||||||
ret
|
ret
|
||||||
|
|
||||||
%endif
|
%endif
|
||||||
|
|||||||
@@ -1,22 +1,17 @@
|
|||||||
; Copyright (c) 2024 Elaina Claus
|
; Copyright (C) 2025 Elaina Claus
|
||||||
;
|
;
|
||||||
; Permission is hereby granted, free of charge, to any person obtaining a copy
|
; This program is free software: you can redistribute it and/or modify
|
||||||
; of this software and associated documentation files (the "Software"), to deal
|
; it under the terms of the GNU General Public License as published by
|
||||||
; in the Software without restriction, including without limitation the rights
|
; the Free Software Foundation, either version 3 of the License, or
|
||||||
; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
; (at your option) any later version.
|
||||||
; copies of the Software, and to permit persons to whom the Software is
|
|
||||||
; furnished to do so, subject to the following conditions:
|
|
||||||
;
|
;
|
||||||
; The above copyright notice and this permission notice shall be included in all
|
; This program is distributed in the hope that it will be useful,
|
||||||
; copies or substantial portions of the Software.
|
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
; GNU General Public License for more details.
|
||||||
;
|
;
|
||||||
; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
; You should have received a copy of the GNU General Public License
|
||||||
; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
; along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
; SOFTWARE.
|
|
||||||
|
|
||||||
%ifndef __INC_VIDEO
|
%ifndef __INC_VIDEO
|
||||||
; Sets output to 80x25 16 color text mode via BIOS call
|
; Sets output to 80x25 16 color text mode via BIOS call
|
||||||
@@ -25,25 +20,27 @@
|
|||||||
ALIGN 4, db 0x90
|
ALIGN 4, db 0x90
|
||||||
SetTextMode:
|
SetTextMode:
|
||||||
.prolog:
|
.prolog:
|
||||||
__CDECL16_ENTRY
|
__CDECL16_PROC_ENTRY
|
||||||
pushf
|
pushf
|
||||||
.func:
|
.func:
|
||||||
xor ah, ah ; Set Video mode BIOS function
|
xor ah, ah ; Set Video mode BIOS function
|
||||||
mov al, 0x02 ; 16 color 80x25 Text mode
|
mov al, 0x03 ; 16 color 80x25 Text mode
|
||||||
int 0x10 ; Call video interrupt
|
int 0x10 ; Call video interrupt
|
||||||
|
|
||||||
|
|
||||||
mov ah, 0x05 ; Select active display page BIOS function
|
mov ah, 0x05 ; Select active display page BIOS function
|
||||||
xor al, al ; page 0
|
xor al, al ; page 0
|
||||||
int 0x10 ; call video interrupt
|
int 0x10 ; call video interrupt
|
||||||
.endp:
|
.endp:
|
||||||
popf
|
popf
|
||||||
__CDECL16_EXIT
|
__CDECL16_PROC_EXIT
|
||||||
ret
|
ret
|
||||||
|
|
||||||
; disables blinking text mode cursor
|
; disables blinking text mode cursor via crtc pokes
|
||||||
|
; 0x3D4/0x3D5 for color, mono at 0x3B4/0x3B5
|
||||||
ALIGN 4, db 0x90
|
ALIGN 4, db 0x90
|
||||||
disable_cursor:
|
disable_cursor_crtc:
|
||||||
__CDECL16_ENTRY
|
__CDECL16_PROC_ENTRY
|
||||||
.func:
|
.func:
|
||||||
mov dx, 0x3D4
|
mov dx, 0x3D4
|
||||||
mov al, 0xA ; low cursor shape register
|
mov al, 0xA ; low cursor shape register
|
||||||
@@ -53,8 +50,126 @@ disable_cursor:
|
|||||||
mov al, 0x20 ; bits 6-7 unused, bit 5 disables the cursor, bits 0-4 control the cursor shape
|
mov al, 0x20 ; bits 6-7 unused, bit 5 disables the cursor, bits 0-4 control the cursor shape
|
||||||
out dx, al
|
out dx, al
|
||||||
.endp:
|
.endp:
|
||||||
__CDECL16_EXIT
|
__CDECL16_PROC_EXIT
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
; disables blinking text mode cursor via BIOS int 10h, ah = 01
|
||||||
|
ALIGN 4, db 0x90
|
||||||
|
disable_cursor_bios:
|
||||||
|
__CDECL16_PROC_ENTRY
|
||||||
|
.func:
|
||||||
|
push bx
|
||||||
|
mov ah, 03h ; read cursor pos & shape
|
||||||
|
xor bh, bh
|
||||||
|
int 10h ; CH=top scanline, CL=bottom
|
||||||
|
|
||||||
|
or ch, 20h ; set bit 5 = disable
|
||||||
|
mov ah, 01h ; set leaf 01h
|
||||||
|
int 10h
|
||||||
|
pop bx
|
||||||
|
.endp:
|
||||||
|
__CDECL16_PROC_EXIT
|
||||||
|
ret
|
||||||
|
|
||||||
|
; Prints a C-Style string (null terminated) using BIOS vga teletype call
|
||||||
|
; void PrintString(char* buf)
|
||||||
|
ALIGN 4, db 0x90
|
||||||
|
PrintString:
|
||||||
|
__CDECL16_PROC_ENTRY
|
||||||
|
mov di, [bp + 4] ; first arg is char[]
|
||||||
|
.str_len:
|
||||||
|
xor cx, cx ; ECX = 0
|
||||||
|
not cx ; ECX = -1 == 0xFFFF
|
||||||
|
xor ax, ax ; search for al = 0x0
|
||||||
|
|
||||||
|
cld
|
||||||
|
repne scasb ; deincrement cx while searching for al
|
||||||
|
|
||||||
|
not cx ; the inverse of a neg number = abs(x) - 1
|
||||||
|
dec cx ; CX contains the length of the string - nul byte at end
|
||||||
|
.print:
|
||||||
|
mov si, [bp + 4] ; source string
|
||||||
|
.print_L0:
|
||||||
|
movzx ax, byte [si]
|
||||||
|
%ifdef __STEVIA_DEV_DEBUG
|
||||||
|
out 0xe9, byte al ; bochs magic debug port
|
||||||
|
%endif
|
||||||
|
push ax
|
||||||
|
call PrintCharacter
|
||||||
|
add sp, 0x2
|
||||||
|
|
||||||
|
inc si
|
||||||
|
dec cx
|
||||||
|
|
||||||
|
jcxz PrintString.endp
|
||||||
|
jmp PrintString.print_L0 ; Fetch next character from string
|
||||||
|
.endp:
|
||||||
|
__CDECL16_PROC_EXIT
|
||||||
|
ret ; Return from procedure
|
||||||
|
|
||||||
|
; Prints a single character
|
||||||
|
; void PrintCharacter(char c);
|
||||||
|
ALIGN 4, db 0x90
|
||||||
|
PrintCharacter:
|
||||||
|
__CDECL16_PROC_ENTRY
|
||||||
|
.func:
|
||||||
|
mov al, byte [bp + 4] ; AL = character c
|
||||||
|
mov ah, 0x0E ; INT 0x10, AH=0x0E call
|
||||||
|
mov bx, 0x0007 ; BH = page no. BL =Text attribute
|
||||||
|
int 0x10 ; call video interrupt
|
||||||
|
; TODO: check for carry and clear carry before call
|
||||||
|
.endp:
|
||||||
|
__CDECL16_PROC_EXIT
|
||||||
|
ret
|
||||||
|
|
||||||
|
; TODO: fix the prolog, epilog and stack usage to confirm with cdecl16
|
||||||
|
; prints the hex representation of of val
|
||||||
|
; void PrintDWORD(uint32_t val);
|
||||||
|
ALIGN 4, db 0x90
|
||||||
|
PrintDWORD:
|
||||||
|
__CDECL16_PROC_ENTRY
|
||||||
|
.func:
|
||||||
|
mov si, IntToHex_table
|
||||||
|
mov ebx, 16 ; base-16
|
||||||
|
|
||||||
|
mov eax, dword [bp + 4] ;val
|
||||||
|
|
||||||
|
xor edx, edx
|
||||||
|
xor cx, cx
|
||||||
|
.next_digit:
|
||||||
|
div ebx ; dividend in edx:eax -> quotient in eax, remainder in edx
|
||||||
|
push dx ; save remainder
|
||||||
|
inc cx
|
||||||
|
|
||||||
|
xor dx, dx
|
||||||
|
test eax, eax
|
||||||
|
jnz PrintDWORD.next_digit
|
||||||
|
|
||||||
|
.zero_pad:
|
||||||
|
cmp cx, 0x0008
|
||||||
|
je PrintDWORD.print_stack
|
||||||
|
xor ax, ax
|
||||||
|
push ax
|
||||||
|
inc cx
|
||||||
|
jmp PrintDWORD.zero_pad
|
||||||
|
|
||||||
|
.print_stack:
|
||||||
|
pop bx
|
||||||
|
dec cx
|
||||||
|
push cx
|
||||||
|
|
||||||
|
movzx ax, byte [bx+si+0] ; bx = index into Hex lookup table
|
||||||
|
push ax
|
||||||
|
call PrintCharacter
|
||||||
|
add sp, 0x2
|
||||||
|
|
||||||
|
pop cx
|
||||||
|
|
||||||
|
jcxz PrintDWORD.endp
|
||||||
|
jmp PrintDWORD.print_stack
|
||||||
|
|
||||||
|
.endp:
|
||||||
|
__CDECL16_PROC_EXIT
|
||||||
|
ret
|
||||||
%endif
|
%endif
|
||||||
%define __INC_VIDEO
|
%define __INC_VIDEO
|
||||||
@@ -1,36 +1,35 @@
|
|||||||
; Copyright (c) 2024 Elaina Claus
|
; Copyright (C) 2025 Elaina Claus
|
||||||
;
|
;
|
||||||
; Permission is hereby granted, free of charge, to any person obtaining a copy
|
; This program is free software: you can redistribute it and/or modify
|
||||||
; of this software and associated documentation files (the "Software"), to deal
|
; it under the terms of the GNU General Public License as published by
|
||||||
; in the Software without restriction, including without limitation the rights
|
; the Free Software Foundation, either version 3 of the License, or
|
||||||
; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
; (at your option) any later version.
|
||||||
; copies of the Software, and to permit persons to whom the Software is
|
|
||||||
; furnished to do so, subject to the following conditions:
|
|
||||||
;
|
;
|
||||||
; The above copyright notice and this permission notice shall be included in all
|
; This program is distributed in the hope that it will be useful,
|
||||||
; copies or substantial portions of the Software.
|
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
; GNU General Public License for more details.
|
||||||
;
|
;
|
||||||
; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
; You should have received a copy of the GNU General Public License
|
||||||
; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
; along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
%ifnmacro __CDECL16_PROC_ENTRY
|
||||||
; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
%macro __CDECL16_PROC_ENTRY 0-1
|
||||||
; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
; SOFTWARE.
|
|
||||||
%ifnmacro __CDECL16_ENTRY
|
|
||||||
%macro __CDECL16_ENTRY 0
|
|
||||||
push bp
|
push bp
|
||||||
mov bp, sp
|
mov bp, sp
|
||||||
sub sp, 0x10
|
|
||||||
|
|
||||||
push si
|
push si
|
||||||
push di
|
push di
|
||||||
push bx
|
push bx
|
||||||
|
|
||||||
|
%if %0 = 1
|
||||||
|
sub sp, %1 ; reserve locals only when needed
|
||||||
|
%endif
|
||||||
%endmacro
|
%endmacro
|
||||||
%endif
|
%endif
|
||||||
|
|
||||||
%ifnmacro __CDECL16_EXIT
|
%ifnmacro __CDECL16_PROC_EXIT
|
||||||
%macro __CDECL16_EXIT 0
|
%macro __CDECL16_PROC_EXIT 0
|
||||||
pop bx
|
pop bx
|
||||||
pop di
|
pop di
|
||||||
pop si
|
pop si
|
||||||
@@ -40,18 +39,111 @@
|
|||||||
%endmacro
|
%endmacro
|
||||||
%endif
|
%endif
|
||||||
|
|
||||||
%ifnmacro __CDECL16_CALLER_SAVE
|
; __CDECL16_PROC_ARGS nargs
|
||||||
%macro __CDECL16_CALLER_SAVE 0
|
; Creates %$arg1 .. %$argN as [bp+4], [bp+6], ...
|
||||||
push ax
|
; for use inside of function bodies
|
||||||
push cx
|
; BUG: still needs to be tested
|
||||||
push dx
|
%ifnmacro __CDECL16_PROC_ARGS
|
||||||
|
%macro __CDECL16_PROC_ARGS 1
|
||||||
|
%push __CDECL16_PROC_ARGS
|
||||||
|
%assign %$__i 1
|
||||||
|
%rep %1
|
||||||
|
%xdefine %$arg%$__i [bp + 4 + 2*(%$__i-1)]
|
||||||
|
%assign %$__i %$__i + 1
|
||||||
|
%endrep
|
||||||
|
%pop
|
||||||
%endmacro
|
%endmacro
|
||||||
%endif
|
%endif
|
||||||
|
|
||||||
%ifnmacro __CDECL16_CALLER_RESTORE
|
; __CDECL16_CALL_ARGS a,b,c ==> push c / push b / push a
|
||||||
%macro __CDECL16_CALLER_RESTORE 0
|
; handles pushing values to the stack in the correct order
|
||||||
pop dx
|
%ifnmacro __CDECL16_CALL_ARGS
|
||||||
pop cx
|
%macro __CDECL16_CALL_ARGS 1-*
|
||||||
pop ax
|
%rep %0
|
||||||
|
%rotate -1 ; move the last argument into %1
|
||||||
|
push %1 ; push last, then next-to-last, ...
|
||||||
|
%endrep
|
||||||
|
%endmacro
|
||||||
|
%endif
|
||||||
|
|
||||||
|
; __CDECL16_CALL func, nargs ; adds sp by nargs*2 after call
|
||||||
|
; adds up word pushes to restore stack frame
|
||||||
|
; WARNING: if you push a dword it will only count 2, use __CDECL16_CALL_ARGS_SIZED
|
||||||
|
%ifnmacro __CDECL16_CALL
|
||||||
|
%macro __CDECL16_CALL 2
|
||||||
|
call %1
|
||||||
|
add sp, %2*2
|
||||||
|
%endmacro
|
||||||
|
%endif
|
||||||
|
|
||||||
|
; __CDECL16_CALL_ARGS_SIZED func, size1[, size2 ...] ; sizes in BYTES
|
||||||
|
; if you *need* to pass dword sized args in 16-bit mode, use this to properly
|
||||||
|
; count the stack frame to restore later!
|
||||||
|
; BUG: still needs to be tested
|
||||||
|
%ifnmacro __CDECL16_CALL_ARGS_SIZED
|
||||||
|
%macro __CDECL16_CALL_ARGS_SIZED 2-*
|
||||||
|
%push __CDECL16_CALL_ARGS_SIZED
|
||||||
|
call %1
|
||||||
|
%assign %$__sum 0
|
||||||
|
%assign %$__i 2
|
||||||
|
%rep %0-1
|
||||||
|
%assign %$__sum %$__sum + %[%$__i] ; sizes may be expressions
|
||||||
|
%assign %$__i %$__i + 1
|
||||||
|
%endrep
|
||||||
|
%if %$__sum & 1
|
||||||
|
%error "__CDECL16_CALL_ARGS_SIZED: total size is odd; pushes must sum to whole bytes actually pushed (usually even)."
|
||||||
|
%endif
|
||||||
|
add sp, %$__sum
|
||||||
|
%pop
|
||||||
|
%endmacro
|
||||||
|
%endif
|
||||||
|
|
||||||
|
%ifnmacro __CDECL16_CLOB
|
||||||
|
; Save registers in the order listed. Supports "flags" as a pseudo-reg.
|
||||||
|
%macro __CDECL16_CLOB 1-*
|
||||||
|
%rep %0
|
||||||
|
%ifidni %1, flags
|
||||||
|
pushf
|
||||||
|
%else
|
||||||
|
push %1
|
||||||
|
%endif
|
||||||
|
%rotate 1
|
||||||
|
%endrep
|
||||||
|
%endmacro
|
||||||
|
%endif
|
||||||
|
|
||||||
|
%ifnmacro __CDECL16_UNCLOB
|
||||||
|
; Restore in reverse order of CLOB. Supports "flags".
|
||||||
|
%macro __CDECL16_UNCLOB 1-*
|
||||||
|
%rep %0
|
||||||
|
%rotate -1
|
||||||
|
%ifidni %1, flags
|
||||||
|
popf
|
||||||
|
%else
|
||||||
|
pop %1
|
||||||
|
%endif
|
||||||
|
%endrep
|
||||||
|
%endmacro
|
||||||
|
%endif
|
||||||
|
|
||||||
|
;
|
||||||
|
; Only setup the minimum stack frame
|
||||||
|
; unlike the above, everything is caller save
|
||||||
|
;
|
||||||
|
%ifnmacro __FASTCALL16_ENTRY
|
||||||
|
%macro __FASTCALL16_ENTRY 0-1
|
||||||
|
push bp
|
||||||
|
mov bp, sp
|
||||||
|
%if %0 = 1
|
||||||
|
sub sp, %1 ; reserve locals only when needed
|
||||||
|
%endif
|
||||||
|
%endmacro
|
||||||
|
%endif
|
||||||
|
|
||||||
|
; restore minimum stack frame, all regs are caller save
|
||||||
|
%ifnmacro __FASTCALL16_EXIT
|
||||||
|
%macro __FASTCALL16_EXIT 0
|
||||||
|
mov sp, bp
|
||||||
|
pop bp
|
||||||
%endmacro
|
%endmacro
|
||||||
%endif
|
%endif
|
||||||
@@ -1,26 +1,21 @@
|
|||||||
; Copyright (c) 2024 Elaina Claus
|
; Copyright (C) 2025 Elaina Claus
|
||||||
;
|
;
|
||||||
; Permission is hereby granted, free of charge, to any person obtaining a copy
|
; This program is free software: you can redistribute it and/or modify
|
||||||
; of this software and associated documentation files (the "Software"), to deal
|
; it under the terms of the GNU General Public License as published by
|
||||||
; in the Software without restriction, including without limitation the rights
|
; the Free Software Foundation, either version 3 of the License, or
|
||||||
; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
; (at your option) any later version.
|
||||||
; copies of the Software, and to permit persons to whom the Software is
|
|
||||||
; furnished to do so, subject to the following conditions:
|
|
||||||
;
|
;
|
||||||
; The above copyright notice and this permission notice shall be included in all
|
; This program is distributed in the hope that it will be useful,
|
||||||
; copies or substantial portions of the Software.
|
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
; GNU General Public License for more details.
|
||||||
;
|
;
|
||||||
; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
; You should have received a copy of the GNU General Public License
|
||||||
; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
; along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
; SOFTWARE.
|
|
||||||
|
|
||||||
%ifndef __INC_STEVIA_CONFIG
|
%ifndef __INC_STEVIA_CONFIG
|
||||||
|
|
||||||
%define SECTOR_SIZE 512
|
%define SECTOR_SIZE 0x200
|
||||||
%define STAGE2_SECTOR_COUNT 0x20
|
%define STAGE2_SECTOR_COUNT 0x20
|
||||||
; 16 KiB
|
; 16 KiB
|
||||||
%define MAX_STAGE2_BYTES (SECTOR_SIZE * STAGE2_SECTOR_COUNT)
|
%define MAX_STAGE2_BYTES (SECTOR_SIZE * STAGE2_SECTOR_COUNT)
|
||||||
|
|||||||
@@ -1,33 +0,0 @@
|
|||||||
; Copyright (c) 2024 Elaina Claus
|
|
||||||
;
|
|
||||||
; Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
; of this software and associated documentation files (the "Software"), to deal
|
|
||||||
; in the Software without restriction, including without limitation the rights
|
|
||||||
; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
; copies of the Software, and to permit persons to whom the Software is
|
|
||||||
; furnished to do so, subject to the following conditions:
|
|
||||||
;
|
|
||||||
; The above copyright notice and this permission notice shall be included in all
|
|
||||||
; copies or substantial portions of the Software.
|
|
||||||
;
|
|
||||||
; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
; SOFTWARE.
|
|
||||||
|
|
||||||
%ifndef __INC_EARLY_MEM
|
|
||||||
|
|
||||||
;PhysicalAddress = Segment * 16 + Offset
|
|
||||||
%define SEG_TO_LINEAR(s,o) ((s << 4) + o)
|
|
||||||
|
|
||||||
; Offset = physical / (Segment * 16)
|
|
||||||
%define LINEAR_TO_OFFSET(p,s) ((p / (s << 4)))
|
|
||||||
|
|
||||||
; Seg = (physical - offset) / 16
|
|
||||||
%define LINEAR_TO_SEGMENT(p,o) ((p - o) >> 4)
|
|
||||||
|
|
||||||
%endif
|
|
||||||
%define __INC_EARLY_MEM
|
|
||||||
@@ -1,26 +1,21 @@
|
|||||||
; Copyright (c) 2024 Elaina Claus
|
; Copyright (C) 2025 Elaina Claus
|
||||||
;
|
;
|
||||||
; Permission is hereby granted, free of charge, to any person obtaining a copy
|
; This program is free software: you can redistribute it and/or modify
|
||||||
; of this software and associated documentation files (the "Software"), to deal
|
; it under the terms of the GNU General Public License as published by
|
||||||
; in the Software without restriction, including without limitation the rights
|
; the Free Software Foundation, either version 3 of the License, or
|
||||||
; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
; (at your option) any later version.
|
||||||
; copies of the Software, and to permit persons to whom the Software is
|
|
||||||
; furnished to do so, subject to the following conditions:
|
|
||||||
;
|
;
|
||||||
; The above copyright notice and this permission notice shall be included in all
|
; This program is distributed in the hope that it will be useful,
|
||||||
; copies or substantial portions of the Software.
|
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
; GNU General Public License for more details.
|
||||||
;
|
;
|
||||||
; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
; You should have received a copy of the GNU General Public License
|
||||||
; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
; along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
; SOFTWARE.
|
|
||||||
|
|
||||||
%ifndef __INC_ENTRY
|
%ifndef __INC_ENTRY
|
||||||
|
|
||||||
%define MBR_ENTRY 0x8C00
|
%define MBR_ENTRY 0x6C00
|
||||||
%define VBR_ENTRY 0x7C00
|
%define VBR_ENTRY 0x7C00
|
||||||
%define STAGE2_ENTRY 0x0500
|
%define STAGE2_ENTRY 0x0500
|
||||||
|
|
||||||
|
|||||||
@@ -1,27 +1,21 @@
|
|||||||
; Copyright (c) 2024 Elaina Claus
|
; Copyright (C) 2025 Elaina Claus
|
||||||
;
|
;
|
||||||
; Permission is hereby granted, free of charge, to any person obtaining a copy
|
; This program is free software: you can redistribute it and/or modify
|
||||||
; of this software and associated documentation files (the "Software"), to deal
|
; it under the terms of the GNU General Public License as published by
|
||||||
; in the Software without restriction, including without limitation the rights
|
; the Free Software Foundation, either version 3 of the License, or
|
||||||
; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
; (at your option) any later version.
|
||||||
; copies of the Software, and to permit persons to whom the Software is
|
|
||||||
; furnished to do so, subject to the following conditions:
|
|
||||||
;
|
;
|
||||||
; The above copyright notice and this permission notice shall be included in all
|
; This program is distributed in the hope that it will be useful,
|
||||||
; copies or substantial portions of the Software.
|
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
; GNU General Public License for more details.
|
||||||
;
|
;
|
||||||
; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
; You should have received a copy of the GNU General Public License
|
||||||
; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
; along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
; SOFTWARE.
|
|
||||||
|
|
||||||
%ifndef __INC_ERROR_CODES
|
%ifndef __INC_ERROR_CODES
|
||||||
|
|
||||||
; Errors
|
; MBR Error codes
|
||||||
; 12 Errors, 5 in use
|
|
||||||
%define MBR_ERROR_DISK_T_ERR 'a'
|
%define MBR_ERROR_DISK_T_ERR 'a'
|
||||||
%define MBR_ERROR_NO_INT32E 'b'
|
%define MBR_ERROR_NO_INT32E 'b'
|
||||||
%define MBR_ERROR_NO_NO_BOOT_PART 'c'
|
%define MBR_ERROR_NO_NO_BOOT_PART 'c'
|
||||||
@@ -35,7 +29,7 @@
|
|||||||
%define MBR_ERROR_RESERVED_k 'k'
|
%define MBR_ERROR_RESERVED_k 'k'
|
||||||
%define MBR_ERROR_INT13h_EREAD_ERR 'l'
|
%define MBR_ERROR_INT13h_EREAD_ERR 'l'
|
||||||
|
|
||||||
; 12 Error
|
; VBR Error codes
|
||||||
%define VBR_ERROR_WRONG_FAT_SIZE 'm'
|
%define VBR_ERROR_WRONG_FAT_SIZE 'm'
|
||||||
%define VBR_ERROR_NO_SIGNATURE 'n'
|
%define VBR_ERROR_NO_SIGNATURE 'n'
|
||||||
%define VBR_ERROR_DISK_READ_ERR 'o'
|
%define VBR_ERROR_DISK_READ_ERR 'o'
|
||||||
@@ -49,31 +43,31 @@
|
|||||||
%define VBR_ERROR_RESERVED_w 'w'
|
%define VBR_ERROR_RESERVED_w 'w'
|
||||||
%define VBR_ERROR_RESERVED_x 'x'
|
%define VBR_ERROR_RESERVED_x 'x'
|
||||||
|
|
||||||
; 22 errors, 8 in use
|
; Stage2 Error codes
|
||||||
%define STAGE2_A20_FAILED 'A'
|
%define STAGE2_A20_FAILED 'A'
|
||||||
%define STAGE2_SIGNATURE_MISSING 'B'
|
%define STAGE2_SIGNATURE_MISSING 'B'
|
||||||
%define STAGE2_MM_E820_NO_SUPPORT 'C'
|
%define STAGE2_MM_E820_NO_SUPPORT 'C'
|
||||||
%define STAGE2_MM_E820_MISC_ERR 'D'
|
%define STAGE2_MM_E820_MISC_ERR 'D'
|
||||||
%define STAGE2_MM_E820_NONSTANDARD 'E'
|
%define STAGE2_MM_E820_NONSTANDARD 'E'
|
||||||
%define STAGE2_MM_E820_NO_SMAP 'F'
|
%define STAGE2_MM_E820_NO_SMAP 'F'
|
||||||
%define STAGE2_MBR_DISK_READ_ERROR 'G'
|
%define STAGE2_INT13_DISK_READ_ERR 'G'
|
||||||
%define STAGE2_FAT32_INIT_ERROR 'H'
|
%define STAGE2_FAT32_E_FMT 'H'
|
||||||
%define STAGE2_FAT32_NO_FILE 'I'
|
%define STAGE2_FAT32_E_RANGE 'I'
|
||||||
%define STAGE2_FAT32_END_OF_CHAIN 'J'
|
%define STAGE2_FAT32_E_NOSUCH 'J'
|
||||||
%define STAGE2_FAT32_NCLUS_CFDIVZ 'K'
|
%define STAGE2_FAT32_E_ISDIR 'K'
|
||||||
%define STAGE2_FAT32_CLS2LBA_CF 'L'
|
%define STAGE2_FAT32_E_TOOLONG 'L'
|
||||||
%define STAGE2_FAT32_INIT_CF 'M'
|
%define STAGE2_FAT32_E_UNSUPPORTED 'M'
|
||||||
%define STAGE2_ERROR_RESERVED_N 'N'
|
%define STAGE2_FAT32_E_UNIMPLEMENTED 'N'
|
||||||
%define STAGE2_ERROR_RESERVED_O 'O'
|
%define STAGE2_ERROR_BAD_MBR 'O'
|
||||||
%define STAGE2_ERROR_RESERVED_P 'P'
|
%define STAGE2_VBR_E_ACTIVE 'P'
|
||||||
%define STAGE2_ERROR_RESERVED_Q 'Q'
|
%define STAGE2_VBR_E_SIGN 'Q'
|
||||||
%define STAGE2_ERROR_RESERVED_R 'R'
|
%define STAGE2_VBR_E_TOT 'R'
|
||||||
%define STAGE2_ERROR_RESERVED_S 'S'
|
%define STAGE2_VBR_E_FATSZ 'S'
|
||||||
%define STAGE2_ERROR_RESERVED_T 'T'
|
%define STAGE2_VBR_E_DIRENT 'T'
|
||||||
%define STAGE2_ERROR_RESERVED_U 'U'
|
%define STAGE2_VBR_E_PARTTYPE 'U'
|
||||||
%define STAGE2_ERROR_RESERVED_V 'V'
|
%define STAGE2_RESERVED_E_V 'V'
|
||||||
|
|
||||||
; for development only, specific errors should be above.
|
; Debug error codes
|
||||||
%define STEVIA_DEBUG_OK 'W'
|
%define STEVIA_DEBUG_OK 'W'
|
||||||
%define STEVIA_DEBUG_ERR 'X'
|
%define STEVIA_DEBUG_ERR 'X'
|
||||||
%define STEVIA_DEBUG_UNIMPLEMENTED 'Y'
|
%define STEVIA_DEBUG_UNIMPLEMENTED 'Y'
|
||||||
|
|||||||
290
include/fat32/FAT32_SYS.nasm
Normal file
290
include/fat32/FAT32_SYS.nasm
Normal file
@@ -0,0 +1,290 @@
|
|||||||
|
; Copyright (C) 2025 Elaina Claus
|
||||||
|
;
|
||||||
|
; This program is free software: you can redistribute it and/or modify
|
||||||
|
; it under the terms of the GNU General Public License as published by
|
||||||
|
; the Free Software Foundation, either version 3 of the License, or
|
||||||
|
; (at your option) any later version.
|
||||||
|
;
|
||||||
|
; This program is distributed in the hope that it will be useful,
|
||||||
|
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
; GNU General Public License for more details.
|
||||||
|
;
|
||||||
|
; You should have received a copy of the GNU General Public License
|
||||||
|
; along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
%ifndef __INC_FAT32_SYS
|
||||||
|
|
||||||
|
%include "partition_table.inc"
|
||||||
|
%include "fat32/fat32_structures.inc"
|
||||||
|
|
||||||
|
; int read_mbr(int boot_drive, void* dst)
|
||||||
|
; destination buffer needs 512 bytes of space
|
||||||
|
FAT32_load_mbr:
|
||||||
|
__CDECL16_PROC_ENTRY
|
||||||
|
.proc:
|
||||||
|
; read mbr on boot drive to memory (for the partition table)
|
||||||
|
movzx ax, byte [bp + 4]
|
||||||
|
push ax ; drive_num (2)
|
||||||
|
push 0x01 ; count (2)
|
||||||
|
|
||||||
|
push dword 0x0 ; lba (4)
|
||||||
|
|
||||||
|
push word [bp + 6] ; offset = dst
|
||||||
|
push __STAGE2_SEGMENT ; this segment
|
||||||
|
call BIOS_int13h_ext_read
|
||||||
|
add sp, 0xC
|
||||||
|
.check_sig:
|
||||||
|
mov bx, [bp + 6]
|
||||||
|
cmp word [bx + 0x1FE], 0xAA55 ; check for bytes at end
|
||||||
|
jne .error_nosign
|
||||||
|
; TODO: this needs more error checking, zero checking, check the sig a bunch of stuff...
|
||||||
|
.endp:
|
||||||
|
__CDECL16_PROC_EXIT
|
||||||
|
ret
|
||||||
|
.error_nosign:
|
||||||
|
ERROR STAGE2_ERROR_BAD_MBR
|
||||||
|
|
||||||
|
; int read_vbr(int boot_drive, void* buf)
|
||||||
|
; read vbr on boot partition to memory (for fat bpb/ebpb)
|
||||||
|
; TODO: seperate validation and loading the sector, just check the 0xAA55 at the end here...
|
||||||
|
FAT32_load_vbr:
|
||||||
|
__CDECL16_PROC_ENTRY
|
||||||
|
.proc:
|
||||||
|
mov bx, SteviaInfo
|
||||||
|
mov ax, word [bx + SteviaInfoStruct_t.p16_MbrPtr]
|
||||||
|
add ax, DISK_PARTITION_TABLE_OFFSET
|
||||||
|
mov bx, ax ; offset to part table
|
||||||
|
mov cx, 4 ; only checking 4 entries
|
||||||
|
|
||||||
|
.find_active_L0:
|
||||||
|
mov al, [bx + PartEntry_t.attributes]
|
||||||
|
cmp al, 0x80 ; 0x80 == 1000_0000b
|
||||||
|
je .check_fstype
|
||||||
|
add bx, PartEntry_t_size ; next part entry's attributes
|
||||||
|
loop .find_active_L0
|
||||||
|
jmp .error_noactive
|
||||||
|
.check_fstype:
|
||||||
|
; check for part_type = 0x0C (DOS 7.1+/W95 FAT32 w/ LBA) or 0x1C (Hidden 0x0C)
|
||||||
|
__BOCHS_MAGIC_DEBUG
|
||||||
|
mov al, [bx + PartEntry_t.part_type]
|
||||||
|
cmp al, 0x0C
|
||||||
|
je .active_ok
|
||||||
|
; *or*
|
||||||
|
cmp al, 0x1C
|
||||||
|
je .active_ok
|
||||||
|
|
||||||
|
jmp .error_badparttype ; error if part_type != 0x1C or 0x0C
|
||||||
|
.active_ok:
|
||||||
|
movzx ax, byte [bp + 4]
|
||||||
|
push ax ; drive_num (2)
|
||||||
|
push 0x01 ; count (2)
|
||||||
|
|
||||||
|
mov eax, dword [bx + PartEntry_t.lba_start]
|
||||||
|
push dword eax ; lba (4)
|
||||||
|
|
||||||
|
push word [bp + 6] ; offset = dst
|
||||||
|
push __STAGE2_SEGMENT ; this segment
|
||||||
|
call BIOS_int13h_ext_read
|
||||||
|
add sp, 0xC
|
||||||
|
; vbr (with fat bpb/ebpb) is at the buffer now
|
||||||
|
.check_sig:
|
||||||
|
mov bx, [bp + 6]
|
||||||
|
cmp word [bx + 0x1FE], 0xAA55 ; check for bytes at end
|
||||||
|
jne .error_nosign
|
||||||
|
.check_FAT_sanity:
|
||||||
|
; we only quickly validate that this is *probably* a FAT32 volume
|
||||||
|
|
||||||
|
add bx, 11 ; point bx at start of bpb (skip jmp code and ident)
|
||||||
|
cmp word [bx + FAT32_bpb_t.u16_TotalSectors16], 0 ; TotalSectors16 should be 0 (use TotalSectors32 in bpb)
|
||||||
|
jne .error_totsectors
|
||||||
|
|
||||||
|
cmp word [bx + FAT32_bpb_t.u16_FATSize16], 0 ; FatSize16 will be 0 if FAT32 (use FATSize32 in ebpb)
|
||||||
|
jne .error_fatsz
|
||||||
|
|
||||||
|
cmp word [bx + FAT32_bpb_t.u16_RootEntryCount16], 0 ; root dir info is in data clusters on fat32
|
||||||
|
jne .error_rootdir
|
||||||
|
.endp:
|
||||||
|
__CDECL16_PROC_EXIT
|
||||||
|
ret
|
||||||
|
.error_noactive:
|
||||||
|
ERROR STAGE2_VBR_E_ACTIVE
|
||||||
|
.error_nosign:
|
||||||
|
ERROR STAGE2_VBR_E_SIGN
|
||||||
|
.error_totsectors:
|
||||||
|
ERROR STAGE2_VBR_E_TOT
|
||||||
|
.error_fatsz:
|
||||||
|
ERROR STAGE2_VBR_E_FATSZ
|
||||||
|
.error_rootdir:
|
||||||
|
ERROR STAGE2_VBR_E_DIRENT
|
||||||
|
.error_badparttype:
|
||||||
|
ERROR STAGE2_VBR_E_PARTTYPE
|
||||||
|
|
||||||
|
; what a 'mount' should probably do at this point...
|
||||||
|
; - read VBR at partition_lba
|
||||||
|
; - validate FAT32 signatures
|
||||||
|
; - fill fat32_bpb_t and compute derived fields
|
||||||
|
; - read FSInfo (free count/next free)
|
||||||
|
; - ???
|
||||||
|
; int fat32_mount(FAT32_State_t* state, uint32_t partition_lba);
|
||||||
|
FAT32_mountfs:
|
||||||
|
__CDECL16_PROC_ENTRY
|
||||||
|
.proc:
|
||||||
|
; mount: parse BPB, derive fat0_lba, data_lba, cluster0_lba.
|
||||||
|
|
||||||
|
.endp:
|
||||||
|
__CDECL16_PROC_EXIT
|
||||||
|
ret
|
||||||
|
.error:
|
||||||
|
ERROR STEVIA_DEBUG_ERR
|
||||||
|
|
||||||
|
|
||||||
|
; int fat32_read_fat(FAT32_State_t* state, uint32_t clus, uint32_t* out);
|
||||||
|
FAT32_read_fat:
|
||||||
|
__CDECL16_PROC_ENTRY
|
||||||
|
.proc:
|
||||||
|
; Read 32-bit FAT entry for cluster n
|
||||||
|
.endp:
|
||||||
|
__CDECL16_PROC_EXIT
|
||||||
|
ret
|
||||||
|
.error:
|
||||||
|
ERROR STEVIA_DEBUG_ERR
|
||||||
|
|
||||||
|
; FAT32 entry is 32-bits; only low 28 bits are meaningful.
|
||||||
|
; EOC if (val & 0x0FFFFFFF) >= 0x0FFFFFF8.
|
||||||
|
; bad if == 0x0FFFFFF7.
|
||||||
|
; free if == 0x00000000.
|
||||||
|
; int fat32_next_clus(FAT32_State_t* state, uint32_t clus, uint32_t* out_next);
|
||||||
|
FAT32_next_cluster:
|
||||||
|
__CDECL16_PROC_ENTRY
|
||||||
|
.proc:
|
||||||
|
; Walk to next cluster in chain (validates EOC/bad)
|
||||||
|
.endp:
|
||||||
|
__CDECL16_PROC_EXIT
|
||||||
|
ret
|
||||||
|
.error:
|
||||||
|
ERROR STEVIA_DEBUG_ERR
|
||||||
|
|
||||||
|
; e.g:
|
||||||
|
; uint64_t clus_to_lba(FAT32_State_t* state, uint32_t clus) {
|
||||||
|
; return v->data_lba + (uint64_t)(clus - 2) * v->secs_per_clus;
|
||||||
|
; }
|
||||||
|
FAT32_clus_to_lba:
|
||||||
|
__CDECL16_PROC_ENTRY
|
||||||
|
.proc:
|
||||||
|
; Convert cluster -> LBA of first sector of that cluster
|
||||||
|
.endp:
|
||||||
|
__CDECL16_PROC_EXIT
|
||||||
|
ret
|
||||||
|
.error:
|
||||||
|
ERROR STEVIA_DEBUG_ERR
|
||||||
|
|
||||||
|
; Prototyping for now...
|
||||||
|
|
||||||
|
; TODO:
|
||||||
|
; - bio_read_sectors (BIOS int13h LBA or CHS) + tiny sector cache.
|
||||||
|
; - mount: parse BPB, derive fat0_lba, data_lba, cluster0_lba.
|
||||||
|
; - FAT read: fat32_read_fat, fat32_next_clus.
|
||||||
|
; - dir iterator (SFN only) + path lookup.
|
||||||
|
; - file reader (fopen/fread) with cluster crossing.
|
||||||
|
; - contiguity probe for speed (optional).
|
||||||
|
; - (later) LFN support & code page handling.
|
||||||
|
|
||||||
|
|
||||||
|
; keep count <= 127
|
||||||
|
; int bio_read_sectors(uint64_t lba, uint16_t count, void* dst);
|
||||||
|
; will also need a bio_bios_int13h() (refactor ext_disk_read?)
|
||||||
|
; to abstract the backend 'sector getter'
|
||||||
|
|
||||||
|
; Error codes
|
||||||
|
|
||||||
|
; FS_OK 0
|
||||||
|
; FS_E_IO 1 (bio read failed)
|
||||||
|
; FS_E_FMT 2 (not FAT32 or bad BPB)
|
||||||
|
; FS_E_RANGE 3 (bad cluster or out of range)
|
||||||
|
; FS_E_END 4 (iterator end)
|
||||||
|
; FS_E_NOSUCH 5 (file/dir not found)
|
||||||
|
; FS_E_ISDIR 6 (opened dir as file)
|
||||||
|
; FS_E_TOOLONG 7 (path segment too long for 8.3)
|
||||||
|
; FS_E_UNSUPPORTED 8 (LFN present but disabled)
|
||||||
|
; FS_E_UNIMPLEMENTED 0xffff (procedure call unimplmented)
|
||||||
|
|
||||||
|
;
|
||||||
|
; Cache methods
|
||||||
|
;
|
||||||
|
; TODO: make a cache for ~4-8 disk sectors
|
||||||
|
; TODO: make a cache for FATs to avoid having to re-read the FAT
|
||||||
|
;
|
||||||
|
; // uses bio_read_sectors + cache
|
||||||
|
; int cache_read_sector(uint64_t lba, void* dst);
|
||||||
|
; int cache_invalidate_all(void);
|
||||||
|
|
||||||
|
;
|
||||||
|
; SFN directories
|
||||||
|
;
|
||||||
|
|
||||||
|
; typedef struct {
|
||||||
|
; char name83[12]; // "FILENAMEEXT" (no dot), NUL-terminated
|
||||||
|
; uint8_t attr; // ATTR_DIRECTORY=0x10, ATTR_VOLUME=0x08
|
||||||
|
; uint32_t first_clus; // (hi<<16)|lo
|
||||||
|
; uint32_t size; // bytes
|
||||||
|
; } fat32_dirent_sfn_t;
|
||||||
|
|
||||||
|
; typedef struct { // iterator
|
||||||
|
; fat32_bpb_t* v;
|
||||||
|
; uint32_t cur_clus;
|
||||||
|
; uint32_t offs_in_clus; // byte offset
|
||||||
|
; } fat32_dir_iter_t;
|
||||||
|
|
||||||
|
;int fat32_dir_iter_open_root(fat32_bpb_t* v, fat32_dir_iter_t* it);
|
||||||
|
;int fat32_dir_iter_open(fat32_bpb_t* v, uint32_t first_clus, fat32_dir_iter_t* it);
|
||||||
|
;int fat32_dir_iter_next(fat32_dir_iter_t* it, fat32_dirent_sfn_t* out); // FS_OK or FS_E_END
|
||||||
|
|
||||||
|
; typedef struct {
|
||||||
|
; uint32_t first_clus;
|
||||||
|
; uint32_t size;
|
||||||
|
; uint8_t attr; // dir or file
|
||||||
|
; } fat32_node_t;
|
||||||
|
|
||||||
|
; split by / or \.
|
||||||
|
; start at root (v->root_clus).
|
||||||
|
; for each component:
|
||||||
|
; iterate directory with dir_iter_* to find case-insensitive 8.3 match (fold to upper and space-pad during compare).
|
||||||
|
; if final component: return file’s cluster & size.
|
||||||
|
; if intermediate: ensure ATTR_DIRECTORY and descend.
|
||||||
|
;
|
||||||
|
; int fat32_path_lookup(fat32_bpb_t* v, const char* path, fat32_node_t* out);
|
||||||
|
|
||||||
|
; an example 'do the thing' proc to load a file to a location
|
||||||
|
;
|
||||||
|
; // loads file at path into dst, up to max_bytes; returns size read.
|
||||||
|
; int fat32_load_file(fat32_bpb_t* v, const char* path, void* dst,
|
||||||
|
; uint32_t max_bytes, uint32_t* out_size);
|
||||||
|
|
||||||
|
; streamed reads
|
||||||
|
;
|
||||||
|
; typedef struct {
|
||||||
|
; fat32_bpb_t* v;
|
||||||
|
; uint32_t first_clus;
|
||||||
|
; uint32_t cur_clus;
|
||||||
|
; uint32_t cur_clus_index; // which cluster within file we’re on
|
||||||
|
; uint32_t size; // total bytes
|
||||||
|
; uint32_t pos; // current byte position
|
||||||
|
; } fat32_file_t;
|
||||||
|
;
|
||||||
|
;
|
||||||
|
; int fat32_fopen(fat32_bpb_t* v, const char* path, fat32_file_t* f);
|
||||||
|
; int fat32_fread(fat32_file_t* f, void* dst, uint32_t nbytes, uint32_t* out_read);
|
||||||
|
; int fat32_fseek(fat32_file_t* f, uint32_t new_pos); // forward seeks only is fine
|
||||||
|
; int fat32_fclose(fat32_file_t* f);
|
||||||
|
|
||||||
|
|
||||||
|
; an example 'do the thing' proc to load a file to a location
|
||||||
|
;
|
||||||
|
; // loads file at path into dst, up to max_bytes; returns size read.
|
||||||
|
; int fat32_load_file(fat32_bpb_t* v, const char* path, void* dst,
|
||||||
|
; uint32_t max_bytes, uint32_t* out_size);
|
||||||
|
|
||||||
|
|
||||||
|
%endif
|
||||||
|
%define __INC_FAT32_SYS
|
||||||
@@ -1,22 +1,17 @@
|
|||||||
; Copyright (c) 2023 Elaina Claus
|
; Copyright (C) 2025 Elaina Claus
|
||||||
;
|
;
|
||||||
; Permission is hereby granted, free of charge, to any person obtaining a copy
|
; This program is free software: you can redistribute it and/or modify
|
||||||
; of this software and associated documentation files (the "Software"), to deal
|
; it under the terms of the GNU General Public License as published by
|
||||||
; in the Software without restriction, including without limitation the rights
|
; the Free Software Foundation, either version 3 of the License, or
|
||||||
; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
; (at your option) any later version.
|
||||||
; copies of the Software, and to permit persons to whom the Software is
|
|
||||||
; furnished to do so, subject to the following conditions:
|
|
||||||
;
|
;
|
||||||
; The above copyright notice and this permission notice shall be included in all
|
; This program is distributed in the hope that it will be useful,
|
||||||
; copies or substantial portions of the Software.
|
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
; GNU General Public License for more details.
|
||||||
;
|
;
|
||||||
; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
; You should have received a copy of the GNU General Public License
|
||||||
; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
; along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
; SOFTWARE.
|
|
||||||
|
|
||||||
%ifndef __INC_FAT32_STRUCT
|
%ifndef __INC_FAT32_STRUCT
|
||||||
|
|
||||||
@@ -63,20 +58,18 @@
|
|||||||
; resulting in a value which does not fit in the Number of Sectors entry at 0x13.
|
; resulting in a value which does not fit in the Number of Sectors entry at 0x13.
|
||||||
|
|
||||||
struc FAT32_bpb_t
|
struc FAT32_bpb_t
|
||||||
.reserved_init resb 3
|
.u16_BytesPerSector resw 1
|
||||||
.ident_8 resb 8
|
.u8_SectorsPerCluster resb 1
|
||||||
.bytes_per_sector_16 resb 2
|
.u16_ReservedSectors resw 1
|
||||||
.sectors_per_cluster_8 resb 1
|
.u8_FatCount resb 1
|
||||||
.reserved_sectors_16 resb 2
|
.u16_RootEntryCount16 resw 1 ; Root dir entry count field, 0 on fat32
|
||||||
.fat_count_8 resb 1
|
.u16_TotalSectors16 resw 1 ; total number of sectors size, 0 on fat32
|
||||||
.dir_entry_count_16 resb 2
|
.u8_MediaDesc resb 1
|
||||||
.sector_count_16 resb 2
|
.u16_FATSize16 resw 1 ; FAT size 16, 0 on fat32
|
||||||
.media_desc_8 resb 1
|
.u16_SectorsPerTrack resw 1
|
||||||
.sectors_per_fat_16 resb 2
|
.u16_HeadCount resw 1
|
||||||
.sectors_per_track_16 resb 2
|
.u32_HiddenSectors resd 1
|
||||||
.head_count_16 resb 2
|
.u32_TotalSectors32 resd 1
|
||||||
.hidden_sectors_32 resb 4
|
|
||||||
.sector_count_32 resb 4
|
|
||||||
endstruc
|
endstruc
|
||||||
|
|
||||||
; EBPB Information (FAT32)
|
; EBPB Information (FAT32)
|
||||||
@@ -96,19 +89,19 @@ endstruc
|
|||||||
; 8 System identifier string. Always "FAT32 ". The spec says never to trust the contents of this string for any use.
|
; 8 System identifier string. Always "FAT32 ". The spec says never to trust the contents of this string for any use.
|
||||||
|
|
||||||
struc FAT32_ebpb_t
|
struc FAT32_ebpb_t
|
||||||
.sectors_per_fat_32 resb 4
|
.u32_FATSize32 resd 1 ; size of *each* fat in sectors, total = FATSz * (# of FATs)
|
||||||
.fat32_flags_16 resb 2
|
.u16_ExtFlags resw 1
|
||||||
.fat32_version_16 resb 2
|
.u16_FSVersion resw 1
|
||||||
.root_dir_cluster_32 resb 4
|
.u32_RootDirCluster resd 1
|
||||||
.fsinfo_sector_16 resb 2
|
.u16_FSInfoSector resw 1
|
||||||
.backup_boot_sector_16 resb 2
|
.u16_BkBootSector resw 1
|
||||||
.reserved1 resb 12
|
.reserved0 resb 12
|
||||||
.drive_number_8 resb 1
|
.u8_DriveNumber resb 1
|
||||||
.nt_flags_8 resb 1
|
.u8_NtFlags resb 1
|
||||||
.signature_8 resb 1
|
.u8_Signature resb 1
|
||||||
.volume_serial_32 resb 4
|
.u32_VolumeId resd 1
|
||||||
.volume_label resb 11
|
.volume_label resb 11
|
||||||
.system_ident resb 8
|
.system_ident resb 8 ; Should always be 'FAT32 '
|
||||||
endstruc
|
endstruc
|
||||||
|
|
||||||
; ## Standard 8.3 structure ###
|
; ## Standard 8.3 structure ###
|
||||||
@@ -134,19 +127,43 @@ endstruc
|
|||||||
; 26 2 Low 16 bits of entry's first cluster
|
; 26 2 Low 16 bits of entry's first cluster
|
||||||
; 28 4 File size in bytes
|
; 28 4 File size in bytes
|
||||||
|
|
||||||
|
; FSInfo
|
||||||
|
; 0 0x0 4 Lead signature (must be 0x41615252 to indicate a valid FSInfo structure)
|
||||||
|
; 4 0x4 480 Reserved, these bytes should never be used
|
||||||
|
; 484 0x1E4 4 Another signature (must be 0x61417272)
|
||||||
|
; 488 0x1E8 4 Contains the last known free cluster count on the volume. 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)
|
||||||
|
;
|
||||||
|
; 492 0x1EC 4 Indicates the cluster number at which the filesystem driver should start looking for available clusters.
|
||||||
|
; If the value is 0xFFFFFFFF, then there is no hint and the driver should start searching at 2.
|
||||||
|
; Typically this value is set to the last allocated cluster number. As the previous field, this value should be range checked.
|
||||||
|
;
|
||||||
|
; 496 0x1F0 12 Reserved
|
||||||
|
; 508 0x1FC 4 Trail signature (0xAA550000)
|
||||||
|
|
||||||
|
struc FAT32_FSInfo_t
|
||||||
|
.head_sig_dword resd 1 ; 0x41615252
|
||||||
|
.reserved1 resb 480 ; fill zero
|
||||||
|
.body_sig_dword resd 1 ; 0x61417272
|
||||||
|
.free_count_dword resd 1
|
||||||
|
.next_free_dword resd 1
|
||||||
|
.reserved2 resb 12 ; fill zero
|
||||||
|
.tail_sig_dword resd 1 ; 0xAA550000
|
||||||
|
endstruc
|
||||||
|
|
||||||
struc FAT32_SFN_t
|
struc FAT32_SFN_t
|
||||||
.label resb 11
|
.label_83 resb 11
|
||||||
.attributes_8 resb 1
|
.attributes_byte resb 1
|
||||||
.nt_res_8 resb 1
|
.nt_res_byte resb 1
|
||||||
.csec_8 resb 1
|
.csec_byte resb 1
|
||||||
.ctime_16 resb 2
|
.ctime_word resb 2
|
||||||
.cdate_16 resb 2
|
.cdate_word resb 2
|
||||||
.adate_16 resb 2
|
.adate_word resb 2
|
||||||
.cluster_16_high resb 2
|
.cluster_16_high resb 2
|
||||||
.mtime_16 resb 2
|
.mtime_word resb 2
|
||||||
.mdate_16 resb 2
|
.mdate_word resb 2
|
||||||
.cluster_16_low resb 2
|
.cluster_16_low resb 2
|
||||||
.size_32 resb 4
|
.size_dword resb 4
|
||||||
endstruc
|
endstruc
|
||||||
|
|
||||||
; ## Long file name (LFN) structure format ##
|
; ## Long file name (LFN) structure format ##
|
||||||
@@ -176,49 +193,13 @@ struc FAT32_LFN_t
|
|||||||
.lfn_last2 resb 4
|
.lfn_last2 resb 4
|
||||||
endstruc
|
endstruc
|
||||||
|
|
||||||
; FSInfo
|
|
||||||
; 0 0x0 4 Lead signature (must be 0x41615252 to indicate a valid FSInfo structure)
|
|
||||||
; 4 0x4 480 Reserved, these bytes should never be used
|
|
||||||
; 484 0x1E4 4 Another signature (must be 0x61417272)
|
|
||||||
; 488 0x1E8 4 Contains the last known free cluster count on the volume. 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)
|
|
||||||
;
|
|
||||||
; 492 0x1EC 4 Indicates the cluster number at which the filesystem driver should start looking for available clusters.
|
|
||||||
; If the value is 0xFFFFFFFF, then there is no hint and the driver should start searching at 2.
|
|
||||||
; Typically this value is set to the last allocated cluster number. As the previous field, this value should be range checked.
|
|
||||||
;
|
|
||||||
; 496 0x1F0 12 Reserved
|
|
||||||
; 508 0x1FC 4 Trail signature (0xAA550000)
|
|
||||||
|
|
||||||
struc FAT32_FSInfo_t
|
|
||||||
.head_signature_32 resd 1
|
|
||||||
.reserved1 resb 480
|
|
||||||
.body_signature_32 resd 1
|
|
||||||
.free_cluster_count_32 resd 1
|
|
||||||
.first_avail_cluster_32 resd 1
|
|
||||||
.reserved2 resd 3
|
|
||||||
.tail_signature_32 resd 1
|
|
||||||
endstruc
|
|
||||||
|
|
||||||
|
|
||||||
; 32 bytes
|
; 32 bytes
|
||||||
struc FAT32_State_t
|
struc FAT32_State_t
|
||||||
.first_root_dir_sector_32 resd 1
|
.u32_TotalClusters resd 1
|
||||||
.first_data_sector_32 resd 1
|
.u32_DataAreaStartSector resd 1
|
||||||
.first_fat_sector_32 resd 1
|
.u32_FATAreaStartSector resd 1
|
||||||
.fat_size_32 resd 1
|
.p16_FATBuffer resw 1
|
||||||
.active_cluster_32 resd 1
|
.p16_ClustBuffer resw 1
|
||||||
.active_FAT_cluster_32 resd 1
|
|
||||||
.active_dir_cluster_32 resd 1
|
|
||||||
.active_drive_lba_32 resd 1
|
|
||||||
endstruc
|
|
||||||
|
|
||||||
; 16 bytes
|
|
||||||
struc FAT32_NextClusterData_t
|
|
||||||
.fat_offset resd 1
|
|
||||||
.fat_sector resd 1
|
|
||||||
.entry_offset resd 1
|
|
||||||
.reserved_1 resd 1
|
|
||||||
endstruc
|
endstruc
|
||||||
|
|
||||||
; FAT32 Attributes
|
; FAT32 Attributes
|
||||||
|
|||||||
@@ -1,22 +1,17 @@
|
|||||||
; Copyright (c) 2024 Elaina Claus
|
; Copyright (C) 2025 Elaina Claus
|
||||||
;
|
;
|
||||||
; Permission is hereby granted, free of charge, to any person obtaining a copy
|
; This program is free software: you can redistribute it and/or modify
|
||||||
; of this software and associated documentation files (the "Software"), to deal
|
; it under the terms of the GNU General Public License as published by
|
||||||
; in the Software without restriction, including without limitation the rights
|
; the Free Software Foundation, either version 3 of the License, or
|
||||||
; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
; (at your option) any later version.
|
||||||
; copies of the Software, and to permit persons to whom the Software is
|
|
||||||
; furnished to do so, subject to the following conditions:
|
|
||||||
;
|
;
|
||||||
; The above copyright notice and this permission notice shall be included in all
|
; This program is distributed in the hope that it will be useful,
|
||||||
; copies or substantial portions of the Software.
|
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
; GNU General Public License for more details.
|
||||||
;
|
;
|
||||||
; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
; You should have received a copy of the GNU General Public License
|
||||||
; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
; along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
; SOFTWARE.
|
|
||||||
|
|
||||||
%ifndef __INC_FAT32_SYS
|
%ifndef __INC_FAT32_SYS
|
||||||
|
|
||||||
@@ -24,57 +19,75 @@
|
|||||||
%include "fat32/bpb_offset_bx.inc"
|
%include "fat32/bpb_offset_bx.inc"
|
||||||
%include "fat32/fat32_structures.inc"
|
%include "fat32/fat32_structures.inc"
|
||||||
|
|
||||||
|
; Clobbers: eax, edx
|
||||||
|
; returns: none
|
||||||
ALIGN 4, db 0x90
|
ALIGN 4, db 0x90
|
||||||
InitFATDriver:
|
InitFATDriver:
|
||||||
__CDECL16_ENTRY
|
__CDECL16_PROC_ENTRY
|
||||||
.func:
|
.func:
|
||||||
mov ax, FAT32_State_t_size
|
|
||||||
push ax ; length of fat32_state structure
|
__CDECL16_CALL_ARGS fat32_state, 0x0000, FAT32_State_t_size
|
||||||
xor ax, ax
|
__CDECL16_CALL kmemset, 3
|
||||||
push ax ; init fat32_state with zero
|
|
||||||
mov ax, fat32_state
|
|
||||||
push ax ; address of structure
|
|
||||||
call kmemset
|
|
||||||
sub sp, 0x6
|
|
||||||
|
|
||||||
.calc_active_part:
|
.calc_active_part:
|
||||||
mov ax, word [partition_offset]
|
mov ax, word [partition_offset]
|
||||||
|
mov di, fat32_state
|
||||||
|
|
||||||
mov dx, partition_table
|
mov dx, partition_table
|
||||||
add dx, ax ; dx points to the partition that was booted from
|
add dx, ax ; dx points to the partition that was booted from
|
||||||
mov bx, dx ; set bx, should point at our partition
|
mov bx, dx ; set bx, should point at our partition
|
||||||
|
|
||||||
mov eax, dword [bx + PartEntry_t.lba_start]
|
mov eax, dword [bx + PartEntry_t.lba_start]
|
||||||
mov dword [fat32_state + FAT32_State_t.active_drive_lba_32], eax
|
mov dword [di + FAT32_State_t.curr_drive_lba_32], eax
|
||||||
|
|
||||||
|
mov si, fat32_bpb
|
||||||
|
mov bx, fat32_ebpb
|
||||||
.calc_first_fat:
|
.calc_first_fat:
|
||||||
movzx eax, word [fat32_bpb + FAT32_bpb_t.reserved_sectors_16] ; first fat from start of partition
|
movzx eax, word [si + FAT32_bpb_t.reserved_sectors_word] ; first fat from start of partition
|
||||||
add eax, dword [fat32_state + FAT32_State_t.active_drive_lba_32] ; calculate offset from start of drive
|
add eax, dword [di + FAT32_State_t.curr_drive_lba_32] ; calculate offset from start of drive
|
||||||
|
jc InitFATDriver.error
|
||||||
|
|
||||||
mov dword [fat32_state + FAT32_State_t.first_fat_sector_32], eax
|
mov dword [di + FAT32_State_t.first_fat_sector_32], eax
|
||||||
.calc_total_fat:
|
.calc_total_fat:
|
||||||
mov ebx, dword [fat32_ebpb + FAT32_ebpb_t.sectors_per_fat_32]
|
mov edx, dword [bx + FAT32_ebpb_t.FATSz_dword]
|
||||||
movzx eax, byte [fat32_bpb + FAT32_bpb_t.fat_count_8]
|
movzx eax, byte [si + FAT32_bpb_t.fat_count_byte]
|
||||||
mul ebx ; result in EDX:EAX, CF set on > 32bit return value
|
mul edx ; result in EDX:EAX, CF set on > 32bit return value
|
||||||
jc InitFATDriver.error ; as a catch for unhandled overflow, just error if value is greater than 32bits
|
jc InitFATDriver.error ; as a catch for unhandled overflow, just error if value is greater than 32bits
|
||||||
|
|
||||||
mov dword [fat32_state + FAT32_State_t.fat_size_32], eax
|
mov dword [di + FAT32_State_t.fat_size_32], eax
|
||||||
.calc_first_data:
|
.calc_first_data:
|
||||||
mov edx, dword [fat32_state + FAT32_State_t.first_fat_sector_32]
|
mov edx, dword [di + FAT32_State_t.first_fat_sector_32]
|
||||||
add eax, edx
|
add eax, edx
|
||||||
|
jc InitFATDriver.error
|
||||||
|
|
||||||
mov dword [fat32_state + FAT32_State_t.first_data_sector_32], eax
|
mov dword [di + FAT32_State_t.first_data_sector_32], eax
|
||||||
.get_first_root_dir:
|
.set_first_dir:
|
||||||
mov eax, [fat32_ebpb + FAT32_ebpb_t.root_dir_cluster_32]
|
mov eax, dword [bx + FAT32_ebpb_t.root_clus_dword]
|
||||||
mov dword [fat32_state + FAT32_State_t.first_root_dir_sector_32], eax ; this only works when 1 cluster = 1 sector
|
mov dword [di + FAT32_State_t.curr_dir_cluster_32], eax
|
||||||
mov dword [fat32_state + FAT32_State_t.active_dir_cluster_32], eax
|
|
||||||
|
|
||||||
.endp:
|
.endp:
|
||||||
__CDECL16_EXIT
|
__CDECL16_PROC_EXIT
|
||||||
ret
|
ret
|
||||||
.error:
|
.error:
|
||||||
ERROR STAGE2_FAT32_INIT_CF
|
ERROR STAGE2_FAT32_INIT_CF
|
||||||
|
|
||||||
|
ALIGN 4, db 0x90
|
||||||
|
FSInfoPrinter:
|
||||||
|
__CDECL16_PROC_ENTRY
|
||||||
|
.func:
|
||||||
|
;info we want to print to validate we are loading stuff from the disk correctly
|
||||||
|
; boot_drive # (i.e 0x80)
|
||||||
|
; active/bootable partition info (lba_start, lba_length, part_type)
|
||||||
|
; BPB Info: BS_OEMName = ident_8, BPB_BytsPerSec = bytes_per_sector_16, BPB_SecPerClus = sectors_per_cluster_8
|
||||||
|
; eBPB info: FATSz_dword, volid, vol label
|
||||||
|
;
|
||||||
|
; print entire FAT32 state
|
||||||
|
;
|
||||||
|
.endp:
|
||||||
|
__CDECL16_PROC_EXIT
|
||||||
|
ret
|
||||||
|
.error:
|
||||||
|
ERROR STAGE2_ERROR_INFOPRINTER
|
||||||
|
|
||||||
; this involves using the low memory buffer for the bios call and moving the file sector by sector to high memory
|
; this involves using the low memory buffer for the bios call and moving the file sector by sector to high memory
|
||||||
;
|
;
|
||||||
; SFN is a 8.3 file name, all uppercase, and padded with spaces
|
; SFN is a 8.3 file name, all uppercase, and padded with spaces
|
||||||
@@ -86,18 +99,19 @@ InitFATDriver:
|
|||||||
; uint32_t SearchFATDIR(uint8_t* SFN);
|
; uint32_t SearchFATDIR(uint8_t* SFN);
|
||||||
ALIGN 4, db 0x90
|
ALIGN 4, db 0x90
|
||||||
SearchFATDIR:
|
SearchFATDIR:
|
||||||
__CDECL16_ENTRY
|
__CDECL16_PROC_ENTRY
|
||||||
.file_lookup:
|
.file_lookup:
|
||||||
print_string SearchFATDIR_INFO_cstr
|
__CDECL16_CALL_ARGS SearchFATDIR_info
|
||||||
|
__CDECL16_CALL PrintString, 1
|
||||||
|
|
||||||
|
mov bx, fat32_state
|
||||||
.load_first_dir:
|
.load_first_dir:
|
||||||
mov eax, dword [fat32_state + FAT32_State_t.active_dir_cluster_32]
|
|
||||||
push dword eax ; cluster
|
; uint8_t ReadFATCluster(uint16_t seg, uint16_t offset, uint32_t cluster)
|
||||||
mov ax, dir_buffer
|
push dword [bx + FAT32_State_t.curr_dir_cluster_32] ; cluster
|
||||||
push ax ; offset
|
push dir_buffer ; offset
|
||||||
xor ax, ax
|
push 0x0000 ; segment
|
||||||
push ax ; segment
|
call ReadFATCluster
|
||||||
call ReadFATCluster ; uint8_t ReadFATCluster(uint16_t seg, uint16_t offset, uint32_t cluster)
|
|
||||||
add sp, 0x8
|
add sp, 0x8
|
||||||
|
|
||||||
mov si, dir_buffer
|
mov si, dir_buffer
|
||||||
@@ -107,9 +121,9 @@ SearchFATDIR:
|
|||||||
; if eax >= 0x0FFFFFF8 then there are no more clusters (end of chain)
|
; if eax >= 0x0FFFFFF8 then there are no more clusters (end of chain)
|
||||||
; if eax == 0x0FFFFFF7 then this is a cluster that is marked as bad
|
; if eax == 0x0FFFFFF7 then this is a cluster that is marked as bad
|
||||||
|
|
||||||
mov eax, dword [fat32_state + FAT32_State_t.active_dir_cluster_32]
|
; uint32_t NextCluster(uint32_t active_cluster);
|
||||||
push dword eax
|
push dword [bx + FAT32_State_t.curr_dir_cluster_32]
|
||||||
call NextCluster ; uint32_t NextCluster(uint32_t active_cluster);
|
call NextCluster
|
||||||
add sp, 0x4
|
add sp, 0x4
|
||||||
|
|
||||||
cmp eax, 0x0fff_fff7
|
cmp eax, 0x0fff_fff7
|
||||||
@@ -119,16 +133,14 @@ SearchFATDIR:
|
|||||||
|
|
||||||
.load_next_dir_next_OK:
|
.load_next_dir_next_OK:
|
||||||
; load 512 bytes of directory entries from data sector
|
; load 512 bytes of directory entries from data sector
|
||||||
mov eax, [fat32_state + FAT32_State_t.active_dir_cluster_32]
|
|
||||||
push dword eax ; cluster
|
|
||||||
|
|
||||||
mov ax, dir_buffer
|
; uint8_t ReadFATCluster(uint16_t seg, uint16_t offset, uint32_t cluster)
|
||||||
push ax ; offset
|
push dword [bx + FAT32_State_t.curr_dir_cluster_32] ; cluster
|
||||||
|
push dir_buffer ; offset
|
||||||
|
push 0x0000 ; segment
|
||||||
|
call ReadFATCluster
|
||||||
|
add sp, 0x8
|
||||||
|
|
||||||
xor ax, ax
|
|
||||||
push ax ; segment
|
|
||||||
call ReadFATCluster ; uint8_t ReadFATCluster(uint16_t seg, uint16_t offset, uint32_t cluster)
|
|
||||||
sub sp, 0x8
|
|
||||||
.empty_dir_entry:
|
.empty_dir_entry:
|
||||||
; check for 0x0 in first byte, if true then there are no more files
|
; check for 0x0 in first byte, if true then there are no more files
|
||||||
; if true we did not find the file, we should error here
|
; if true we did not find the file, we should error here
|
||||||
@@ -156,8 +168,11 @@ SearchFATDIR:
|
|||||||
jae SearchFATDIR.load_next_dir
|
jae SearchFATDIR.load_next_dir
|
||||||
jmp SearchFATDIR.empty_dir_entry
|
jmp SearchFATDIR.empty_dir_entry
|
||||||
|
|
||||||
|
; TODO: move this to a seperate string search function
|
||||||
.parse_dir:
|
.parse_dir:
|
||||||
print_string MaybeFound_Boot_INFO_cstr
|
__CDECL16_CALL_ARGS MaybeFound_Boot_info
|
||||||
|
__CDECL16_CALL PrintString, 1
|
||||||
|
|
||||||
.lfn_check:
|
.lfn_check:
|
||||||
; check for ATTR_READ_ONLY | ATTR_HIDDEN | ATTR_SYSTEM | ATTR_VOLUME_ID (0x0F) in offset 11
|
; check for ATTR_READ_ONLY | ATTR_HIDDEN | ATTR_SYSTEM | ATTR_VOLUME_ID (0x0F) in offset 11
|
||||||
; TODO: going to skip LFN for now, since all valid volumes will have SFN's
|
; TODO: going to skip LFN for now, since all valid volumes will have SFN's
|
||||||
@@ -169,7 +184,7 @@ SearchFATDIR:
|
|||||||
|
|
||||||
mov cx, 0xA ; max of 11 filename length of 11 characters
|
mov cx, 0xA ; max of 11 filename length of 11 characters
|
||||||
; si points to the start of the current directory entry
|
; si points to the start of the current directory entry
|
||||||
mov di, BootTarget_str ; current memory location (8.3 name is at offset 0)
|
mov di, BootTarget ; current memory location (8.3 name is at offset 0)
|
||||||
repe cmpsb ; compare the strings
|
repe cmpsb ; compare the strings
|
||||||
|
|
||||||
pop di
|
pop di
|
||||||
@@ -182,7 +197,7 @@ SearchFATDIR:
|
|||||||
mov ax, [si + FAT32_SFN_t.cluster_16_low]
|
mov ax, [si + FAT32_SFN_t.cluster_16_low]
|
||||||
; eax == first cluster of file
|
; eax == first cluster of file
|
||||||
.endp:
|
.endp:
|
||||||
__CDECL16_EXIT
|
__CDECL16_PROC_EXIT
|
||||||
ret
|
ret
|
||||||
|
|
||||||
; BUG: this function needs review
|
; BUG: this function needs review
|
||||||
@@ -191,45 +206,36 @@ SearchFATDIR:
|
|||||||
; if eax == 0x0FFFFFF7 then this is a cluster that is marked as bad
|
; if eax == 0x0FFFFFF7 then this is a cluster that is marked as bad
|
||||||
ALIGN 4, db 0x90
|
ALIGN 4, db 0x90
|
||||||
NextCluster:
|
NextCluster:
|
||||||
__CDECL16_ENTRY
|
__CDECL16_PROC_ENTRY
|
||||||
.func:
|
.func:
|
||||||
print_string NextFATCluster_INFO_cstr
|
__CDECL16_CALL_ARGS NextFATCluster_info
|
||||||
mov edx, dword [bp + 4]
|
__CDECL16_CALL PrintString, 1
|
||||||
|
|
||||||
|
__CDECL16_CALL_ARGS fat32_nc_data, 0x0000, FAT32_NextClusterData_t_size
|
||||||
|
__CDECL16_CALL kmemset, 3
|
||||||
|
|
||||||
|
mov edx, dword [bp + 4] ; active_cluster
|
||||||
mov si, fat32_nc_data ; instead of push/pop and moving the data back
|
mov si, fat32_nc_data ; instead of push/pop and moving the data back
|
||||||
mov di, fat32_bpb ; load si & di then use xchg
|
mov di, fat32_bpb ; load si & di then use xchg
|
||||||
|
mov bx, fat32_state
|
||||||
.calc_offset:
|
.calc_offset:
|
||||||
; fat_offset = active_cluster * 4
|
; fat_offset = active_cluster * 4
|
||||||
mov eax, 4
|
mov eax, 4
|
||||||
mul edx
|
mul edx
|
||||||
jc NextCluster.error_cfdivz
|
jc NextCluster.error_cfdivz
|
||||||
mov dword [si + FAT32_NextClusterData_t.fat_offset], eax ; move lower 32 bits to fat offset
|
mov dword [si + FAT32_NextClusterData_t.fat_offset], eax ; move lower 32 bits to fat offset
|
||||||
|
|
||||||
.calc_fat_sector:
|
.calc_fat_sector:
|
||||||
; fat_sector = first_fat_sector + (fat_offset / sector_size)
|
; fat_sector = first_fat_sector + (fat_offset / sector_size)
|
||||||
; entry_offset = fat_offset % sector_size
|
; entry_offset = fat_offset % sector_size
|
||||||
mov edx, 0xffff_0000
|
xor edx, edx
|
||||||
and edx, eax
|
movzx ecx, word [di + FAT32_bpb_t.bytes_per_sector_word]
|
||||||
shr edx, 16
|
cmp eax, 0
|
||||||
|
|
||||||
xchg si, di ; switch to fat32_bpb in si
|
|
||||||
mov cx, word [si + FAT32_bpb_t.bytes_per_sector_16]
|
|
||||||
xchg si, di
|
|
||||||
|
|
||||||
cmp edx, 0
|
|
||||||
je NextCluster.error_cfdivz
|
je NextCluster.error_cfdivz
|
||||||
div cx ; DX:AX / cx = fat_sector - first_fat_sector in AX
|
div ecx ; eDX:eAX / eCX = fat_sector - first_fat_sector in eAX
|
||||||
; DX = remainder (fat_offset mod sector_size)
|
; eDX = remainder (fat_offset mod sector_size)
|
||||||
|
|
||||||
mov ecx, 0x0000_ffff
|
|
||||||
and edx, ecx
|
|
||||||
mov dword [si + FAT32_NextClusterData_t.entry_offset], edx
|
mov dword [si + FAT32_NextClusterData_t.entry_offset], edx
|
||||||
|
mov ecx, dword [bx + FAT32_State_t.first_fat_sector_32]
|
||||||
xchg si, di ; switch to fat32_bpb in si
|
|
||||||
mov ecx, dword [si + FAT32_State_t.first_fat_sector_32]
|
|
||||||
xchg si, di
|
|
||||||
|
|
||||||
mov edx, 0x0000ffff
|
|
||||||
and eax, edx
|
|
||||||
add eax, ecx ; fat_sector + first_fat_sector
|
add eax, ecx ; fat_sector + first_fat_sector
|
||||||
mov dword [si + FAT32_NextClusterData_t.fat_sector], eax
|
mov dword [si + FAT32_NextClusterData_t.fat_sector], eax
|
||||||
.load_fat_table:
|
.load_fat_table:
|
||||||
@@ -259,37 +265,23 @@ NextCluster:
|
|||||||
mov ebx, dword [si + FAT32_NextClusterData_t.entry_offset]
|
mov ebx, dword [si + FAT32_NextClusterData_t.entry_offset]
|
||||||
mov si, fat_buffer
|
mov si, fat_buffer
|
||||||
mov eax, dword [bx+si+0]
|
mov eax, dword [bx+si+0]
|
||||||
|
; BUG: ???
|
||||||
.endp:
|
.endp:
|
||||||
__CDECL16_EXIT
|
__CDECL16_PROC_EXIT
|
||||||
ret
|
ret
|
||||||
.error_cfdivz:
|
.error_cfdivz:
|
||||||
ERROR STAGE2_FAT32_NCLUS_CFDIVZ
|
ERROR STAGE2_FAT32_NCLUS_CFDIVZ
|
||||||
|
|
||||||
; uint32_t ClusterToLBA(uint32_t cluster)
|
|
||||||
ALIGN 4, db 0x90
|
|
||||||
ClusterToLBA:
|
|
||||||
__CDECL16_ENTRY
|
|
||||||
.func:
|
|
||||||
mov dword eax, [bp + 4]
|
|
||||||
sub eax, 2
|
|
||||||
movzx edx, byte [fat32_bpb + FAT32_bpb_t.sectors_per_cluster_8]
|
|
||||||
mul edx
|
|
||||||
jc ClusterToLBA.error
|
|
||||||
add eax, dword [fat32_state + FAT32_State_t.first_data_sector_32]
|
|
||||||
; eax contains the LBA now
|
|
||||||
.endp:
|
|
||||||
__CDECL16_EXIT
|
|
||||||
ret
|
|
||||||
.error:
|
|
||||||
ERROR STAGE2_FAT32_CLS2LBA_CF
|
|
||||||
|
|
||||||
; bp - 2 - byte boot_drive
|
|
||||||
; uint8_t ReadFATCluster(uint16_t seg, uint16_t offset, uint32_t cluster)
|
; uint8_t ReadFATCluster(uint16_t seg, uint16_t offset, uint32_t cluster)
|
||||||
ALIGN 4, db 0x90
|
ALIGN 4, db 0x90
|
||||||
ReadFATCluster:
|
ReadFATCluster:
|
||||||
__CDECL16_ENTRY
|
__CDECL16_PROC_ENTRY
|
||||||
.func:
|
.func:
|
||||||
print_string ReadFATCluster_INFO_cstr
|
__CDECL16_CALL_ARGS ReadFATCluster_info
|
||||||
|
__CDECL16_CALL PrintString, 1
|
||||||
|
|
||||||
|
mov bx, fat32_bpb
|
||||||
|
mov si, fat32_ebpb
|
||||||
|
|
||||||
xor ax, ax
|
xor ax, ax
|
||||||
mov al, byte [boot_drive]
|
mov al, byte [boot_drive]
|
||||||
@@ -298,26 +290,31 @@ ReadFATCluster:
|
|||||||
mov ax, 0x1 ; count = 1
|
mov ax, 0x1 ; count = 1
|
||||||
push ax
|
push ax
|
||||||
|
|
||||||
mov eax, dword [bp + 8]
|
mov eax, dword [bp + 8] ; cluster
|
||||||
push dword eax
|
sub eax, 2
|
||||||
call ClusterToLBA
|
movzx edx, byte [bx + FAT32_bpb_t.sectors_per_cluster_byte]
|
||||||
add sp, 0x4
|
mul edx ; result in eax, error on carry
|
||||||
|
jc ReadFATCluster.error
|
||||||
|
add eax, dword [si + FAT32_State_t.first_data_sector_32]
|
||||||
|
jc ReadFATCluster.error
|
||||||
; eax contains the LBA now
|
; eax contains the LBA now
|
||||||
push dword eax ; lba = ClusterToLBA(..)
|
push dword eax ; lba = ClusterToLBA(..)
|
||||||
|
|
||||||
mov ax, fat_buffer ; offset = fat_buffer (in mem.inc)
|
mov ax, word [bp + 6] ; offset
|
||||||
push ax
|
push ax
|
||||||
|
|
||||||
xor ax, ax ; segment = 0x0000, our buffer is in the first 64 KiB
|
mov ax, word [bp + 4]
|
||||||
push ax
|
push ax
|
||||||
; uint8_t read_stage2_raw(uint16_t buf_segment, uint16_t buf_offset,
|
; uint8_t read_disk_raw(uint16_t buf_segment, uint16_t buf_offset,
|
||||||
; uint32_t lba,
|
; uint32_t lba,
|
||||||
; uint16_t count, uint16_t drive_num)
|
; uint16_t count, uint16_t drive_num)
|
||||||
call read_disk_raw
|
call read_disk_raw
|
||||||
add sp, 0xC
|
add sp, 0xC
|
||||||
.endp:
|
.endp:
|
||||||
__CDECL16_EXIT
|
__CDECL16_PROC_EXIT
|
||||||
ret
|
ret
|
||||||
|
.error:
|
||||||
|
ERROR STAGE2_FAT32_CLS2LBA_CF
|
||||||
|
|
||||||
%endif
|
%endif
|
||||||
%define __INC_FAT32_SYS
|
%define __INC_FAT32_SYS
|
||||||
@@ -1,22 +1,17 @@
|
|||||||
; Copyright (c) 2024 Elaina Claus
|
; Copyright (C) 2025 Elaina Claus
|
||||||
;
|
;
|
||||||
; Permission is hereby granted, free of charge, to any person obtaining a copy
|
; This program is free software: you can redistribute it and/or modify
|
||||||
; of this software and associated documentation files (the "Software"), to deal
|
; it under the terms of the GNU General Public License as published by
|
||||||
; in the Software without restriction, including without limitation the rights
|
; the Free Software Foundation, either version 3 of the License, or
|
||||||
; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
; (at your option) any later version.
|
||||||
; copies of the Software, and to permit persons to whom the Software is
|
|
||||||
; furnished to do so, subject to the following conditions:
|
|
||||||
;
|
;
|
||||||
; The above copyright notice and this permission notice shall be included in all
|
; This program is distributed in the hope that it will be useful,
|
||||||
; copies or substantial portions of the Software.
|
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
; GNU General Public License for more details.
|
||||||
;
|
;
|
||||||
; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
; You should have received a copy of the GNU General Public License
|
||||||
; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
; along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
; SOFTWARE.
|
|
||||||
|
|
||||||
%ifndef __INC_BPD_OFFSET_BX
|
%ifndef __INC_BPD_OFFSET_BX
|
||||||
|
|
||||||
228
include/fat32/old/fat32_structures.inc
Executable file
228
include/fat32/old/fat32_structures.inc
Executable file
@@ -0,0 +1,228 @@
|
|||||||
|
; Copyright (C) 2025 Elaina Claus
|
||||||
|
;
|
||||||
|
; This program is free software: you can redistribute it and/or modify
|
||||||
|
; it under the terms of the GNU General Public License as published by
|
||||||
|
; the Free Software Foundation, either version 3 of the License, or
|
||||||
|
; (at your option) any later version.
|
||||||
|
;
|
||||||
|
; This program is distributed in the hope that it will be useful,
|
||||||
|
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
; GNU General Public License for more details.
|
||||||
|
;
|
||||||
|
; You should have received a copy of the GNU General Public License
|
||||||
|
; along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
%ifndef __INC_FAT32_STRUCT
|
||||||
|
|
||||||
|
; ## FAT32 Info ##
|
||||||
|
; total_sectors = bsSectorsHuge
|
||||||
|
; fat_size = bsSectorsPerFat
|
||||||
|
;
|
||||||
|
; first_data_sector = bsResSectors + (bsFATs * bsSectPerFAT);
|
||||||
|
; total_data_sectors = bsSectorsHuge - (bsResSectors + (bsFATs * bsSectPerFAT));
|
||||||
|
; total_clusters = total_data_sectors / bsSectsPerClust
|
||||||
|
; first_fat_sector = bsResSectors
|
||||||
|
;
|
||||||
|
; ## FAT32 Table information ##
|
||||||
|
;
|
||||||
|
; fat_offset = active_cluster * 4
|
||||||
|
; fat_sector = first_fat_sector + (fat_offset / sector_size)
|
||||||
|
; entry_offset = fat_offset % sector_size
|
||||||
|
;
|
||||||
|
; table_value = fat_table[entry_offset] & 0x0FFF_FFFF
|
||||||
|
;
|
||||||
|
; ## FAT32 Directory Entries ##
|
||||||
|
; root_dir_cluster = bsRootDirCluster
|
||||||
|
; root_dir_sectors = ? (this is varible on FAT32 since the root dir is a cluster chain)
|
||||||
|
; first_sector_of_cluster = ((cluster - 2) * bsSectPerClust) + first_data_sector;
|
||||||
|
|
||||||
|
; BPB Information
|
||||||
|
; Size Description
|
||||||
|
; 8 OEM identifier.
|
||||||
|
; 2 The number of Bytes per sector (remember, all numbers are in the little-endian format).
|
||||||
|
; 1 Number of sectors per cluster.
|
||||||
|
; 2 Number of reserved sectors. The boot record sectors are included in this value.
|
||||||
|
; 1 Number of File Allocation Tables (FAT's) on the storage media. Often this value is 2.
|
||||||
|
; 2 Number of directory entries (must be set so that the root directory occupies entire sectors).
|
||||||
|
; 2 The total sectors in the logical volume.
|
||||||
|
; If this value is 0, it means there are more than 65535 sectors in the volume,
|
||||||
|
; and the actual count is stored in the Large Sector Count entry at 0x20.
|
||||||
|
;
|
||||||
|
; 1 This Byte indicates the media descriptor type.
|
||||||
|
; 2 Number of sectors per FAT. FAT12/FAT16 only.
|
||||||
|
; 2 Number of sectors per track.
|
||||||
|
; 2 Number of heads or sides on the storage media.
|
||||||
|
; 4 Number of hidden sectors. (i.e. the LBA of the beginning of the partition.)
|
||||||
|
; 4 Large sector count. This field is set if there are more than 65535 sectors in the volume,
|
||||||
|
; resulting in a value which does not fit in the Number of Sectors entry at 0x13.
|
||||||
|
|
||||||
|
struc FAT32_bpb_t
|
||||||
|
.reserved_jmpboot resb 3
|
||||||
|
.ident resb 8
|
||||||
|
.bytes_per_sector_word resb 2
|
||||||
|
.sectors_per_cluster_byte resb 1
|
||||||
|
.reserved_sectors_word resb 2
|
||||||
|
.fat_count_byte resb 1
|
||||||
|
.unused1_ZERO_word resb 2 ; Root entry count field, 0 on fat32
|
||||||
|
.unused2_ZERO_word resb 2 ; total sectors size 16, 0 on fat32
|
||||||
|
.media_desc_byte resb 1
|
||||||
|
.unused3_ZERO_word resb 2 ; FAT size 16, 0 on fat32
|
||||||
|
.sectors_per_track_word resb 2
|
||||||
|
.head_count_word resb 2
|
||||||
|
.hidden_sectors_dword resb 4
|
||||||
|
.total_sectors_dword resb 4
|
||||||
|
endstruc
|
||||||
|
|
||||||
|
; EBPB Information (FAT32)
|
||||||
|
; Size Description
|
||||||
|
; 4 Sectors per FAT. The size of the FAT in sectors.
|
||||||
|
; 2 Flags.
|
||||||
|
; 2 FAT version number. The high byte is the major version and the low byte is the minor version. FAT drivers should respect this field.
|
||||||
|
; 4 The cluster number of the root directory. Often this field is set to 2.
|
||||||
|
; 2 The sector number of the FSInfo structure.
|
||||||
|
; 2 The sector number of the backup boot sector.
|
||||||
|
; 12 Reserved. When the volume is formated these bytes should be zero.
|
||||||
|
; 1 Drive number. The values here are identical to the values returned by the BIOS interrupt 0x13. 0x00 for a floppy disk and 0x80 for hard disks.
|
||||||
|
; 1 Flags in Windows NT. Reserved otherwise.
|
||||||
|
; 1 Signature (must be 0x28 or 0x29).
|
||||||
|
; 4 Volume ID 'Serial' number. Used for tracking volumes between computers. You can ignore this if you want.
|
||||||
|
; 11 Volume label string. This field is padded with spaces.
|
||||||
|
; 8 System identifier string. Always "FAT32 ". The spec says never to trust the contents of this string for any use.
|
||||||
|
|
||||||
|
struc FAT32_ebpb_t
|
||||||
|
.FATSz_dword resb 4
|
||||||
|
.extflags_word resb 2
|
||||||
|
.FSVersion_word resb 2
|
||||||
|
.root_clus_dword resb 4
|
||||||
|
.FSInfo_word resb 2
|
||||||
|
.BkBootSec_word resb 2
|
||||||
|
.reserved1 resb 12
|
||||||
|
.drive_number_byte resb 1
|
||||||
|
.nt_flags_byte resb 1
|
||||||
|
.signature_byte resb 1
|
||||||
|
.volume_id_dword resb 4
|
||||||
|
.volume_label_bytea resb 11
|
||||||
|
.system_ident_bytea resb 8
|
||||||
|
endstruc
|
||||||
|
|
||||||
|
; ## Standard 8.3 structure ###
|
||||||
|
; Offset Length (Bytes) Description
|
||||||
|
; 0 11 8.3 file name. The first 8 characters are the name and the last 3 are the extension.
|
||||||
|
; 11 1 File Atrributes
|
||||||
|
; READ_ONLY=0x01
|
||||||
|
; HIDDEN=0x02
|
||||||
|
; SYSTEM=0x04
|
||||||
|
; VOLUME_ID=0x08
|
||||||
|
; DIRECTORY=0x10
|
||||||
|
; ARCHIVE=0x20
|
||||||
|
; LFN=READ_ONLY|HIDDEN|SYSTEM|VOLUME_ID == 0x0F
|
||||||
|
;
|
||||||
|
; 12 1 NT Reserved
|
||||||
|
; 13 1 Creation time in tenths of a second.
|
||||||
|
; 14 2 File creation time, Hour 5 bits, Minutes 6 bits, Seconds 5 Bits, multiply seconds by 2
|
||||||
|
; 16 2 File creation date, Year 7 bits, month 4 bits, day 5 bits
|
||||||
|
; 18 2 Last Accessed date. same format at creation date
|
||||||
|
; 20 2 High 16 bits of entry's first cluster
|
||||||
|
; 22 2 Last modification time. same format at creation time
|
||||||
|
; 24 2 Last modification date. same format as creation date
|
||||||
|
; 26 2 Low 16 bits of entry's first cluster
|
||||||
|
; 28 4 File size in bytes
|
||||||
|
|
||||||
|
; FSInfo
|
||||||
|
; 0 0x0 4 Lead signature (must be 0x41615252 to indicate a valid FSInfo structure)
|
||||||
|
; 4 0x4 480 Reserved, these bytes should never be used
|
||||||
|
; 484 0x1E4 4 Another signature (must be 0x61417272)
|
||||||
|
; 488 0x1E8 4 Contains the last known free cluster count on the volume. 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)
|
||||||
|
;
|
||||||
|
; 492 0x1EC 4 Indicates the cluster number at which the filesystem driver should start looking for available clusters.
|
||||||
|
; If the value is 0xFFFFFFFF, then there is no hint and the driver should start searching at 2.
|
||||||
|
; Typically this value is set to the last allocated cluster number. As the previous field, this value should be range checked.
|
||||||
|
;
|
||||||
|
; 496 0x1F0 12 Reserved
|
||||||
|
; 508 0x1FC 4 Trail signature (0xAA550000)
|
||||||
|
|
||||||
|
struc FAT32_FSInfo_t
|
||||||
|
.head_sig_dword resd 1 ; 0x41615252
|
||||||
|
.reserved1 resb 480 ; fill zero
|
||||||
|
.body_sig_dword resd 1 ; 0x61417272
|
||||||
|
.free_count_dword resd 1
|
||||||
|
.next_free_dword resd 1
|
||||||
|
.reserved2 resb 12 ; fill zero
|
||||||
|
.tail_sig_dword resd 1 ; 0xAA550000
|
||||||
|
endstruc
|
||||||
|
|
||||||
|
struc FAT32_SFN_t
|
||||||
|
.label_83 resb 11
|
||||||
|
.attributes_byte resb 1
|
||||||
|
.nt_res_byte resb 1
|
||||||
|
.csec_byte resb 1
|
||||||
|
.ctime_word resb 2
|
||||||
|
.cdate_word resb 2
|
||||||
|
.adate_word resb 2
|
||||||
|
.cluster_16_high resb 2
|
||||||
|
.mtime_word resb 2
|
||||||
|
.mdate_word resb 2
|
||||||
|
.cluster_16_low resb 2
|
||||||
|
.size_dword resb 4
|
||||||
|
endstruc
|
||||||
|
|
||||||
|
; ## Long file name (LFN) structure format ##
|
||||||
|
;
|
||||||
|
; 0 1 The order of this entry in the sequence of long file name entries. This value helps you to know where in the file's name the characters from this entry should be placed.
|
||||||
|
; 1 10 The first 5, 2-byte characters of this entry.
|
||||||
|
; 11 1 Attribute. Always equals 0x0F. (the long file name attribute)
|
||||||
|
; 12 1 Long entry type. Zero for name entries.
|
||||||
|
; 13 1 Checksum generated of the short file name when the file was created. The short filename can change without changing the long filename in cases where the partition is mounted on a system which does not support long filenames.
|
||||||
|
; 14 12 The next 6, 2-byte characters of this entry.
|
||||||
|
; 26 2 Always zero.
|
||||||
|
; 28 4 The final 2, 2-byte characters of this entry.
|
||||||
|
;
|
||||||
|
; LFN entries are always placed immediately before their respective 8.3 entry
|
||||||
|
;
|
||||||
|
; LAST_LFN_ENTRY == 0x40
|
||||||
|
; Max of 20 in sequence == 0x14
|
||||||
|
|
||||||
|
struc FAT32_LFN_t
|
||||||
|
.order resb 1
|
||||||
|
.lfn_first5 resb 10
|
||||||
|
.attributes_8 resb 1
|
||||||
|
.zero1 resb 1
|
||||||
|
.checksum resb 1
|
||||||
|
.lfn_next6 resb 12
|
||||||
|
.zero2 resb 2
|
||||||
|
.lfn_last2 resb 4
|
||||||
|
endstruc
|
||||||
|
|
||||||
|
; 32 bytes
|
||||||
|
struc FAT32_State_t
|
||||||
|
.first_data_sector_32 resd 1
|
||||||
|
.first_fat_sector_32 resd 1
|
||||||
|
.fat_size_32 resd 1
|
||||||
|
.curr_FAT_cluster_32 resd 1
|
||||||
|
.curr_dir_cluster_32 resd 1
|
||||||
|
.curr_drive_lba_32 resd 1
|
||||||
|
endstruc
|
||||||
|
|
||||||
|
; 16 bytes
|
||||||
|
struc FAT32_NextClusterData_t
|
||||||
|
.fat_offset resd 1
|
||||||
|
.fat_sector resd 1
|
||||||
|
.entry_offset resd 1
|
||||||
|
.reserved_1 resd 1
|
||||||
|
endstruc
|
||||||
|
|
||||||
|
; FAT32 Attributes
|
||||||
|
%define FAT32_ATTR_RO 0x01
|
||||||
|
%define FAT32_ATTR_HIDDEN 0x02
|
||||||
|
%define FAT32_ATTR_SYSTEM 0x04
|
||||||
|
%define FAT32_ATTR_VOLID 0x08
|
||||||
|
%define FAT32_ATTR_DIR 0x10
|
||||||
|
%define FAT32_ATTR_ARC 0x20
|
||||||
|
|
||||||
|
; LFN == RO | HIDDEN | SYSTEM | VOLID == 0x0F
|
||||||
|
%define FAT32_ATTR_LFN 0x0F
|
||||||
|
|
||||||
|
%endif
|
||||||
|
%define __INC_FAT32_STRUCT
|
||||||
@@ -1,25 +1,23 @@
|
|||||||
; Copyright (c) 2024 Elaina Claus
|
; Copyright (C) 2025 Elaina Claus
|
||||||
;
|
;
|
||||||
; Permission is hereby granted, free of charge, to any person obtaining a copy
|
; This program is free software: you can redistribute it and/or modify
|
||||||
; of this software and associated documentation files (the "Software"), to deal
|
; it under the terms of the GNU General Public License as published by
|
||||||
; in the Software without restriction, including without limitation the rights
|
; the Free Software Foundation, either version 3 of the License, or
|
||||||
; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
; (at your option) any later version.
|
||||||
; copies of the Software, and to permit persons to whom the Software is
|
|
||||||
; furnished to do so, subject to the following conditions:
|
|
||||||
;
|
;
|
||||||
; The above copyright notice and this permission notice shall be included in all
|
; This program is distributed in the hope that it will be useful,
|
||||||
; copies or substantial portions of the Software.
|
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
; GNU General Public License for more details.
|
||||||
;
|
;
|
||||||
; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
; You should have received a copy of the GNU General Public License
|
||||||
; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
; along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
; SOFTWARE.
|
|
||||||
|
|
||||||
%ifndef __INC_PART_TABLE
|
%ifndef __INC_PART_TABLE
|
||||||
|
|
||||||
|
%define DISK_SIGNATURE_OFFSET 0x1B8
|
||||||
|
%define DISK_PARTITION_TABLE_OFFSET 0x1BE
|
||||||
|
|
||||||
; Partition table entry format
|
; Partition table entry format
|
||||||
; Off. Size. Description
|
; Off. Size. Description
|
||||||
;0x00 1 Drive attributes (bit 7 set = active or bootable)
|
;0x00 1 Drive attributes (bit 7 set = active or bootable)
|
||||||
@@ -39,8 +37,6 @@ struc PartEntry_t
|
|||||||
endstruc
|
endstruc
|
||||||
|
|
||||||
struc PartTable_t
|
struc PartTable_t
|
||||||
.signature resb 4
|
|
||||||
.reserved resb 2
|
|
||||||
.partition1 resb PartEntry_t_size
|
.partition1 resb PartEntry_t_size
|
||||||
.partition2 resb PartEntry_t_size
|
.partition2 resb PartEntry_t_size
|
||||||
.partition3 resb PartEntry_t_size
|
.partition3 resb PartEntry_t_size
|
||||||
|
|||||||
164
include/util/arena_alloc.nasm
Normal file
164
include/util/arena_alloc.nasm
Normal file
@@ -0,0 +1,164 @@
|
|||||||
|
%ifndef __INC_ARENA_ALLOC_FUNC
|
||||||
|
|
||||||
|
%define __ARENA_HEAP_START 0x8000
|
||||||
|
%define __ARENA_HEAP_SIZE 0x6000 ; 0x8000 -> 0xE000 = 24KiB of Heap
|
||||||
|
|
||||||
|
struc ArenaStateStruc_t
|
||||||
|
.start resw 1
|
||||||
|
.end resw 1
|
||||||
|
.mark resw 1
|
||||||
|
endstruc
|
||||||
|
|
||||||
|
; void arena_init(ArenaState *a)
|
||||||
|
;
|
||||||
|
ArenaInit:
|
||||||
|
__CDECL16_PROC_ENTRY
|
||||||
|
.proc:
|
||||||
|
mov ax, word [bp + 4] ; ptr to state structure
|
||||||
|
mov di, ax
|
||||||
|
|
||||||
|
xor ax, ax
|
||||||
|
mov word [di + ArenaStateStruc_t.mark], ax
|
||||||
|
mov word [di + ArenaStateStruc_t.end], word (__ARENA_HEAP_START + __ARENA_HEAP_SIZE)
|
||||||
|
mov word [di + ArenaStateStruc_t.start], __ARENA_HEAP_START
|
||||||
|
|
||||||
|
; zero out heap area on init
|
||||||
|
; void* kmemset_byte(void* dst, uint8_t val, uint16_t len);
|
||||||
|
; TODO: use word or qword spacing at least to speed this up
|
||||||
|
push __ARENA_HEAP_SIZE ; len
|
||||||
|
push 0x0 ; val = 0
|
||||||
|
push __ARENA_HEAP_START ; dst
|
||||||
|
call kmemset
|
||||||
|
add sp, 0x6
|
||||||
|
.endp:
|
||||||
|
__CDECL16_PROC_EXIT
|
||||||
|
ret
|
||||||
|
|
||||||
|
; size_t align_up(size_t x, size_t a)
|
||||||
|
; ax, bx. cx are all clobbered
|
||||||
|
; align x up to the nearest specified alignment (a), a should be a power of 2
|
||||||
|
; (x + (a-1)) & ~(a-1)
|
||||||
|
; return value in ax
|
||||||
|
ArenaAlignUp:
|
||||||
|
__CDECL16_PROC_ENTRY
|
||||||
|
.func:
|
||||||
|
; if a == 0 return x
|
||||||
|
mov ax, [bp + 4] ; x
|
||||||
|
mov bx, [bp + 6] ; a
|
||||||
|
|
||||||
|
test bx, bx
|
||||||
|
jz .endf
|
||||||
|
|
||||||
|
; enforce power-of-two for alignment, return x
|
||||||
|
; for example...
|
||||||
|
; alignment = 0x0010,
|
||||||
|
; 0x0010 & (0x0010 - 0x0001)
|
||||||
|
; 0x0010 & 0x000F -> 1_0000000b & 0_11111111b => 0b == zero
|
||||||
|
;
|
||||||
|
; alignment = 0x0006
|
||||||
|
; 0x0006 & (0x0006 - 0x0001)
|
||||||
|
; 0x0006 & 0x0005 -> 00000110b & 00000101b => 00000100b != 0
|
||||||
|
;
|
||||||
|
; i.e any power of 2 has only 1 bit set in binary (2 = 0010b, 4 = 0100b, 8 = 1000b and so on)
|
||||||
|
; subtracting 1 from a power of 2 'flips' lower bits ( 7 = 0111b, 15 = 1111b ...)
|
||||||
|
; so 'and'ing a power of two with (itself - 1) will result in none of the bit's being set
|
||||||
|
mov cx, bx
|
||||||
|
dec cx
|
||||||
|
test bx, cx
|
||||||
|
jnz .endf
|
||||||
|
|
||||||
|
dec bx ; a - 1
|
||||||
|
|
||||||
|
mov cx, ax
|
||||||
|
add cx, bx ; x + (a-1)
|
||||||
|
not bx ; ~(a-1)
|
||||||
|
|
||||||
|
and cx, bx ; and with the inverse
|
||||||
|
|
||||||
|
mov ax, cx ; move to ax and return
|
||||||
|
.endf:
|
||||||
|
__CDECL16_PROC_EXIT
|
||||||
|
ret
|
||||||
|
|
||||||
|
; void* arena_alloc(size_t bytes, size_t align)
|
||||||
|
; bp-2 - current used arena (i.e 'highmark')
|
||||||
|
; bp-4 - aligned_ptr
|
||||||
|
; bp-6 - new_end
|
||||||
|
ArenaAlloc:
|
||||||
|
__CDECL16_PROC_ENTRY 0x10
|
||||||
|
.proc:
|
||||||
|
; remove bytes from pool and increment mark to the new cursor location
|
||||||
|
; return a pointer to the begining of allocated segment
|
||||||
|
mov bx, early_heap_state
|
||||||
|
|
||||||
|
mov ax, word [bx + ArenaStateStruc_t.start]
|
||||||
|
mov dx, word [bx + ArenaStateStruc_t.mark]
|
||||||
|
add ax, dx ; i.e the total used arena
|
||||||
|
mov word [bp - 2], ax ; save as a local
|
||||||
|
|
||||||
|
push bx ; save heap_state pointer
|
||||||
|
|
||||||
|
|
||||||
|
push word [bp + 6] ; requested next allocation alignment
|
||||||
|
push word [bp - 2] ; current arena 'highmark'
|
||||||
|
call ArenaAlignUp
|
||||||
|
add sp, 0x4
|
||||||
|
mov word [bp - 4], ax ; save return value
|
||||||
|
|
||||||
|
pop bx ; restore heap_state pointer
|
||||||
|
|
||||||
|
; new_end = aligned_ptr + bytes
|
||||||
|
add ax, word [bp + 4] ; add to total (so current aligned mark + bytes)
|
||||||
|
mov word [bp - 6], ax ; save as local
|
||||||
|
|
||||||
|
mov dx, word [bx + ArenaStateStruc_t.end]
|
||||||
|
cmp ax, dx
|
||||||
|
ja .error ; if our heap end is < the requested throw an error, heap is full
|
||||||
|
; else update the mark to the new value & return the aligned pointer
|
||||||
|
|
||||||
|
; mark_delta = new_end - curr_used
|
||||||
|
mov dx, word [bp - 6]
|
||||||
|
sub dx, word [bp - 2]
|
||||||
|
|
||||||
|
; mark += mark_delta
|
||||||
|
mov ax, word [bx + ArenaStateStruc_t.mark]
|
||||||
|
add ax, dx
|
||||||
|
mov word [bx + ArenaStateStruc_t.mark], ax
|
||||||
|
|
||||||
|
; return aligned_ptr
|
||||||
|
mov ax, word [bp - 4]
|
||||||
|
.endp:
|
||||||
|
__CDECL16_PROC_EXIT
|
||||||
|
ret
|
||||||
|
.error:
|
||||||
|
ERROR STEVIA_DEBUG_ERR
|
||||||
|
|
||||||
|
arena_mark:
|
||||||
|
__CDECL16_PROC_ENTRY
|
||||||
|
.proc:
|
||||||
|
; return the current location of the 'cursor' in the allocator
|
||||||
|
ERROR STEVIA_DEBUG_UNIMPLEMENTED
|
||||||
|
.endp:
|
||||||
|
__CDECL16_PROC_EXIT
|
||||||
|
ret
|
||||||
|
|
||||||
|
arena_reset_to:
|
||||||
|
__CDECL16_PROC_ENTRY
|
||||||
|
.proc:
|
||||||
|
; rewind the arena to a previously marked point
|
||||||
|
ERROR STEVIA_DEBUG_UNIMPLEMENTED
|
||||||
|
.endp:
|
||||||
|
__CDECL16_PROC_EXIT
|
||||||
|
ret
|
||||||
|
|
||||||
|
arena_reset:
|
||||||
|
__CDECL16_PROC_ENTRY
|
||||||
|
.proc:
|
||||||
|
; reset the entire heap to a fresh state
|
||||||
|
ERROR STEVIA_DEBUG_UNIMPLEMENTED
|
||||||
|
.endp:
|
||||||
|
__CDECL16_PROC_EXIT
|
||||||
|
ret
|
||||||
|
|
||||||
|
%endif
|
||||||
|
%define __INC_ARENA_ALLOC_FUNC
|
||||||
@@ -1,22 +1,17 @@
|
|||||||
; Copyright (c) 2024 Elaina Claus
|
; Copyright (C) 2025 Elaina Claus
|
||||||
;
|
;
|
||||||
; Permission is hereby granted, free of charge, to any person obtaining a copy
|
; This program is free software: you can redistribute it and/or modify
|
||||||
; of this software and associated documentation files (the "Software"), to deal
|
; it under the terms of the GNU General Public License as published by
|
||||||
; in the Software without restriction, including without limitation the rights
|
; the Free Software Foundation, either version 3 of the License, or
|
||||||
; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
; (at your option) any later version.
|
||||||
; copies of the Software, and to permit persons to whom the Software is
|
|
||||||
; furnished to do so, subject to the following conditions:
|
|
||||||
;
|
;
|
||||||
; The above copyright notice and this permission notice shall be included in all
|
; This program is distributed in the hope that it will be useful,
|
||||||
; copies or substantial portions of the Software.
|
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
; GNU General Public License for more details.
|
||||||
;
|
;
|
||||||
; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
; You should have received a copy of the GNU General Public License
|
||||||
; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
; along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
; SOFTWARE.
|
|
||||||
|
|
||||||
%ifndef __INC_BOCHS_DEBUG_MAGIC
|
%ifndef __INC_BOCHS_DEBUG_MAGIC
|
||||||
|
|
||||||
|
|||||||
@@ -1,22 +1,17 @@
|
|||||||
; Copyright (c) 2024 Elaina Claus
|
; Copyright (C) 2025 Elaina Claus
|
||||||
;
|
;
|
||||||
; Permission is hereby granted, free of charge, to any person obtaining a copy
|
; This program is free software: you can redistribute it and/or modify
|
||||||
; of this software and associated documentation files (the "Software"), to deal
|
; it under the terms of the GNU General Public License as published by
|
||||||
; in the Software without restriction, including without limitation the rights
|
; the Free Software Foundation, either version 3 of the License, or
|
||||||
; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
; (at your option) any later version.
|
||||||
; copies of the Software, and to permit persons to whom the Software is
|
|
||||||
; furnished to do so, subject to the following conditions:
|
|
||||||
;
|
;
|
||||||
; The above copyright notice and this permission notice shall be included in all
|
; This program is distributed in the hope that it will be useful,
|
||||||
; copies or substantial portions of the Software.
|
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
; GNU General Public License for more details.
|
||||||
;
|
;
|
||||||
; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
; You should have received a copy of the GNU General Public License
|
||||||
; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
; along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
; SOFTWARE.
|
|
||||||
|
|
||||||
%ifndef __INC_ERROR_FUNC
|
%ifndef __INC_ERROR_FUNC
|
||||||
|
|
||||||
|
|||||||
@@ -1,47 +1,42 @@
|
|||||||
; Copyright (c) 2024 Elaina Claus
|
; Copyright (C) 2025 Elaina Claus
|
||||||
;
|
;
|
||||||
; Permission is hereby granted, free of charge, to any person obtaining a copy
|
; This program is free software: you can redistribute it and/or modify
|
||||||
; of this software and associated documentation files (the "Software"), to deal
|
; it under the terms of the GNU General Public License as published by
|
||||||
; in the Software without restriction, including without limitation the rights
|
; the Free Software Foundation, either version 3 of the License, or
|
||||||
; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
; (at your option) any later version.
|
||||||
; copies of the Software, and to permit persons to whom the Software is
|
|
||||||
; furnished to do so, subject to the following conditions:
|
|
||||||
;
|
;
|
||||||
; The above copyright notice and this permission notice shall be included in all
|
; This program is distributed in the hope that it will be useful,
|
||||||
; copies or substantial portions of the Software.
|
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
; GNU General Public License for more details.
|
||||||
;
|
;
|
||||||
; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
; You should have received a copy of the GNU General Public License
|
||||||
; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
; along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
; SOFTWARE.
|
|
||||||
|
|
||||||
%ifndef __INC_KMEM_FUNC
|
%ifndef __INC_KMEM_FUNC
|
||||||
%include 'cdecl16.inc'
|
%include 'cdecl16.inc'
|
||||||
|
|
||||||
; uint8_t* kmemset_byte(void* dst, uint8_t val, uint16_t len);
|
; void* kmemset_byte(void* dst, uint8_t val, uint16_t len);
|
||||||
ALIGN 4, db 0x90
|
ALIGN 4, db 0x90
|
||||||
kmemset:
|
kmemset:
|
||||||
__CDECL16_ENTRY
|
__CDECL16_PROC_ENTRY
|
||||||
.func:
|
.func:
|
||||||
mov cx, [bp + 8] ; size_t len
|
mov cx, [bp + 8] ; uint16_t len
|
||||||
mov al, [bp + 6] ; uint8_t val
|
mov al, byte [bp + 6] ; uint8_t val
|
||||||
mov di, [bp + 4] ; void * dst
|
mov di, [bp + 4] ; void * dst
|
||||||
|
|
||||||
cld
|
cld
|
||||||
rep stosb
|
rep stosb
|
||||||
mov ax, di ; return pointer to dest
|
mov ax, di ; return pointer to dest + len (last elem of dest)
|
||||||
.endp:
|
.endp:
|
||||||
__CDECL16_EXIT
|
__CDECL16_PROC_EXIT
|
||||||
ret
|
ret
|
||||||
|
|
||||||
; uint8_t* kmemset(uint8_t* dest, uint8_t* src, uint8_t len);
|
; uint8_t* kmemset(uint16_t* dest, uint16_t* src, uint16_t len);
|
||||||
; not overlap safe
|
; not overlap safe
|
||||||
ALIGN 4, db 0x90
|
ALIGN 4, db 0x90
|
||||||
kmemcpy:
|
kmemcpy:
|
||||||
__CDECL16_ENTRY
|
__CDECL16_PROC_ENTRY
|
||||||
.func:
|
.func:
|
||||||
mov cx, [bp + 8] ; len
|
mov cx, [bp + 8] ; len
|
||||||
mov si, [bp + 6] ; src
|
mov si, [bp + 6] ; src
|
||||||
@@ -51,7 +46,7 @@ kmemcpy:
|
|||||||
rep movsb
|
rep movsb
|
||||||
mov ax, di ; return pointer to dest
|
mov ax, di ; return pointer to dest
|
||||||
.endf:
|
.endf:
|
||||||
__CDECL16_EXIT
|
__CDECL16_PROC_EXIT
|
||||||
ret
|
ret
|
||||||
|
|
||||||
%endif
|
%endif
|
||||||
|
|||||||
@@ -1,22 +1,17 @@
|
|||||||
; Copyright (c) 2024 Elaina Claus
|
; Copyright (C) 2025 Elaina Claus
|
||||||
;
|
;
|
||||||
; Permission is hereby granted, free of charge, to any person obtaining a copy
|
; This program is free software: you can redistribute it and/or modify
|
||||||
; of this software and associated documentation files (the "Software"), to deal
|
; it under the terms of the GNU General Public License as published by
|
||||||
; in the Software without restriction, including without limitation the rights
|
; the Free Software Foundation, either version 3 of the License, or
|
||||||
; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
; (at your option) any later version.
|
||||||
; copies of the Software, and to permit persons to whom the Software is
|
|
||||||
; furnished to do so, subject to the following conditions:
|
|
||||||
;
|
;
|
||||||
; The above copyright notice and this permission notice shall be included in all
|
; This program is distributed in the hope that it will be useful,
|
||||||
; copies or substantial portions of the Software.
|
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
; GNU General Public License for more details.
|
||||||
;
|
;
|
||||||
; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
; You should have received a copy of the GNU General Public License
|
||||||
; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
; along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
; SOFTWARE.
|
|
||||||
|
|
||||||
%ifndef __INC_KMEMCPY5_FUNC
|
%ifndef __INC_KMEMCPY5_FUNC
|
||||||
%include 'cdecl16.inc'
|
%include 'cdecl16.inc'
|
||||||
@@ -25,7 +20,7 @@
|
|||||||
; not overlap safe, only for
|
; not overlap safe, only for
|
||||||
ALIGN 4, db 0x90
|
ALIGN 4, db 0x90
|
||||||
kmemcpy5:
|
kmemcpy5:
|
||||||
__CDECL16_ENTRY
|
__CDECL16_PROC_ENTRY
|
||||||
push ds
|
push ds
|
||||||
push es
|
push es
|
||||||
.setup_segments:
|
.setup_segments:
|
||||||
@@ -46,7 +41,7 @@ kmemcpy5:
|
|||||||
pop es
|
pop es
|
||||||
pop ds
|
pop ds
|
||||||
.endf:
|
.endf:
|
||||||
__CDECL16_EXIT
|
__CDECL16_PROC_EXIT
|
||||||
ret
|
ret
|
||||||
|
|
||||||
%define __INC_KMEMCPY5_FUNC
|
%define __INC_KMEMCPY5_FUNC
|
||||||
|
|||||||
@@ -1,22 +1,17 @@
|
|||||||
; Copyright (c) 2024 Elaina Claus
|
; Copyright (C) 2025 Elaina Claus
|
||||||
;
|
;
|
||||||
; Permission is hereby granted, free of charge, to any person obtaining a copy
|
; This program is free software: you can redistribute it and/or modify
|
||||||
; of this software and associated documentation files (the "Software"), to deal
|
; it under the terms of the GNU General Public License as published by
|
||||||
; in the Software without restriction, including without limitation the rights
|
; the Free Software Foundation, either version 3 of the License, or
|
||||||
; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
; (at your option) any later version.
|
||||||
; copies of the Software, and to permit persons to whom the Software is
|
|
||||||
; furnished to do so, subject to the following conditions:
|
|
||||||
;
|
;
|
||||||
; The above copyright notice and this permission notice shall be included in all
|
; This program is distributed in the hope that it will be useful,
|
||||||
; copies or substantial portions of the Software.
|
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
; GNU General Public License for more details.
|
||||||
;
|
;
|
||||||
; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
; You should have received a copy of the GNU General Public License
|
||||||
; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
; along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
; SOFTWARE.
|
|
||||||
|
|
||||||
%ifndef __INC_KMEMSET4_FUNC
|
%ifndef __INC_KMEMSET4_FUNC
|
||||||
%include 'cdecl16.inc'
|
%include 'cdecl16.inc'
|
||||||
@@ -24,7 +19,7 @@
|
|||||||
; word kmemset_byte(word segment, word dst, byte val, word len);
|
; word kmemset_byte(word segment, word dst, byte val, word len);
|
||||||
ALIGN 4, db 0x90
|
ALIGN 4, db 0x90
|
||||||
kmemset4:
|
kmemset4:
|
||||||
__CDECL16_ENTRY
|
__CDECL16_PROC_ENTRY
|
||||||
.setup_segment:
|
.setup_segment:
|
||||||
push es
|
push es
|
||||||
mov ax, [bp + 4]
|
mov ax, [bp + 4]
|
||||||
@@ -40,7 +35,7 @@ kmemset4:
|
|||||||
.restore_segments:
|
.restore_segments:
|
||||||
pop es
|
pop es
|
||||||
.endf:
|
.endf:
|
||||||
__CDECL16_EXIT
|
__CDECL16_PROC_EXIT
|
||||||
ret
|
ret
|
||||||
|
|
||||||
%endif
|
%endif
|
||||||
|
|||||||
@@ -1,265 +1,176 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
# Copyright (c) 2023 Elaina Claus
|
# Copyright (C) 2025 Elaina Claus
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
# This program is free software: you can redistribute it and/or modify
|
||||||
# of this software and associated documentation files (the "Software"), to deal
|
# it under the terms of the GNU General Public License as published by
|
||||||
# in the Software without restriction, including without limitation the rights
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
# (at your option) any later version.
|
||||||
# copies of the Software, and to permit persons to whom the Software is
|
|
||||||
# furnished to do so, subject to the following conditions:
|
|
||||||
#
|
#
|
||||||
# The above copyright notice and this permission notice shall be included in all
|
# This program is distributed in the hope that it will be useful,
|
||||||
# copies or substantial portions of the Software.
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
#
|
#
|
||||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
# You should have received a copy of the GNU General Public License
|
||||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
# SOFTWARE.
|
|
||||||
|
|
||||||
if ! [ $(id -u) = 0 ]; then
|
if [ $(id -u) = 0 ]; then
|
||||||
echo "Script must be run as root!" >&2
|
echo "Script should not be run as root, it could break something!" >&2
|
||||||
exit 1
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# paths to bootcode
|
# paths to bootcode
|
||||||
mbr_file=build/mbr.bin
|
mbr_file=build/mbr/mbr.bin
|
||||||
vbr_file=build/vbr.bin
|
vbr_file=build/vbr/vbr.bin
|
||||||
stage2_file=build/stage2.bin
|
stage2_file=build/stage2/stage2.bin
|
||||||
boottest_file=build/BOOTi686.bin
|
boottest_file=build/miniboot32/BOOTi686.bin
|
||||||
|
|
||||||
|
|
||||||
# Disk creation options
|
# Disk creation options
|
||||||
mount_point=/tmp/stevia_disk
|
disk_img=build/disk.img
|
||||||
disk_tmp_file=/tmp/disk.img
|
disk_img_final=build/output/disk.img.gz
|
||||||
disk_file_final=./disk.img.gz
|
|
||||||
|
part_img=build/part.img
|
||||||
|
part_img_final=build/output/part.img.gz
|
||||||
|
|
||||||
|
artifacts_archive=build/output/artifacts.tar.gz
|
||||||
|
|
||||||
# $disk_sector_size * $disk_size = total bytes, default is 256MiB
|
# $disk_sector_size * $disk_size = total bytes, default is 256MiB
|
||||||
disk_size=(524288 * 2)
|
disk_sectors=(524288 * 2)
|
||||||
disk_sector_size=512
|
disk_sector_size=512
|
||||||
|
part_start=2048
|
||||||
|
part_sectors=$((disk_sectors - part_start))
|
||||||
|
|
||||||
if ! [ -e $disk_tmp_file ]; then
|
#
|
||||||
|
# Build sanity section
|
||||||
|
#
|
||||||
|
|
||||||
|
echo "*** Performing pre-build sanity checks ***"
|
||||||
|
|
||||||
|
# Tools needed:
|
||||||
|
# sfdisk dosfstools (mkfs.fat), mtools (mcopy,mmd), gzip, dd, truncate, awk
|
||||||
|
for t in mcopy mmd gzip dd truncate awk; do
|
||||||
|
command -v "$t" >/dev/null || { echo "Missing tool: $t" >&2; exit 1; }
|
||||||
|
done
|
||||||
|
|
||||||
|
# these are normally in the sbin paths so I've had issues detecting them with command -v
|
||||||
|
SF=$(command -v sfdisk || echo /usr/sbin/sfdisk)
|
||||||
|
MKFS=$(command -v mkfs.fat || echo /usr/sbin/mkfs.fat)
|
||||||
|
|
||||||
|
[[ -x "$SF" ]] || { echo "sfdisk not found"; exit 1; }
|
||||||
|
[[ -x "$MKFS" ]] || { echo "mkfs.fat not found"; exit 1; }
|
||||||
|
|
||||||
|
# check that required build files exist
|
||||||
|
for f in "$mbr_file" "$vbr_file" "$stage2_file" "$boottest_file"; do
|
||||||
|
[[ -f "$f" ]] || { echo "missing $f" >&2; exit 1; }
|
||||||
|
done
|
||||||
|
|
||||||
|
cat > /tmp/pt.sfdisk <<EOF
|
||||||
|
label: dos
|
||||||
|
unit: sectors
|
||||||
|
sector-size: $disk_sector_size
|
||||||
|
label-id: 0xa0b0c0d0
|
||||||
|
|
||||||
|
start=$part_start, size=$((disk_sectors - part_start)), type=c, bootable
|
||||||
|
EOF
|
||||||
|
|
||||||
|
mtool_src=/tmp/mtools.conf
|
||||||
|
cat > $mtool_src <<EOF
|
||||||
|
drive c: file="$part_img"
|
||||||
|
EOF
|
||||||
|
|
||||||
|
#
|
||||||
|
# Create disk images
|
||||||
|
#
|
||||||
|
|
||||||
|
echo "[1/7] Create disk.img and part.img"
|
||||||
|
|
||||||
|
if ! [ -e "$disk_img" ]; then
|
||||||
# create raw disk image
|
# create raw disk image
|
||||||
if ! dd if=/dev/zero of=$disk_tmp_file bs=$disk_sector_size count=$disk_size; then
|
if ! truncate -s $((disk_sectors * disk_sector_size)) "$disk_img"; then
|
||||||
echo "Failed creating blank disk image." >&2
|
echo "Failed creating blank disk image." >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
sync
|
sync
|
||||||
else
|
else
|
||||||
echo "Removing old disk image..."
|
echo "Removing old disk image..."
|
||||||
rm -rfv $disk_tmp_file
|
rm -rfv "$disk_img"
|
||||||
if ! dd if=/dev/zero of=$disk_tmp_file bs=$disk_sector_size count=$disk_size; then
|
if ! truncate -s $((disk_sectors * disk_sector_size)) "$disk_img"; then
|
||||||
echo "Failed creating blank disk image." >&2
|
echo "Failed creating blank disk image." >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
sync
|
sync
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if ! [ -e "$part_img" ]; then
|
||||||
|
# create raw partition disk image
|
||||||
|
if ! truncate -s $((part_sectors * disk_sector_size)) "$part_img"; then
|
||||||
|
echo "Failed creating blank partition image." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
sync
|
||||||
|
else
|
||||||
|
echo "Removing old (partition) disk image..."
|
||||||
|
rm -rfv "$part_img"
|
||||||
|
if ! truncate -s $((part_sectors * disk_sector_size)) "$part_img"; then
|
||||||
|
echo "Failed creating blank partition image." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
sync
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
if [[ "$OSTYPE" == "linux-gnu"* ]]; then
|
if [[ "$OSTYPE" == "linux-gnu"* ]]; then
|
||||||
if [ -e $mbr_file ] && [ -e $vbr_file ]; then
|
echo "[2/7] Write DOS partition table (single FAT32 LBA @ 2048)"
|
||||||
# get next loop device and mount it
|
"$SF" --no-reread "$disk_img" < /tmp/pt.sfdisk
|
||||||
ld=$(losetup -f)
|
|
||||||
losetup -P -b 512 $ld $disk_tmp_file
|
|
||||||
|
|
||||||
# create a DOS disk, with 1 FAT32 partition that is bootable, part1 starts at sector 2048
|
# BUG: the default disk img is 256MiB which mkfs.fat wants to create
|
||||||
sfdisk $ld < scripts/loop_setup.sfdisk
|
# a FAT16 FS by default. it needs to be at least 2GiB to to 'lock out'
|
||||||
|
# FAT16 as an option. Force FAT32 here, might(?) break some things.
|
||||||
|
echo "[3/7] Make FAT filesystem in partition image"
|
||||||
|
"$MKFS" -F32 -v -n 'STEVIAFS' "$part_img"
|
||||||
|
|
||||||
# get first partition, this is sloppy might need to review this...
|
echo "[4/7] Patch VBR inside partition image (preserve BPB)"
|
||||||
firstpart=$(lsblk -ilp -o NAME $ld | tr '\n' ' ' | awk '{print $3}')
|
|
||||||
mkfs.fat -v -F32 -s 1 -n 'STEVIAFS' $firstpart
|
|
||||||
|
|
||||||
#
|
|
||||||
# MBR setup
|
|
||||||
#
|
|
||||||
|
|
||||||
# copy MBR while preserving partition table
|
|
||||||
if ! dd if=$mbr_file of=$ld bs=1 count=440; then
|
|
||||||
echo "Failed to write MBR to disk. (part 1)" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# copy MBR 0xAA55
|
|
||||||
if ! dd if=$mbr_file of=$ld bs=1 seek=510 skip=510 count=2; then
|
|
||||||
echo "Failed to write MBR to disk. (part 2)" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
#
|
|
||||||
# VBR Setup & backup VBR
|
|
||||||
#
|
|
||||||
|
|
||||||
# copy VBR to partition 1 while preserving partition information
|
|
||||||
# copy jmp short entry; nop
|
# copy jmp short entry; nop
|
||||||
if ! dd if=$vbr_file of=$firstpart bs=1 count=3; then
|
dd if=$vbr_file of="$part_img" bs=1 count=3 conv=notrunc
|
||||||
echo "Failed to write VBR to disk. (part 1)" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
# copy bootcode
|
# copy bootcode
|
||||||
if ! dd if=$vbr_file of=$firstpart bs=1 seek=90 skip=90 count=420; then
|
dd if=$vbr_file of="$part_img" bs=1 seek=90 skip=90 count=420 conv=notrunc
|
||||||
echo "Failed to write VBR to disk. (part 2)" >&2
|
# copy signature (should be 0xAA55)
|
||||||
exit 1
|
dd if=$vbr_file of="$part_img" bs=1 seek=510 skip=510 count=2 conv=notrunc
|
||||||
fi
|
|
||||||
# copy 0xAA55
|
# copy backup VBR within the created partition image
|
||||||
if ! dd if=$vbr_file of=$firstpart bs=1 seek=510 skip=510 count=2; then
|
# Linux dosfstools will complain (read: not work) unless this is done it seems
|
||||||
echo "Failed to write VBR to disk. (part 3)" >&2
|
# HACK: sector 6 is the **default** location of the BPB_BkBootSec, it **can** be different.
|
||||||
exit 1
|
dd if="$part_img" of="$part_img" bs=$disk_sector_size count=1 seek=6 conv=notrunc
|
||||||
fi
|
|
||||||
|
echo "[5/7] Copy boot payload to FAT32 filesystem using mtools as BOOT.BIN"
|
||||||
# write backup VBR
|
MTOOLSRC="$mtool_src" mcopy "$boottest_file" C:BOOT.BIN
|
||||||
if ! dd if=$firstpart of=$firstpart bs=$disk_sector_size count=1 seek=6; then
|
MTOOLSRC="$mtool_src" mdir C:
|
||||||
echo "Failed to copy VBR (sector 1) to backup VBR." >&2
|
|
||||||
exit 1
|
echo "[6/7] Patch MBR and install stage2 loader to disk image"
|
||||||
fi
|
# patch MBR+signature while preserving partition table
|
||||||
|
dd if="$mbr_file" of="$disk_img" bs=1 count=440 conv=notrunc
|
||||||
|
dd if="$mbr_file" of="$disk_img" bs=1 seek=510 skip=510 count=2 conv=notrunc
|
||||||
#
|
|
||||||
# Stage2 Setup
|
# copy stage2 to absolute LBA 1
|
||||||
#
|
dd if="$stage2_file" of="$disk_img" bs=$disk_sector_size seek=1 conv=notrunc
|
||||||
|
|
||||||
#stage2 to sectors 1-64
|
echo "[7/7] Assembling final disk image"
|
||||||
if ! dd if=$stage2_file of=$ld bs=$disk_sector_size seek=1; then
|
# place partition at it's place in the disk image
|
||||||
echo "Failed to write Stage2 to disk." >&2
|
dd if="$part_img" of="$disk_img" bs=$disk_sector_size seek=$part_start conv=notrunc
|
||||||
exit 1
|
|
||||||
fi
|
echo " *** Outputing disk images will be in ./build/output/* *** "
|
||||||
|
|
||||||
# copy boot32 boot test file to disk image
|
if [ ! -d ./build/output ]; then
|
||||||
if ! [ -e $mount_point ]; then
|
echo "./build/output does not exist. creating"
|
||||||
mkdir $mount_point
|
mkdir -p ./build/output
|
||||||
fi
|
|
||||||
mount $firstpart $mount_point
|
|
||||||
|
|
||||||
# ensure mountpoint is actually a mountpoint
|
|
||||||
if ! mountpoint -q $mount_point; then
|
|
||||||
echo "Failed to mount partition at $mount_point." >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# copy kernel to filesystem
|
|
||||||
if [ -e $boottest_file ]; then
|
|
||||||
cp -v $boottest_file $mount_point/BOOT.BIN
|
|
||||||
else
|
|
||||||
echo "Failed to write $boottest_file to disk image" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
#
|
|
||||||
# Final Cleanup
|
|
||||||
#
|
|
||||||
|
|
||||||
# detach loop device
|
|
||||||
umount $mount_point
|
|
||||||
sync
|
|
||||||
sleep 1
|
|
||||||
losetup -d $ld
|
|
||||||
|
|
||||||
# chown to the real user to prevent issues with reading/writing the file later
|
|
||||||
# BUG: ${logname}:$(id $(logname -g)) doesn't work right on WSL because of runlevel hacks in WSL
|
|
||||||
# BUG: https://github.com/microsoft/WSL/issues/1761
|
|
||||||
# as a work around I'll just reference LICENSE.md...WHICH SHOULD ALWAYS BE THERE 👀
|
|
||||||
chown --from=root:root --reference=LICENSE.md $disk_tmp_file
|
|
||||||
|
|
||||||
else
|
|
||||||
echo "unable to find MBR/VBR binaries!" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
# requires util-linux from homebrew
|
|
||||||
elif [[ "$OSTYPE" == "darwin"* ]]; then
|
|
||||||
sfdisk_path="/usr/local/opt/util-linux/sbin/sfdisk"
|
|
||||||
if [ -e $mbr_file ] && [ -e $vbr_file ]; then
|
|
||||||
# use hdiutil to attach our empty disk image
|
|
||||||
ld_path_raw=$(hdiutil attach -readwrite -imagekey diskimage-class=CRawDiskImage -nomount -blocksize 512 -noverify disk.img)
|
|
||||||
ld=$(echo $ld_path_raw | sed s:/dev/::)
|
|
||||||
ld_path="/dev/$ld"
|
|
||||||
|
|
||||||
# create a DOS disk, with 1 FAT32 partition
|
|
||||||
if ! [ -e $sfdisk_path ]; then
|
|
||||||
echo "sfdisk utility was not found...We cannot use diskutil to make disks due to the fact that it only makes Hybrid MBR's & GPT disks...blame Apple"
|
|
||||||
exit 4
|
|
||||||
else
|
|
||||||
$sfdisk_path $ld_path < scripts/loop_setup.sfdisk
|
|
||||||
fi
|
|
||||||
|
|
||||||
# give stuff a chance to settle, macOS has problems here
|
|
||||||
sync
|
|
||||||
sleep .5
|
|
||||||
|
|
||||||
# reattch the raw image file since macOS doesn't have a partprobe...
|
|
||||||
# this is the only way I know to get macOS to reprobe the disk
|
|
||||||
hdiutil eject $ld
|
|
||||||
unset ld_path
|
|
||||||
unset ld
|
|
||||||
unset ld_path_raw
|
|
||||||
|
|
||||||
ld_path_raw=$(hdiutil attach -readwrite -imagekey diskimage-class=CRawDiskImage -nomount -blocksize 512 -noverify disk.img)
|
|
||||||
ld=$(echo $ld_path_raw | grep "FDisk_partition_scheme" | awk '{print $1}' | sed s:/dev/::)
|
|
||||||
ld_path="/dev/$ld"
|
|
||||||
|
|
||||||
if ! [ -b /dev/$ld ]; then
|
|
||||||
echo "Unable to remount disk! exitting before I do some damage!"
|
|
||||||
exit 5
|
|
||||||
fi
|
|
||||||
|
|
||||||
# get first partition and format as FAT32
|
|
||||||
firstpart=$(diskutil list $ld | grep 1: | awk '{print $6}')
|
|
||||||
firstpart_direct="r$firstpart"
|
|
||||||
|
|
||||||
newfs_msdos -F 32 /dev/$firstpart_direct
|
|
||||||
sync
|
|
||||||
|
|
||||||
# copy MBR while preserving partition table
|
|
||||||
dd if=$mbr_file of=$ld_path bs=1 count=440 conv=sync
|
|
||||||
# copy MBR 0xAA55
|
|
||||||
dd if=$mbr_file of=$ld_path bs=1 seek=510 skip=510 count=2 conv=sync
|
|
||||||
|
|
||||||
# copy VBR to partition 1 while preserving partition information
|
|
||||||
# copy jmp short entry; nop
|
|
||||||
dd if=$vbr_file of=/dev/$firstpart bs=1 count=3 conv=sync
|
|
||||||
# copy bootcode
|
|
||||||
dd if=$vbr_file of=/dev/$firstpart bs=1 seek=90 skip=90 count=420 conv=sync
|
|
||||||
# copy 0xAA55
|
|
||||||
dd if=$vbr_file of=/dev/$firstpart bs=1 seek=510 skip=510 count=2 conv=sync
|
|
||||||
|
|
||||||
#stage2 to sectors 1-64
|
|
||||||
dd if=$stage2_file of=$ld_path bs=$disk_sector_size seek=1 conv=sync
|
|
||||||
|
|
||||||
#sync pending dd stuff
|
|
||||||
sync
|
|
||||||
|
|
||||||
# copy boot32 boot test file to disk image
|
|
||||||
if ! [ -e $mount_point ]; then
|
|
||||||
mkdir $mount_point
|
|
||||||
else
|
|
||||||
echo "$mount_point exists! clearing contents..."
|
|
||||||
rm -rfv $mount_point
|
|
||||||
mkdir $mount_point
|
|
||||||
fi
|
|
||||||
mount -t msdos /dev/$firstpart $mount_point
|
|
||||||
|
|
||||||
if [ -e $boottest_file ]; then
|
|
||||||
cp -v $boottest_file $mount_point
|
|
||||||
else
|
|
||||||
echo "unable to find boot32.bin!"
|
|
||||||
exit 3
|
|
||||||
fi
|
|
||||||
|
|
||||||
# detach loop device
|
|
||||||
sync
|
|
||||||
umount /dev/$firstpart
|
|
||||||
hdiutil eject $ld
|
|
||||||
|
|
||||||
# chown to the real user to prevent issues with reading/writing the file later
|
|
||||||
SUDOUSER=$(logname)
|
|
||||||
chown ${SUDOUSER}:staff disk.img
|
|
||||||
gzip -9kc $disk_tmp_file > $disk_file_final
|
|
||||||
else
|
|
||||||
echo "unable to find MBR/VBR binaries!"
|
|
||||||
exit 2
|
|
||||||
fi
|
fi
|
||||||
|
gzip -9c "$disk_img" > "$disk_img_final"
|
||||||
|
gzip -9c "$part_img" > "$part_img_final"
|
||||||
|
tar caf "$artifacts_archive" --exclude ./build/output ./build/
|
||||||
else
|
else
|
||||||
# Unknown.
|
# Unknown.
|
||||||
echo "Unknown OS type! Supported build hosts systems are GNU/Linux (WSL) and macOS."
|
echo "Unknown OS type! Supported build hosts systems are GNU/Linux (& WSL)"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
label: dos
|
|
||||||
unit: sectors
|
|
||||||
sector-size: 512
|
|
||||||
|
|
||||||
start= 2048, type=c, bootable
|
|
||||||
@@ -1,29 +1,24 @@
|
|||||||
; Copyright (c) 2023 Elaina Claus
|
; Copyright (C) 2025 Elaina Claus
|
||||||
;
|
;
|
||||||
; Permission is hereby granted, free of charge, to any person obtaining a copy
|
; This program is free software: you can redistribute it and/or modify
|
||||||
; of this software and associated documentation files (the "Software"), to deal
|
; it under the terms of the GNU General Public License as published by
|
||||||
; in the Software without restriction, including without limitation the rights
|
; the Free Software Foundation, either version 3 of the License, or
|
||||||
; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
; (at your option) any later version.
|
||||||
; copies of the Software, and to permit persons to whom the Software is
|
|
||||||
; furnished to do so, subject to the following conditions:
|
|
||||||
;
|
;
|
||||||
; The above copyright notice and this permission notice shall be included in all
|
; This program is distributed in the hope that it will be useful,
|
||||||
; copies or substantial portions of the Software.
|
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
; GNU General Public License for more details.
|
||||||
;
|
;
|
||||||
; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
; You should have received a copy of the GNU General Public License
|
||||||
; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
; along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
; SOFTWARE.
|
|
||||||
|
|
||||||
[BITS 16]
|
[BITS 16]
|
||||||
[ORG 0x8C00]
|
[ORG 0x6C00]
|
||||||
[CPU KATMAI]
|
[CPU KATMAI]
|
||||||
[WARNING -reloc-abs-byte]
|
[WARNING -reloc-abs-byte]
|
||||||
[WARNING -reloc-abs-word] ; Yes, we use absolute addresses. surpress these warnings.
|
[WARNING -reloc-abs-word] ; Yes, we use absolute addresses. surpress these warnings.
|
||||||
[map all mbr.map]
|
[map all build/mbr.map]
|
||||||
%define __STEVIA_MBR
|
%define __STEVIA_MBR
|
||||||
jmp short (init - $$)
|
jmp short (init - $$)
|
||||||
nop
|
nop
|
||||||
@@ -38,10 +33,10 @@ nop
|
|||||||
%include "config.inc"
|
%include "config.inc"
|
||||||
%include "error_codes.inc"
|
%include "error_codes.inc"
|
||||||
%include "partition_table.inc"
|
%include "partition_table.inc"
|
||||||
%include "fat32/fat32_structures.inc"
|
|
||||||
|
|
||||||
%undef __STEVIA_DEV_DEBUG
|
%undef __STEVIA_DEV_DEBUG
|
||||||
|
|
||||||
|
; BIOS will load 1st sector of boot drive to 0x7c00, init and relocate
|
||||||
ALIGN 4
|
ALIGN 4
|
||||||
init:
|
init:
|
||||||
cli ; We do not want to be interrupted
|
cli ; We do not want to be interrupted
|
||||||
@@ -63,14 +58,14 @@ init:
|
|||||||
cld
|
cld
|
||||||
rep stosb ; zero bss section
|
rep stosb ; zero bss section
|
||||||
|
|
||||||
sub sp, 0x20 ; local varible space
|
sub sp, 0x10 ; local varible space (32 bytes)
|
||||||
push bp ; setup top of stack frame
|
push bp ; setup top of stack frame
|
||||||
|
|
||||||
xor cx, cx
|
xor cx, cx
|
||||||
mov ch, 0x02 ; 0x0200 in cx
|
mov ch, 0x02 ; 0x0200 in cx
|
||||||
mov si, 0x7C00 ; Current MBR Address (loaded here by BIOS)
|
mov si, 0x7C00 ; Current MBR Address (loaded here by BIOS)
|
||||||
mov di, MBR_ENTRY ; New MBR Address (our new relocation address)
|
mov di, MBR_ENTRY ; New MBR Address (our new relocation address)
|
||||||
rep movsb ; copy 512 bytes from 0x0000:7c00 to 0x0000:MBR_ENTRY (7A00 as of writing)
|
rep movsb ; copy 512 bytes from 0x0000:7c00 to 0x0000:MBR_ENTRY (6C00 as of writing)
|
||||||
|
|
||||||
sti
|
sti
|
||||||
|
|
||||||
@@ -101,6 +96,8 @@ main:
|
|||||||
mov ah, 0x41
|
mov ah, 0x41
|
||||||
mov bx, 0x55AA
|
mov bx, 0x55AA
|
||||||
mov dl, 0x80
|
mov dl, 0x80
|
||||||
|
|
||||||
|
clc
|
||||||
int 0x13
|
int 0x13
|
||||||
jnc main.find_active
|
jnc main.find_active
|
||||||
ERROR MBR_ERROR_NO_INT32E ; no extended function support
|
ERROR MBR_ERROR_NO_INT32E ; no extended function support
|
||||||
@@ -112,7 +109,7 @@ main:
|
|||||||
mov al, byte [bx + PartEntry_t.attributes]
|
mov al, byte [bx + PartEntry_t.attributes]
|
||||||
test al, 0x80 ; 0x80 == 1000_0000b
|
test al, 0x80 ; 0x80 == 1000_0000b
|
||||||
jnz main.active_found
|
jnz main.active_found
|
||||||
add bx, 0x10 ; add 16 bytes to offset
|
add bx, PartEntry_t_size ; add 16 bytes to offset
|
||||||
loop main.find_active_L0
|
loop main.find_active_L0
|
||||||
|
|
||||||
ERROR MBR_ERROR_NO_NO_BOOT_PART
|
ERROR MBR_ERROR_NO_NO_BOOT_PART
|
||||||
@@ -124,42 +121,26 @@ main:
|
|||||||
mov word [bp - 4], ax ; update part_offset
|
mov word [bp - 4], ax ; update part_offset
|
||||||
.read_data:
|
.read_data:
|
||||||
movzx ax, byte [bp - 2]
|
movzx ax, byte [bp - 2]
|
||||||
push ax ; drive_num
|
push ax ; drive_num (2)
|
||||||
|
push 0x01 ; count (2)
|
||||||
mov ax, 0x1
|
|
||||||
push ax ; count
|
|
||||||
|
|
||||||
mov dword eax, dword [bx + PartEntry_t.lba_start]
|
mov dword eax, dword [bx + PartEntry_t.lba_start]
|
||||||
push dword eax ; lba
|
push dword eax ; lba (4)
|
||||||
|
|
||||||
mov ax, VBR_ENTRY
|
push word 0x7C00 ; offset = 0x7c00 (2)
|
||||||
push ax ; offset = 0x7c00
|
push 0x00 ; segment = 0 (2)
|
||||||
|
|
||||||
xor ax, ax
|
|
||||||
push ax ; segment = 0
|
|
||||||
|
|
||||||
; uint8_t read_stage2_raw(uint16_t buf_segment, uint16_t buf_offset,
|
; uint8_t read_stage2_raw(uint16_t buf_segment, uint16_t buf_offset,
|
||||||
; uint32_t lba,
|
; uint32_t lba,
|
||||||
; uint16_t count, uint16_t drive_num)
|
; uint16_t count, uint16_t drive_num)
|
||||||
call read_disk_raw
|
call BIOS_int13h_ext_read
|
||||||
add sp, 0xC
|
add sp, 0xC
|
||||||
.goto_vbr:
|
.goto_vbr:
|
||||||
cmp word [VBR_ENTRY + 0x1FE], 0xAA55
|
cmp word [VBR_ENTRY + 0x1FE], 0xAA55
|
||||||
je main.sig_ok
|
je main.sig_ok
|
||||||
ERROR MBR_ERROR_NO_VBR_SIG ; no signature present
|
ERROR MBR_ERROR_NO_VBR_SIG ; no signature present
|
||||||
.sig_ok:
|
.sig_ok:
|
||||||
mov ax, PartTable_t_size
|
mov dl, byte [bp - 2] ; pass drive # from BIOS to VBR in dl
|
||||||
push ax
|
|
||||||
mov ax, DiskSig ; start of partition table
|
|
||||||
push ax
|
|
||||||
mov ax, partition_table
|
|
||||||
push ax
|
|
||||||
call kmemcpy ; copy partition table to bss
|
|
||||||
add sp, 0x6
|
|
||||||
|
|
||||||
mov si, word [bp - 4]
|
|
||||||
mov dl, byte [bp - 2]
|
|
||||||
mov bx, partition_table
|
|
||||||
jmp word 0x0000:VBR_ENTRY
|
jmp word 0x0000:VBR_ENTRY
|
||||||
|
|
||||||
; ###############
|
; ###############
|
||||||
@@ -188,18 +169,15 @@ PartEntry4:
|
|||||||
times 16 db 0x00
|
times 16 db 0x00
|
||||||
BootSig:
|
BootSig:
|
||||||
dw 0xAA55 ; Add boot signature at the end of bootloader
|
dw 0xAA55 ; Add boot signature at the end of bootloader
|
||||||
|
; !!! end of MBR !!!
|
||||||
section .bss follows=.text
|
section .bss follows=.text
|
||||||
begin_bss:
|
begin_bss:
|
||||||
|
|
||||||
align 16, resb 1
|
|
||||||
partition_table resb PartTable_t_size
|
|
||||||
|
|
||||||
align 16, resb 1
|
align 16, resb 1
|
||||||
lba_packet resb LBAPkt_t_size
|
lba_packet resb LBAPkt_t_size
|
||||||
|
|
||||||
align 512, resb 1
|
align 512, resb 1
|
||||||
stack_bottom resb 512 ; 512 byte stack early on
|
stack_bottom resb 1024 - 16 ; 512 byte stack early on
|
||||||
stack_top:
|
stack_top:
|
||||||
mbr_redzone resb 32
|
mbr_redzone resb 16
|
||||||
end_bss:
|
end_bss:
|
||||||
@@ -1,22 +1,17 @@
|
|||||||
; Copyright (c) 2023 Elaina Claus
|
; Copyright (C) 2025 Elaina Claus
|
||||||
;
|
;
|
||||||
; Permission is hereby granted, free of charge, to any person obtaining a copy
|
; This program is free software: you can redistribute it and/or modify
|
||||||
; of this software and associated documentation files (the "Software"), to deal
|
; it under the terms of the GNU General Public License as published by
|
||||||
; in the Software without restriction, including without limitation the rights
|
; the Free Software Foundation, either version 3 of the License, or
|
||||||
; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
; (at your option) any later version.
|
||||||
; copies of the Software, and to permit persons to whom the Software is
|
|
||||||
; furnished to do so, subject to the following conditions:
|
|
||||||
;
|
;
|
||||||
; The above copyright notice and this permission notice shall be included in all
|
; This program is distributed in the hope that it will be useful,
|
||||||
; copies or substantial portions of the Software.
|
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
; GNU General Public License for more details.
|
||||||
;
|
;
|
||||||
; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
; You should have received a copy of the GNU General Public License
|
||||||
; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
; along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
; SOFTWARE.
|
|
||||||
|
|
||||||
[BITS 32]
|
[BITS 32]
|
||||||
[ORG 0x100000]
|
[ORG 0x100000]
|
||||||
|
|||||||
@@ -1,27 +1,22 @@
|
|||||||
; Copyright (c) 2023 Elaina Claus
|
; Copyright (C) 2025 Elaina Claus
|
||||||
;
|
;
|
||||||
; Permission is hereby granted, free of charge, to any person obtaining a copy
|
; This program is free software: you can redistribute it and/or modify
|
||||||
; of this software and associated documentation files (the "Software"), to deal
|
; it under the terms of the GNU General Public License as published by
|
||||||
; in the Software without restriction, including without limitation the rights
|
; the Free Software Foundation, either version 3 of the License, or
|
||||||
; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
; (at your option) any later version.
|
||||||
; copies of the Software, and to permit persons to whom the Software is
|
|
||||||
; furnished to do so, subject to the following conditions:
|
|
||||||
;
|
;
|
||||||
; The above copyright notice and this permission notice shall be included in all
|
; This program is distributed in the hope that it will be useful,
|
||||||
; copies or substantial portions of the Software.
|
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
; GNU General Public License for more details.
|
||||||
;
|
;
|
||||||
; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
; You should have received a copy of the GNU General Public License
|
||||||
; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
; along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
; SOFTWARE.
|
|
||||||
|
|
||||||
[BITS 16]
|
[BITS 16]
|
||||||
[ORG 0x0500] ; IF YOU CHANGE ORG CHANGE THE SIGN OFFSET AT THE END
|
[ORG 0x0500] ; IF YOU CHANGE ORG CHANGE THE SIGN OFFSET AT THE END
|
||||||
[CPU KATMAI]
|
[CPU 686]
|
||||||
[map all stage2.map]
|
[map all build/stage2.map]
|
||||||
[WARNING -reloc-abs-byte]
|
[WARNING -reloc-abs-byte]
|
||||||
[WARNING -reloc-abs-word]
|
[WARNING -reloc-abs-word]
|
||||||
[WARNING -reloc-abs-dword] ; Yes, we use absolute addresses. surpress these warnings.
|
[WARNING -reloc-abs-dword] ; Yes, we use absolute addresses. surpress these warnings.
|
||||||
@@ -36,31 +31,15 @@
|
|||||||
%include "cdecl16.inc"
|
%include "cdecl16.inc"
|
||||||
%include "entry.inc"
|
%include "entry.inc"
|
||||||
%include "config.inc"
|
%include "config.inc"
|
||||||
%include "early_mem.inc"
|
|
||||||
%include "error_codes.inc"
|
%include "error_codes.inc"
|
||||||
|
|
||||||
%macro print_string 1
|
|
||||||
mov ax, %1
|
|
||||||
push ax
|
|
||||||
call PrintString
|
|
||||||
add sp, 0x2
|
|
||||||
%endmacro
|
|
||||||
|
|
||||||
section .text
|
section .text
|
||||||
begin_text:
|
begin_text:
|
||||||
; dl = byte boot_drive
|
; dl = byte boot_drive
|
||||||
; ax = word part_offset (active partition offset)
|
ALIGN 16, db 0x90
|
||||||
; si = ptr PartTable_t partition_table
|
|
||||||
; di = ptr FAT32_bpb_t fat32_bpb
|
|
||||||
ALIGN 4, db 0x90
|
|
||||||
init:
|
init:
|
||||||
cli ; We do not want to be interrupted
|
cli ; We do not want to be interrupted
|
||||||
|
mov [u8_BootDrive], dl ; copy boot_drive to globals
|
||||||
; these 4 are stored in the .data section and are effectivly const types
|
|
||||||
mov [vbr_part_table_ptr], si ; pointer to partition_table
|
|
||||||
mov [vbr_fat32_bpb_ptr], di ; pointer to fat32_bpb
|
|
||||||
mov [boot_drive], dl ; copy boot_drive to globals
|
|
||||||
mov [partition_offset], ax ; copy partition_offset to globals
|
|
||||||
|
|
||||||
mov ax, __STAGE2_SEGMENT ; set all our segments to the configured segment, except es
|
mov ax, __STAGE2_SEGMENT ; set all our segments to the configured segment, except es
|
||||||
mov ds, ax ; *
|
mov ds, ax ; *
|
||||||
@@ -93,7 +72,7 @@ init:
|
|||||||
jmp word __STAGE2_SEGMENT:main
|
jmp word __STAGE2_SEGMENT:main
|
||||||
|
|
||||||
; ###############
|
; ###############
|
||||||
; Functions
|
; Core Functions
|
||||||
; ###############
|
; ###############
|
||||||
|
|
||||||
%include "util/kmem_func.nasm"
|
%include "util/kmem_func.nasm"
|
||||||
@@ -101,11 +80,18 @@ init:
|
|||||||
%include "util/kmemset4_func.nasm"
|
%include "util/kmemset4_func.nasm"
|
||||||
%include "util/error_func.nasm"
|
%include "util/error_func.nasm"
|
||||||
|
|
||||||
|
; ###############
|
||||||
|
; Functions
|
||||||
|
; ###############
|
||||||
|
%include "util/arena_alloc.nasm"
|
||||||
|
|
||||||
; ###############
|
; ###############
|
||||||
; FAT32 Driver
|
; FAT32 Driver
|
||||||
; ###############
|
; ###############
|
||||||
|
|
||||||
%include 'fat32/FAT32_SYS.inc'
|
%include "partition_table.inc"
|
||||||
|
%include "fat32/fat32_structures.inc"
|
||||||
|
%include 'fat32/FAT32_SYS.nasm'
|
||||||
|
|
||||||
; ###############
|
; ###############
|
||||||
; BIOS functions
|
; BIOS functions
|
||||||
@@ -116,14 +102,10 @@ init:
|
|||||||
; structures
|
; structures
|
||||||
|
|
||||||
struc SteviaInfoStruct_t
|
struc SteviaInfoStruct_t
|
||||||
.MemoryMapPtr resd 1
|
.p16_E820MemoryMapPtr resw 1
|
||||||
.MemoryMapEntries resd 1
|
.u16_E820MMapEntryCount resw 1
|
||||||
endstruc
|
.p16_MbrPtr resw 1
|
||||||
|
.p16_VbrPtr resw 1
|
||||||
struc EarlyBootStruct_t
|
|
||||||
.partition_table resb PartTable_t_size
|
|
||||||
.fat32_bpb resb FAT32_bpb_t_size
|
|
||||||
.fat32_ebpb resb FAT32_ebpb_t_size
|
|
||||||
endstruc
|
endstruc
|
||||||
|
|
||||||
ALIGN 4, db 0x90
|
ALIGN 4, db 0x90
|
||||||
@@ -135,55 +117,71 @@ main:
|
|||||||
je main.stage2_main
|
je main.stage2_main
|
||||||
ERROR STAGE2_SIGNATURE_MISSING
|
ERROR STAGE2_SIGNATURE_MISSING
|
||||||
.stage2_main:
|
.stage2_main:
|
||||||
mov ax, PartTable_t_size
|
|
||||||
push ax ; len = PartTable_t_size
|
|
||||||
mov ax, word [vbr_part_table_ptr] ; src = ptr to vbr partition_table
|
|
||||||
push ax
|
|
||||||
mov ax, partition_table ; dst
|
|
||||||
push ax
|
|
||||||
call kmemcpy ; copy partition table data to .data section in stage2
|
|
||||||
add sp, 0x6
|
|
||||||
|
|
||||||
mov ax, (FAT32_bpb_t_size + FAT32_ebpb_t_size) ; len
|
|
||||||
push ax
|
|
||||||
mov ax, word [vbr_fat32_bpb_ptr] ; src
|
|
||||||
push ax
|
|
||||||
mov ax, fat32_bpb ; dst
|
|
||||||
push ax
|
|
||||||
call kmemcpy ; copy bpb & ebpb to memory
|
|
||||||
add sp, 0x6
|
|
||||||
|
|
||||||
call SetTextMode
|
call SetTextMode
|
||||||
call disable_cursor
|
call disable_cursor_bios
|
||||||
print_string HelloPrompt_cstr
|
|
||||||
|
; setup the early heap
|
||||||
|
__CDECL16_CALL_ARGS early_heap_state
|
||||||
|
__CDECL16_CALL ArenaInit, 1
|
||||||
|
|
||||||
|
__CDECL16_CALL_ARGS pszHelloPrompt
|
||||||
|
__CDECL16_CALL PrintString, 1
|
||||||
|
|
||||||
|
; setup heap space for mbr data
|
||||||
|
__CDECL16_CALL_ARGS 0x200, 0x10
|
||||||
|
__CDECL16_CALL ArenaAlloc, 2
|
||||||
|
mov word [SteviaInfo + SteviaInfoStruct_t.p16_MbrPtr], ax
|
||||||
|
|
||||||
|
push ax ; dst
|
||||||
|
movzx ax, byte [u8_BootDrive]
|
||||||
|
push ax ; boot_drive
|
||||||
|
__CDECL16_CALL FAT32_load_mbr, 2 ; fill/validate mbr buffer
|
||||||
|
|
||||||
|
; setup heap space for vbr data
|
||||||
|
__CDECL16_CALL_ARGS 0x200, 0x10
|
||||||
|
__CDECL16_CALL ArenaAlloc, 2
|
||||||
|
mov word [SteviaInfo + SteviaInfoStruct_t.p16_VbrPtr], ax
|
||||||
|
|
||||||
|
push ax ; dst
|
||||||
|
movzx ax, byte [u8_BootDrive]
|
||||||
|
push ax ; boot_drive
|
||||||
|
__CDECL16_CALL FAT32_load_vbr, 2 ; fill/validate vbr buffer
|
||||||
|
|
||||||
; enable A20 gate
|
; enable A20 gate
|
||||||
call EnableA20
|
call EnableA20
|
||||||
print_string A20_Enabled_OK_cstr
|
__CDECL16_CALL_ARGS pszA20EnabledOk
|
||||||
|
__CDECL16_CALL PrintString, 1
|
||||||
|
|
||||||
; get system memory map
|
; get system memory map
|
||||||
call GetMemoryMap
|
call GetMemoryMap
|
||||||
print_string MemoryMap_OK_cstr
|
__CDECL16_CALL_ARGS pszMemoryMapOk
|
||||||
|
__CDECL16_CALL PrintString, 1
|
||||||
|
|
||||||
; enter unreal mode
|
; enter unreal mode (enter PM w/ 16 bit code, 32 bit flat memory model & return to real)
|
||||||
|
; ds, es will be set to the 64KiB STAGE2_SEGMENT, fs/gs will be flat/huge memory (4GiB)
|
||||||
|
; use __REFLAT macros to re-flat ds/es for easy transfers to >1MiB
|
||||||
|
; NOTE: if you modify a segment register you will need to re-unreal it
|
||||||
call EnterUnrealMode
|
call EnterUnrealMode
|
||||||
print_string UnrealMode_OK_cstr
|
__CDECL16_CALL_ARGS pszUnrealModeOk
|
||||||
|
__CDECL16_CALL PrintString, 1
|
||||||
|
|
||||||
; FAT Driver setup
|
; FAT Driver setup
|
||||||
call InitFATDriver
|
;call InitFATDriver
|
||||||
print_string InitFATSYS_OK_cstr
|
;__CDECL16_CALL_ARGS pszInitFAT32Ok
|
||||||
|
;__CDECL16_CALL PrintString, 1
|
||||||
|
|
||||||
;
|
;
|
||||||
; Find first cluster of bootable file
|
; Find first cluster of bootable file
|
||||||
call SearchFATDIR
|
;call SearchFATDIR
|
||||||
push dword eax ; save first cluster of bootable file
|
;push dword eax ; save first cluster of bootable file
|
||||||
|
|
||||||
print_string FileFound_OK_cstr
|
;__CDECL16_CALL_ARGS pszFileFoundMsg
|
||||||
|
;__CDECL16_CALL PrintString, 1
|
||||||
|
|
||||||
pop dword eax
|
;pop dword eax
|
||||||
push dword eax ; print Cluster of boot file
|
;push dword eax ; print Cluster of boot file
|
||||||
call PrintDWORD ; void PrintDWORD(uint32_t dword)
|
;call PrintDWORD ; void PrintDWORD(uint32_t dword)
|
||||||
print_string NewLine_cstr
|
;add sp, 0x4
|
||||||
|
|
||||||
; TODO: using first cluster information, start loading the kernel to memory
|
; TODO: using first cluster information, start loading the kernel to memory
|
||||||
; TODO: going to need an elf parser, some unreal mode file buffer functions to move the data
|
; TODO: going to need an elf parser, some unreal mode file buffer functions to move the data
|
||||||
@@ -192,269 +190,181 @@ hcf:
|
|||||||
|
|
||||||
; ##############################
|
; ##############################
|
||||||
;
|
;
|
||||||
; SYSTEM CONFIGURATION FUNCTIONS
|
; SYSTEM CONFIGURATION FUNCTIONS & MACROS
|
||||||
;
|
;
|
||||||
; ##############################
|
; ##############################
|
||||||
|
|
||||||
; Prints a C-Style string (null terminated) using BIOS vga teletype call
|
; set ds and es segments back to the base of the loader
|
||||||
; void PrintString(char* buf)
|
%ifnmacro __TINY_DS_ES
|
||||||
ALIGN 4, db 0x90
|
%macro __TINY_DS_ES 0
|
||||||
PrintString:
|
mov ax, __STAGE2_SEGMENT
|
||||||
__CDECL16_ENTRY
|
mov ds, ax
|
||||||
mov di, [bp + 4] ; first arg is char*
|
mov es, ax
|
||||||
.str_len:
|
%endmacro
|
||||||
xor cx, cx ; ECX = 0
|
%endif
|
||||||
not cx ; ECX = -1 == 0xFFFF
|
|
||||||
xor ax, ax ; search for al = 0x0
|
|
||||||
|
|
||||||
cld
|
; for copying between locations in high memory
|
||||||
repne scasb ; deincrement cx while searching for al
|
%ifnmacro __REFLAT_DS_ES
|
||||||
|
%macro __REFLAT_DS_ES 0
|
||||||
not cx ; the inverse of a neg number = abs(x) - 1
|
|
||||||
dec cx ; CX contains the length of the string - nul byte at end
|
|
||||||
.print:
|
|
||||||
mov si, [bp + 4] ; source string
|
|
||||||
.print_L0:
|
|
||||||
movzx ax, byte [si]
|
|
||||||
push ax
|
|
||||||
call PrintCharacter
|
|
||||||
add sp, 0x2
|
|
||||||
|
|
||||||
inc si
|
|
||||||
dec cx
|
|
||||||
|
|
||||||
jcxz PrintString.endp
|
|
||||||
jmp PrintString.print_L0 ; Fetch next character from string
|
|
||||||
.endp:
|
|
||||||
__CDECL16_EXIT
|
|
||||||
ret ; Return from procedure
|
|
||||||
|
|
||||||
; Prints a single character
|
|
||||||
; void PrintCharacter(char c);
|
|
||||||
ALIGN 4, db 0x90
|
|
||||||
PrintCharacter:
|
|
||||||
__CDECL16_ENTRY
|
|
||||||
.func:
|
|
||||||
mov ax, [bp + 4] ; c
|
|
||||||
mov dx, 0x00ff
|
|
||||||
and ax, dx
|
|
||||||
|
|
||||||
mov ah, 0x0E ; INT 0x10, AH=0x0E call
|
|
||||||
mov bx, 0x0007 ; BH = page no. BL =Text attribute 0x07 is lightgrey font on black background
|
|
||||||
int 0x10 ; call video interrupt
|
|
||||||
.endp:
|
|
||||||
__CDECL16_EXIT
|
|
||||||
ret
|
|
||||||
|
|
||||||
; TODO: fix the prolog, epilog and stack usage to confirm with cdecl16
|
|
||||||
; prints the hex representation of of val
|
|
||||||
; void PrintDWORD(uint32_t val);
|
|
||||||
ALIGN 4, db 0x90
|
|
||||||
PrintDWORD:
|
|
||||||
__CDECL16_ENTRY
|
|
||||||
.func:
|
|
||||||
lea si, [IntToHex_table]
|
|
||||||
mov ebx, 16 ; base-16
|
|
||||||
|
|
||||||
mov eax, dword [bp + 4] ;val
|
|
||||||
|
|
||||||
xor edx, edx
|
|
||||||
xor cx, cx
|
|
||||||
.next_digit:
|
|
||||||
div ebx ; dividend in edx:eax -> quotient in eax, remainder in edx
|
|
||||||
push dx ; save remainder
|
|
||||||
inc cx
|
|
||||||
|
|
||||||
xor dx, dx
|
|
||||||
test eax, eax
|
|
||||||
jnz PrintDWORD.next_digit
|
|
||||||
|
|
||||||
.zero_pad:
|
|
||||||
cmp cx, 0x0008
|
|
||||||
je PrintDWORD.print_stack
|
|
||||||
xor ax, ax
|
|
||||||
push ax
|
|
||||||
inc cx
|
|
||||||
jmp PrintDWORD.zero_pad
|
|
||||||
|
|
||||||
.print_stack:
|
|
||||||
pop bx
|
|
||||||
dec cx
|
|
||||||
push cx
|
|
||||||
|
|
||||||
movzx ax, byte [bx+si+0] ; bx = index into Hex lookup table
|
|
||||||
push ax
|
|
||||||
call PrintCharacter
|
|
||||||
add sp, 0x2
|
|
||||||
|
|
||||||
pop cx
|
|
||||||
|
|
||||||
jcxz PrintDWORD.endp
|
|
||||||
jmp PrintDWORD.print_stack
|
|
||||||
|
|
||||||
.endp:
|
|
||||||
__CDECL16_EXIT
|
|
||||||
ret
|
|
||||||
|
|
||||||
; ##############################
|
|
||||||
;
|
|
||||||
; SYSTEM CONFIGURATION FUNCTIONS
|
|
||||||
;
|
|
||||||
; ##############################
|
|
||||||
ALIGN 4, db 0x90
|
|
||||||
EnterUnrealMode:
|
|
||||||
__CDECL16_ENTRY
|
|
||||||
.func:
|
|
||||||
cli ; no interrupts
|
cli ; no interrupts
|
||||||
push ds ; save real mode data/stack selectors
|
lgdt [((__STAGE2_SEGMENT << 4) + UnrealGdtInfo)] ; load unreal gdt
|
||||||
push es
|
|
||||||
push fs
|
|
||||||
push gs
|
|
||||||
push ss
|
|
||||||
|
|
||||||
push cs ; save real mode code selector
|
|
||||||
xor ax, ax ;
|
|
||||||
pop ax ; save cs to ax to setup far jump
|
|
||||||
mov word [__UNREAL_SEGMENT], ax
|
|
||||||
|
|
||||||
lgdt [((__STAGE2_SEGMENT << 4) + unreal_gdt_info)] ; load unreal gdt
|
|
||||||
|
|
||||||
mov eax, cr0
|
mov eax, cr0
|
||||||
or al,1 ; set pmode bit
|
or eax, 1 ; set pmode bit
|
||||||
mov cr0, eax ; switch to pmode
|
mov cr0, eax ; switch to pmode
|
||||||
jmp short $+2
|
jmp short $+2 ; i-cache flush
|
||||||
|
|
||||||
;jmp far 0x0008:EnterUnrealMode.load_cs
|
mov ax, 0x10 ; select descriptor 2
|
||||||
db 0xEA ; jmp far imm16:imm16
|
mov ds, ax
|
||||||
dw EnterUnrealMode.load_cs ; error_far_ptr
|
mov es, ax
|
||||||
dw 0x0008 ; error_far_seg
|
|
||||||
.load_cs:
|
|
||||||
mov bx, 0x10 ; select descriptor 2
|
|
||||||
mov ds, bx ; 10h = 0001_0000b
|
|
||||||
|
|
||||||
mov ss, bx
|
mov eax, cr0
|
||||||
mov es, bx
|
and eax, ~1 ; toggle bit 1 of cr0
|
||||||
mov fs, bx
|
|
||||||
mov gs, bx ; other data/stack to index 2 (off 0x10)
|
|
||||||
|
|
||||||
and al,0xFE ; toggle bit 1 of cr0
|
|
||||||
mov cr0, eax ; back to realmode
|
mov cr0, eax ; back to realmode
|
||||||
jmp short $+2
|
jmp short $+2 ; i-cache flush
|
||||||
|
|
||||||
;jmp far 0x0008:EnterUnrealMode.unload_cs
|
|
||||||
db 0xEA ; jmp far imm16:imm16
|
|
||||||
dw EnterUnrealMode.unload_cs ; error_far_ptr
|
|
||||||
__UNREAL_SEGMENT:
|
|
||||||
dw 0x0000 ; error_far_seg
|
|
||||||
EnterUnrealMode.unload_cs:
|
|
||||||
pop ss
|
|
||||||
pop gs
|
|
||||||
pop fs
|
|
||||||
pop es
|
|
||||||
pop ds ; get back old segments
|
|
||||||
sti
|
sti
|
||||||
|
|
||||||
|
%endmacro
|
||||||
|
%endif
|
||||||
|
|
||||||
|
; for copying from low memory to high memory (ds on a real segment, es in flat mode)
|
||||||
|
%ifnmacro __REFLAT_ES
|
||||||
|
%macro __REFLAT_ES 0
|
||||||
|
cli ; no interrupts
|
||||||
|
lgdt [((__STAGE2_SEGMENT << 4) + UnrealGdtInfo)] ; load unreal gdt
|
||||||
|
|
||||||
|
mov eax, cr0
|
||||||
|
or eax, 1 ; set pmode bit
|
||||||
|
mov cr0, eax ; switch to pmode
|
||||||
|
jmp short $+2 ; i-cache flush
|
||||||
|
|
||||||
|
mov ax, 0x10 ; select descriptor 2
|
||||||
|
mov es, ax
|
||||||
|
|
||||||
|
mov eax, cr0
|
||||||
|
and eax, ~1 ; toggle bit 1 of cr0
|
||||||
|
mov cr0, eax ; back to realmode
|
||||||
|
jmp short $+2 ; i-cache flush
|
||||||
|
sti
|
||||||
|
|
||||||
|
%endmacro
|
||||||
|
%endif
|
||||||
|
|
||||||
|
ALIGN 4, db 0x90
|
||||||
|
EnterUnrealMode:
|
||||||
|
__CDECL16_PROC_ENTRY
|
||||||
|
cli ; no interrupts
|
||||||
|
.proc:
|
||||||
|
lgdt [((__STAGE2_SEGMENT << 4) + UnrealGdtInfo)] ; load unreal gdt
|
||||||
|
|
||||||
|
mov eax, cr0
|
||||||
|
or eax, 1 ; set pmode bit
|
||||||
|
mov cr0, eax ; switch to pmode
|
||||||
|
|
||||||
|
; set cs to a pm code segment (0x8) w/ the following
|
||||||
|
jmp 0x0008:EnterUnrealMode.set_segs
|
||||||
|
.set_segs:
|
||||||
|
mov ax, 0x10 ; select descriptor 2
|
||||||
|
mov ds, ax ; 10h = 0001_0000b
|
||||||
|
mov es, ax ; es to big data
|
||||||
|
|
||||||
|
mov fs, ax
|
||||||
|
mov gs, ax ; extra segments to big data as well
|
||||||
|
.pm_start:
|
||||||
|
; code here is running in protected mode w/ descriptor 0x8
|
||||||
|
; insert any PM test code needed here
|
||||||
|
.pm_end:
|
||||||
|
mov eax, cr0
|
||||||
|
and eax, ~1 ; toggle bit 1 of cr0
|
||||||
|
mov cr0, eax ; back to realmode
|
||||||
|
jmp __STAGE2_SEGMENT:EnterUnrealMode.endp
|
||||||
.endp:
|
.endp:
|
||||||
__CDECL16_EXIT
|
sti ; re-enable interupts
|
||||||
|
|
||||||
|
; set ds, es to the STAGE2_SEGMENT, for our model (generally) ds == es == cs
|
||||||
|
; fs, gs & ss are all still huge data model, and the macro(s) "__REFLAT_xxx" exists
|
||||||
|
; to easily access data outside of 64KiB boundries using ds/es addressing
|
||||||
|
__TINY_DS_ES
|
||||||
|
|
||||||
|
__CDECL16_PROC_EXIT
|
||||||
ret
|
ret
|
||||||
end_text:
|
end_text:
|
||||||
|
|
||||||
section .data follows=.text
|
section .data follows=.text
|
||||||
align 512
|
align 16, db 0
|
||||||
|
|
||||||
begin_data:
|
begin_data:
|
||||||
; #############
|
; #############
|
||||||
;
|
;
|
||||||
; Strings
|
; Strings
|
||||||
;
|
;
|
||||||
; #############
|
; #############
|
||||||
|
%define CRLF 0Dh, 0Ah
|
||||||
|
|
||||||
%macro define_str 2
|
%macro define_cstr 2-*
|
||||||
ALIGN 16
|
%if %0 > 2
|
||||||
%1_str:
|
align 16
|
||||||
db %2
|
%1:
|
||||||
%define str_len %strlen(%2) ; string
|
db %{2:-1}, 00h
|
||||||
%1_str_len:
|
%else
|
||||||
dd str_len
|
align 16
|
||||||
|
%1:
|
||||||
|
db %2, 00h
|
||||||
|
%endif
|
||||||
%endmacro
|
%endmacro
|
||||||
|
|
||||||
; TODO: technically this is a cstr but it splices a return and newline on the end
|
define_cstr pszHelloPrompt, "Hello from Stevia Stage2!", CRLF
|
||||||
; TODO: this probably should be seperated out and the printing functionality should
|
define_cstr pszA20EnabledOk, "A20 Enabled OK", CRLF
|
||||||
; TODO: place that newline and return
|
define_cstr pszMemoryMapOk, "Memory map OK", CRLF
|
||||||
%macro define_cstr 2
|
define_cstr pszUnrealModeOk, "Unreal mode OK", CRLF
|
||||||
%define CRLF_NUL 0Dh, 0Ah, 00h
|
define_cstr pszInitFAT32Ok, "FAT32 Driver Init OK", CRLF
|
||||||
ALIGN 16
|
|
||||||
%1_cstr:
|
|
||||||
db %2, CRLF_NUL
|
|
||||||
%endmacro
|
|
||||||
|
|
||||||
define_cstr HelloPrompt, "Hello from Stevia Stage2!"
|
define_cstr pszFileFoundMsg, "Found SFN entry for bootable binary, first cluster -> ", CRLF
|
||||||
define_cstr A20_Enabled_OK, "A20 Enabled OK"
|
define_cstr pszSearchFAT32DirMsg, "Searching FAT fs for bootable file...", CRLF
|
||||||
define_cstr MemoryMap_OK, "Memory map OK"
|
define_cstr pszReadFAT32ClusterMsg, "Attempting to load next FAT", CRLF
|
||||||
define_cstr UnrealMode_OK, "Unreal mode OK"
|
define_cstr pszMaybeFoundBootMsg, "Maybe found a file...checking...", CRLF
|
||||||
define_cstr FileFound_OK, "Found SFN entry for bootable binary, first cluster -> "
|
|
||||||
define_cstr InitFATSYS_OK, "FAT32 Driver Init..."
|
|
||||||
|
|
||||||
define_cstr SearchFATDIR_INFO, "Searching FAT DIR for bootable file..."
|
define_cstr BootTarget, "BOOT BIN"
|
||||||
define_cstr NextFATCluster_INFO, "Attempting to find next FAT cluster..."
|
|
||||||
define_cstr ReadFATCluster_INFO, "Attempting to load next FAT"
|
|
||||||
define_cstr MaybeFound_Boot_INFO, "Maybe found a file...checking..."
|
|
||||||
define_cstr NewLine, ""
|
|
||||||
|
|
||||||
define_str BootTarget, "BOOT BIN"
|
; set to boot_drive passed from BIOS almost first thing in init
|
||||||
|
align 4, db 0
|
||||||
;
|
u8_BootDrive:
|
||||||
; pre-bss init globals (generally const...but there are exceptions)
|
|
||||||
;
|
|
||||||
|
|
||||||
align 8, db 0x00
|
|
||||||
boot_drive:
|
|
||||||
db 0x00
|
db 0x00
|
||||||
|
|
||||||
align 8, db 0x00
|
align 16, db 0
|
||||||
partition_offset:
|
|
||||||
dw 0x0000
|
|
||||||
|
|
||||||
align 8, db 0x00
|
|
||||||
vbr_fat32_bpb_ptr:
|
|
||||||
dw 0x0000
|
|
||||||
|
|
||||||
align 8, db 0x00
|
|
||||||
vbr_part_table_ptr:
|
|
||||||
dw 0x0000
|
|
||||||
|
|
||||||
ALIGN 16
|
|
||||||
IntToHex_table:
|
IntToHex_table:
|
||||||
db '0123456789ABCDEF'
|
db '0123456789ABCDEF'
|
||||||
|
|
||||||
; see docs/gdt.txt for a quick refresher on GDT
|
; see docs/gdt.txt for a quick refresher on GDT
|
||||||
ALIGN 16, db 0
|
align 16, db 0
|
||||||
unreal_gdt_info:
|
UnrealGdtInfo:
|
||||||
unreal_gdt_size: dw (unreal_gdt_end - unreal_gdt_start) - 1
|
u16_UnrealGdt_size: dw (UnrealGdtEnd - UnrealGdtStart) - 1
|
||||||
unreal_gdt_ptr: dd ((__STAGE2_SEGMENT << 4) + unreal_gdt_start)
|
pF_UnrealGdtPtr: dd ((__STAGE2_SEGMENT << 4) + UnrealGdtStart)
|
||||||
unreal_gdt_start:
|
UnrealGdtStart:
|
||||||
; entry 0 (null descriptor)
|
; entry 0 (null descriptor)
|
||||||
dq 0 ; first entry is null
|
dq 0 ; first entry is null
|
||||||
|
|
||||||
; entry 1 (16bit code 64KiB limit)
|
; entry 1 (0x8) (16bit code 64KiB limit)
|
||||||
dd 0x0000FFFF ; Base Address(15:0) 31:16, Segment Limit(15:0) 15:0
|
dd 0x0000FFFF ; Base Address(15:0) 31:16, Segment Limit(15:0) 15:0
|
||||||
db 0x00 ; Base Address 23:16
|
db 0x00 ; Base Address 23:16
|
||||||
db 1001_1010b ; Access Byte: Present, ring0, S = 1, executable (1), non-conforming, readable, Accessed
|
db 1001_1010b ; Access Byte: Present, ring0, S = 1, executable (1), non-conforming, readable, Accessed
|
||||||
db 0000_0000b ; Flags: GR = 4KiB, attr = <DB/L/Avl>, Granularity = 4KiB & 16:19 of limit
|
db 0000_0000b ; Flags: GR = 4KiB, attr = <DB/L/Avl>, Granularity = 4KiB & 16:19 of limit
|
||||||
db 0x00 ; Base Address 31:24
|
db 0x00 ; Base Address 31:24
|
||||||
|
|
||||||
; entry 2 (16bit data segment with 4 GiB flat mapping)
|
; entry 2 (0x10) (16bit data segment with 4 GiB flat mapping)
|
||||||
dd 0x0000FFFF ; Base Address(15:0) 31:16, Segment Limit(15:0) 15:0
|
dd 0x0000FFFF ; Base Address(15:0) 31:16, Segment Limit(15:0) 15:0
|
||||||
db 0x00 ; Base Address(23:16)
|
db 0x00 ; Base Address(23:16)
|
||||||
db 1001_0010b ; Access Byte: Present, ring0, S = 1, data (0), non-confirming, writable, present
|
db 1001_0010b ; Access Byte: Present, ring0, S = 1, data (0), non-confirming, writable, present
|
||||||
db 1000_1111b ; Flags: GR = 4KiB, attr = <16-bit/?/?>, Granularity = 4KiB & 16:19 of limit
|
db 1000_1111b ; Flags: GR = 4KiB, attr = <16-bit/?/?>, Granularity = 4KiB & 16:19 of limit
|
||||||
db 0x00 ; Base Address(31:24)
|
db 0x00 ; Base Address(31:24)
|
||||||
unreal_gdt_end:
|
UnrealGdtEnd:
|
||||||
|
|
||||||
ALIGN 16, db 0
|
align 16, db 0
|
||||||
gdt32_info:
|
Gdt32Info:
|
||||||
gdt32_size: dw (gdt32_end - gdt32_start) - 1
|
gdt32_size: dw (Gdt32End - Gdt32Start) - 1
|
||||||
gdt32_ptr: dd ((__STAGE2_SEGMENT << 4) + gdt32_start)
|
gdt32_ptr: dd ((__STAGE2_SEGMENT << 4) + Gdt32Start)
|
||||||
gdt32_start:
|
Gdt32Start:
|
||||||
dq 0
|
dq 0 ; null segment
|
||||||
.gdt32_code:
|
.gdt32_code:
|
||||||
dw 0xFFFF ; code segment (RX)
|
dw 0xFFFF ; code segment (RX)
|
||||||
dw 0x0000
|
dw 0x0000
|
||||||
@@ -483,82 +393,79 @@ gdt32_start:
|
|||||||
db 1001_0000b ; Access: readable, not writable
|
db 1001_0000b ; Access: readable, not writable
|
||||||
db 1100_1111b ; 4KB granularity, 32-bit
|
db 1100_1111b ; 4KB granularity, 32-bit
|
||||||
db 0x00
|
db 0x00
|
||||||
gdt32_end:
|
Gdt32End:
|
||||||
|
|
||||||
ALIGN 8,db 0x00
|
align 16,db 0
|
||||||
BUILD_NASM_VER:
|
BuildNasmVer:
|
||||||
db "Stevia Stage2 built with NASM - ", __NASM_VER__, 00h
|
db "Stevia Stage2 built with NASM - ", __NASM_VER__, 00h
|
||||||
|
|
||||||
ALIGN 8,db 0x00
|
align 16,db 0
|
||||||
BUILD_DATETIME:
|
BuildDateTime:
|
||||||
db 'Assembled - ', __DATE__, ' ', __TIME__, 00h
|
db 'Assembled - ', __DATE__, ' ', __TIME__, 00h
|
||||||
|
|
||||||
ALIGN 8,db 0x00
|
align 16,db 0
|
||||||
BUILD_GIT_VER:
|
BuildGitVer:
|
||||||
db __GIT_VER__, 00h
|
db __GIT_VER__, 00h
|
||||||
|
|
||||||
ALIGN 8,db 0x00
|
align 16,db 0
|
||||||
BUILD_GIT_HASH:
|
BuildGitHash:
|
||||||
db __GIT_HASH__, 00h
|
db __GIT_HASH__, 00h
|
||||||
end_data:
|
end_data:
|
||||||
|
|
||||||
%assign bytes_remaining ((MAX_STAGE2_BYTES - 4) - (($ - $$) + (end_text - begin_text)))
|
%define SIG_BYTES 0x4
|
||||||
%warning STAGE2 has bytes_remaining bytes remaining for code/data (MAX: MAX_STAGE2_BYTES)
|
|
||||||
|
; Optional: fail fast if we overflowed
|
||||||
|
%if ((MAX_STAGE2_BYTES - 512) - (($ - $$) + (end_text - begin_text))) < 0
|
||||||
|
%error "Stage2 overflow: code+data exceed MAX_STAGE2_BYTES - SIG_BYTES"
|
||||||
|
%endif
|
||||||
|
|
||||||
; section start location needs to be a 'critical expression'
|
; section start location needs to be a 'critical expression'
|
||||||
; i.e resolvable at build time, we are setting 0x7E00 as the offset since
|
; i.e resolvable at build time, we are setting 0x0500 as the offset since
|
||||||
section .sign start=((MAX_STAGE2_BYTES - 512) + 0x0500)
|
section .sign start=((MAX_STAGE2_BYTES - 512) + 0x0500)
|
||||||
times ((512 - 4) - ($ -$$) ) db 0x90 ; nop
|
times ((512 - 4) - ($ -$$) ) db 0x90 ; nop
|
||||||
STAGE2_SIG: dd 0xDEADBEEF ; Signature to mark the end of the stage2
|
STAGE2_SIG: dd 0xDEADBEEF ; Signature to mark the end of the stage2
|
||||||
|
; !!! END Stage2 .text/.data !!!
|
||||||
|
align 16, resb 1
|
||||||
section .bss follows=.sign
|
section .bss follows=.sign
|
||||||
begin_bss:
|
begin_bss:
|
||||||
|
|
||||||
; structures
|
; structures
|
||||||
|
align 16, resb 1
|
||||||
align 8, resb 1
|
|
||||||
partition_table resb PartTable_t_size
|
|
||||||
|
|
||||||
align 8, resb 1
|
|
||||||
fat32_bpb resb FAT32_bpb_t_size
|
|
||||||
fat32_ebpb resb FAT32_ebpb_t_size
|
|
||||||
|
|
||||||
align 8, resb 1
|
|
||||||
fat32_nc_data resb 16
|
|
||||||
|
|
||||||
align 8, resb 1
|
|
||||||
lba_packet resb LBAPkt_t_size
|
|
||||||
|
|
||||||
align 8, resb 1
|
|
||||||
fat32_state:
|
|
||||||
resb FAT32_State_t_size
|
|
||||||
|
|
||||||
align 8, resb 1
|
|
||||||
SteviaInfo:
|
SteviaInfo:
|
||||||
resd 4
|
resd SteviaInfoStruct_t_size
|
||||||
;
|
|
||||||
; post-bss init globals
|
align 16, resb 1
|
||||||
;
|
early_heap_state:
|
||||||
|
resb ArenaStateStruc_t_size
|
||||||
|
|
||||||
|
align 16, resb 1
|
||||||
|
lba_packet:
|
||||||
|
resb LBAPkt_t_size
|
||||||
|
|
||||||
;
|
;
|
||||||
; large continuous allocations
|
; large continuous allocations
|
||||||
;
|
;
|
||||||
align 16, resb 1
|
|
||||||
disk_buffer:
|
|
||||||
resb 512
|
|
||||||
fat_buffer:
|
|
||||||
resb 512
|
|
||||||
dir_buffer:
|
|
||||||
resb 512
|
|
||||||
fat_fsinfo:
|
|
||||||
resb 512
|
|
||||||
|
|
||||||
|
; TODO: this will hold 42 entries from the map function
|
||||||
|
; the e820 function needs to check that it doesn't overflow
|
||||||
|
; but realisticly 42 entries is enough for dev work
|
||||||
align 16, resb 1
|
align 16, resb 1
|
||||||
%define BIOSMemoryMap_SIZE 2048
|
%define BIOSMemoryMap_SIZE 1024
|
||||||
BIOSMemoryMap:
|
BIOSMemoryMap:
|
||||||
resb 2048
|
resb BIOSMemoryMap_SIZE
|
||||||
|
|
||||||
align 512, resb 1
|
|
||||||
stack_bottom:
|
|
||||||
resb 1024
|
|
||||||
stack_top:
|
|
||||||
end_bss:
|
end_bss:
|
||||||
|
; !!! End bss data !!!
|
||||||
|
%define STACK_SIZE 0x1000 ; 4 KiB
|
||||||
|
|
||||||
|
; Pad to the cap (emits nothing in the file; only increases .bss virtual size).
|
||||||
|
; If BSS_SIZE > BSS_MAX_BYTES, this becomes negative and NASM errors out.
|
||||||
|
%define BSS_MAX_BYTES (0x2000 - STACK_SIZE)
|
||||||
|
resb (BSS_MAX_BYTES - (end_bss - begin_bss))
|
||||||
|
|
||||||
|
align 16, resb 1
|
||||||
|
stack_bottom:
|
||||||
|
resb STACK_SIZE
|
||||||
|
stack_top:
|
||||||
|
|
||||||
|
; Optional: keep a label for later math:
|
||||||
|
bss_cap_end:
|
||||||
109
src/vbr/vbr.nasm
109
src/vbr/vbr.nasm
@@ -1,39 +1,41 @@
|
|||||||
; Copyright (c) 2023 Elaina Claus
|
; Copyright (C) 2025 Elaina Claus
|
||||||
;
|
;
|
||||||
; Permission is hereby granted, free of charge, to any person obtaining a copy
|
; This program is free software: you can redistribute it and/or modify
|
||||||
; of this software and associated documentation files (the "Software"), to deal
|
; it under the terms of the GNU General Public License as published by
|
||||||
; in the Software without restriction, including without limitation the rights
|
; the Free Software Foundation, either version 3 of the License, or
|
||||||
; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
; (at your option) any later version.
|
||||||
; copies of the Software, and to permit persons to whom the Software is
|
|
||||||
; furnished to do so, subject to the following conditions:
|
|
||||||
;
|
;
|
||||||
; The above copyright notice and this permission notice shall be included in all
|
; This program is distributed in the hope that it will be useful,
|
||||||
; copies or substantial portions of the Software.
|
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
; GNU General Public License for more details.
|
||||||
;
|
;
|
||||||
; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
; You should have received a copy of the GNU General Public License
|
||||||
; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
; along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
; SOFTWARE.
|
|
||||||
[BITS 16]
|
[BITS 16]
|
||||||
[ORG 0x7C00]
|
[ORG 0x7C00]
|
||||||
[CPU KATMAI]
|
[CPU KATMAI]
|
||||||
[WARNING -reloc-abs-byte]
|
[WARNING -reloc-abs-byte]
|
||||||
[WARNING -reloc-abs-word]
|
[WARNING -reloc-abs-word]
|
||||||
[map all vbr.map] ; Yes, we use absolute addresses. surpress these warnings.
|
[map all build/vbr.map] ; Yes, we use absolute addresses. surpress these warnings.
|
||||||
%define __STEVIA_VBR
|
%define __STEVIA_VBR
|
||||||
section .text
|
section .text
|
||||||
__ENTRY:
|
__ENTRY:
|
||||||
|
; try to force encode a short jmp nop: i.e 0xEB 0x5A 0x90
|
||||||
|
; will jump right 0x5A (90 bytes) after the end of the ebpb
|
||||||
|
; this could also be encoded as 0xE9 0x?? 0x?? for a near jump
|
||||||
|
; if init ends up being >= 128 bytes from entry.
|
||||||
jmp short (init - $$)
|
jmp short (init - $$)
|
||||||
nop
|
nop
|
||||||
|
|
||||||
; fill BPB area with 0x00 since we skip writing this part to disk
|
; 8 ascii bytes, "MSWIN 4.1", ""
|
||||||
; but we need it for the 'jmp short entry; nop' above
|
phy_bs_ident:
|
||||||
times 33 db 0x00
|
times 8 db 0x00
|
||||||
|
|
||||||
|
phy_bpb_start:
|
||||||
|
times 25 db 0x00
|
||||||
|
|
||||||
phy_ebpb_start:
|
phy_ebpb_start:
|
||||||
; fill eBPB area with 0x00 since we skip writing this part to disk
|
|
||||||
times 54 db 0x00
|
times 54 db 0x00
|
||||||
|
|
||||||
; ###############
|
; ###############
|
||||||
@@ -46,7 +48,6 @@ times 54 db 0x00
|
|||||||
%include "cdecl16.inc"
|
%include "cdecl16.inc"
|
||||||
%include "entry.inc"
|
%include "entry.inc"
|
||||||
%include "config.inc"
|
%include "config.inc"
|
||||||
%include "early_mem.inc"
|
|
||||||
%include "error_codes.inc"
|
%include "error_codes.inc"
|
||||||
%include "partition_table.inc"
|
%include "partition_table.inc"
|
||||||
%include "fat32/fat32_structures.inc"
|
%include "fat32/fat32_structures.inc"
|
||||||
@@ -77,7 +78,7 @@ init:
|
|||||||
cld
|
cld
|
||||||
rep stosb
|
rep stosb
|
||||||
|
|
||||||
sub sp, 0x20 ; local varible space
|
sub sp, 0x10 ; local varible space (32 bytes)
|
||||||
push bp
|
push bp
|
||||||
|
|
||||||
sti ; all done with inital setup and relocation, reenable interupts
|
sti ; all done with inital setup and relocation, reenable interupts
|
||||||
@@ -91,10 +92,6 @@ init:
|
|||||||
%include "util/kmem_func.nasm"
|
%include "util/kmem_func.nasm"
|
||||||
%include "util/error_func.nasm"
|
%include "util/error_func.nasm"
|
||||||
|
|
||||||
; ###############
|
|
||||||
; End Section
|
|
||||||
; ###############
|
|
||||||
|
|
||||||
;
|
;
|
||||||
; byte boot_drive @ bp - 2
|
; byte boot_drive @ bp - 2
|
||||||
; word part_offset @ bp - 4
|
; word part_offset @ bp - 4
|
||||||
@@ -102,60 +99,31 @@ init:
|
|||||||
ALIGN 4, db 0x90
|
ALIGN 4, db 0x90
|
||||||
main:
|
main:
|
||||||
mov byte [bp - 2], dl ; boot_drive
|
mov byte [bp - 2], dl ; boot_drive
|
||||||
mov word [bp - 4], si ; part_offset
|
|
||||||
mov word [bp - 6], bx ; partition_table
|
|
||||||
|
|
||||||
.load_fs_data:
|
|
||||||
mov ax, PartTable_t_size ; count=
|
|
||||||
push ax
|
|
||||||
mov ax, [bp - 6] ; src= ptr partition_table
|
|
||||||
push ax
|
|
||||||
mov ax, partition_table ; dst=
|
|
||||||
push ax
|
|
||||||
call kmemcpy ; copy partition table data
|
|
||||||
add sp, 0x6
|
|
||||||
|
|
||||||
mov ax, (FAT32_bpb_t_size + FAT32_ebpb_t_size) ; size in byte, should be 90 bytes
|
|
||||||
push ax
|
|
||||||
mov ax, __ENTRY
|
|
||||||
push ax
|
|
||||||
mov ax, fat32_bpb ;
|
|
||||||
push ax
|
|
||||||
call kmemcpy ; copy bpb & ebpb to memory
|
|
||||||
add sp, 0x6
|
|
||||||
|
|
||||||
.check_FAT_size: ; we only support a very specific setup of FAT32
|
.check_FAT_size: ; we only support a very specific setup of FAT32
|
||||||
mov bx, fat32_bpb
|
mov bx, phy_bpb_start
|
||||||
cmp dword [bx + FAT32_bpb_t.sector_count_32], 0 ; SectorsHuge will not be set if FAT12/16
|
test word [bx + FAT32_bpb_t.u16_TotalSectors16], 0 ; TotSectors16 will not be set if FAT32
|
||||||
ja main.load_stage2
|
jz main.load_stage2
|
||||||
ERROR VBR_ERROR_WRONG_FAT_SIZE
|
ERROR VBR_ERROR_WRONG_FAT_SIZE
|
||||||
.load_stage2:
|
.load_stage2:
|
||||||
; read sectors 1-(MAX_STAGE2_BYTES / 512) to stage2 entry point
|
; read sectors 1-(MAX_STAGE2_BYTES / 512) to stage2 entry point
|
||||||
movzx ax, byte [bp - 2]
|
movzx ax, byte [bp - 2]
|
||||||
push ax ; drive_num
|
push ax ; drive_num
|
||||||
|
|
||||||
mov ax, STAGE2_SECTOR_COUNT
|
push STAGE2_SECTOR_COUNT ; count
|
||||||
push ax ; count
|
|
||||||
|
|
||||||
mov dword eax, 0x1
|
mov dword eax, 0x1
|
||||||
push dword eax ; lba
|
push dword eax ; lba
|
||||||
|
|
||||||
mov ax, STAGE2_ENTRY
|
push STAGE2_ENTRY ; offset
|
||||||
push ax ; offset
|
push 0x00 ; segment = 0
|
||||||
|
|
||||||
xor ax, ax
|
|
||||||
push ax ; segment = 0
|
|
||||||
|
|
||||||
; uint8_t read_stage2_raw(uint16_t buf_segment, uint16_t buf_offset,
|
; uint8_t read_stage2_raw(uint16_t buf_segment, uint16_t buf_offset,
|
||||||
; uint32_t lba,
|
; uint32_t lba,
|
||||||
; uint16_t count, uint16_t drive_num)
|
; uint16_t count, uint16_t drive_num)
|
||||||
call read_disk_raw
|
call BIOS_int13h_ext_read
|
||||||
add sp, 0xC
|
add sp, 0xC
|
||||||
.enter_stage2:
|
.enter_stage2:
|
||||||
mov dl, byte [bp - 2] ; byte boot_drive
|
mov dl, byte [bp - 2] ; byte boot_drive
|
||||||
mov ax, word [bp - 4] ; word part_offset
|
|
||||||
mov si, partition_table ; ptr partition_table
|
|
||||||
mov di, fat32_bpb ; ptr fat32_bpb
|
|
||||||
jmp word 0x0000:STAGE2_ENTRY
|
jmp word 0x0000:STAGE2_ENTRY
|
||||||
|
|
||||||
; ###############
|
; ###############
|
||||||
@@ -171,25 +139,16 @@ times (510 - ($ - $$)) nop ; Fill the rest of sector with nop
|
|||||||
|
|
||||||
BootSig:
|
BootSig:
|
||||||
dw 0xAA55 ; Add boot signature at the end of bootloader
|
dw 0xAA55 ; Add boot signature at the end of bootloader
|
||||||
|
; !!! END VBR !!!
|
||||||
|
|
||||||
section .bss follows=.text
|
section .bss follows=.text
|
||||||
begin_bss:
|
begin_bss:
|
||||||
|
|
||||||
align 16, resb 1
|
|
||||||
partition_table resb PartTable_t_size
|
|
||||||
|
|
||||||
align 16, resb 1
|
|
||||||
fat32_bpb resb FAT32_bpb_t_size
|
|
||||||
fat32_ebpb resb FAT32_ebpb_t_size
|
|
||||||
|
|
||||||
align 16, resb 1
|
|
||||||
fat32_nc_data resb 16
|
|
||||||
|
|
||||||
align 16, resb 1
|
align 16, resb 1
|
||||||
lba_packet resb LBAPkt_t_size
|
lba_packet resb LBAPkt_t_size
|
||||||
|
|
||||||
align 512, resb 1
|
align 512, resb 1
|
||||||
stack_bottom resb 512 ; 512b stack early on
|
stack_bottom resb (1024 - 16) ; 512b stack early on
|
||||||
stack_top:
|
stack_top:
|
||||||
vbr_redzone resb 32
|
vbr_redzone resb 16
|
||||||
end_bss:
|
end_bss:
|
||||||
Reference in New Issue
Block a user