Skip to content

Commit

Permalink
Merge pull request #2 from o8vm/change-to-newasm
Browse files Browse the repository at this point in the history
fix the issue #1
  • Loading branch information
o8vm authored Jan 23, 2021
2 parents a404ff7 + bac1e86 commit 60c12a1
Show file tree
Hide file tree
Showing 9 changed files with 36 additions and 48 deletions.
3 changes: 3 additions & 0 deletions .cargo/config → .cargo/config.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
[unstable]
build-std = ["core", "compiler_builtins", "alloc"]

[build]
target = "i586-rust_dos.json"
rustflags = ["-C", "link-arg=-Tlink.x"]
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ edition = "2018"
opt-level = "z"

[dependencies]
rlibc = "1.0.0"
32 changes: 18 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,37 +4,41 @@ It is possible to create a DOS executable or 1st stage bootloader with Rust.
This is a quick demo of creating COM executable for DOS.

## Building
You need a nightly Rust compiler and binutils. First you need to install the [cargo-xbuild](https://github.com/rust-osdev/cargo-xbuild) and [cargo-binutils](https://github.com/rust-embedded/cargo-binutils):
You need a binutils and llvm-tools-preview.

```shell
cargo install cargo-xbuild
cargo install cargo-binutils
rustup component add llvm-tools-preview
```

Then you can build the project by running:

```shell
cargo xbuild --release
cargo build --release
```

To create a COM executable for DOS, run:

```shell
cargo objcopy -- -I elf32-i386 -O binary --binary-architecture=i386:x86 \
target/i586-rust_dos/release/rust_dos target/i586-rust_dos/release/rust_dos.com
cargo objcopy --release -O binary --binary-architecture=i386:x86 rust_dos.com
```

## Running
You can copy `rust_dos.com` to your DOS image.
You can copy `rust_dos.com` to your DOS image.

examples on macOS:
examples on Linux

```shell
$ hdiutil attach path/to/freedos.img
/dev/disk2 FDisk_partition_scheme
/dev/disk2s1 DOS_FAT_16 /Volumes/FREEDOS2016
$ cp target/i586-rust_dos/release/rust_dos.com /Volumes/FREEDOS2016/
$ sudo partx -av freedos.img
partition: none, disk: freedos.img, lower: 0, upper: 0
Trying to use '/dev/loop1' for the loop device
/dev/loop1: partition table type 'dos' detected
range recount: max partno=1, lower=0, upper=0
/dev/loop1: partition #1 added
$ sudo mount /dev/loop1p1 /mnt
$ sudo cp rust_dos.com /mnt/
$ sudo umount /mnt
$ sudo partx -dv /dev/loop1
```

Then, you can test it using QEMU:
Expand All @@ -43,13 +47,13 @@ Then, you can test it using QEMU:
qemu-system-i386 freedos.img -boot c
```

You can use the `println!` macro.
You can use the `println!` macro.
Below is an example of HelloWorld:

![sample](https://github.com/ellbrid/rust_dos/blob/images/rust_dos_hello.png)
![sample](https://github.com/o8vm/rust_dos/blob/images/rust_dos_hello.png)

### Others
dpkey module steals key input processing from DOS and converts scan code to ascii code.
about scan code: see [PS/2 Keyboard - OSDev Wiki](https://wiki.osdev.org/PS/2_Keyboard).

![sample2](https://github.com/ellbrid/rust_dos/blob/images/dpkey.gif)
![sample2](https://github.com/o8vm/rust_dos/blob/images/dpkey.gif)
2 changes: 1 addition & 1 deletion i586-rust_dos.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,4 @@
"vendor": "unknown",
"panic-strategy": "abort",
"disable-redzone": true
}
}
3 changes: 2 additions & 1 deletion link.x
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ SECTIONS {
.data : { *(.data) } > dos
.bss : { *(.bss) } > dos
.stack : { *(.stack) } > dos
}
/DISCARD/ : { *(.eh_frame*) }
}
9 changes: 3 additions & 6 deletions src/dos.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,8 @@ pub mod kbc;

pub fn exit(rt: u8) -> ! {
unsafe {
asm!("mov $$0x4C, %ah
int $$0x21"
:
: "{al}"(rt)
: "eax");
asm!("mov ah, 0x4C",
"int 0x21", in("al") rt);
}
loop {}
}
}
8 changes: 2 additions & 6 deletions src/dos/console.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,6 @@ impl Write for DosWriter {

fn printc(ch: u8) {
unsafe {
asm!("mov $$0x2, %ah
int $$0x21"
:
: "{dl}"(ch)
: "eax", "edx");
asm!("int 0x21", in("ah") 0x02_u8, in("dl") ch)
}
}
}
24 changes: 5 additions & 19 deletions src/dos/io.rs
Original file line number Diff line number Diff line change
@@ -1,41 +1,27 @@
pub fn inb(port: usize) -> u8 {
let mut ret: u8;
unsafe {
asm!("xorl %eax, %eax
inb %dx, %al"
: "={al}"(ret)
: "{dx}"(port)
);
asm!("in al, dx", out("al") ret, in("dx") port);
}
ret
}

pub fn inw(port: usize) -> u16 {
let mut ret: u16;
unsafe {
asm!("xorl %eax, %eax
inw %dx, %ax"
: "={ax}"(ret)
: "{dx}"(port)
);
asm!("in ax, dx", out("ax") ret, in("dx") port)
}
ret
}

pub fn outb(data: u8, port: usize) {
unsafe {
asm!("outb %al, %dx"
:
: "{al}"(data), "{dx}"(port)
);
asm!("out dx, al", in("dx") port, in("al") data);
}
}

pub fn outw(data: u16, port: usize) {
unsafe {
asm!("outw %ax, %dx"
:
: "{ax}"(data), "{dx}"(port)
);
asm!("out dx, ax", in("dx") port, in("ax") data);
}
}
}
2 changes: 1 addition & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ fn main() {
println!("Hello, World!");
// println!("Hit any Key, please.");
// dpkey::keymap();
}
}

0 comments on commit 60c12a1

Please # to comment.