Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
rcore-os
RCore Tutorial V3
提交
1c4d488a
R
RCore Tutorial V3
项目概览
rcore-os
/
RCore Tutorial V3
上一次同步 1 年多
通知
15
Star
793
Fork
260
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
4
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
RCore Tutorial V3
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
4
Issue
4
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
1c4d488a
编写于
1月 13, 2023
作者:
Y
Yifan Wu
1
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
updates from ch9
上级
b2627812
变更
23
隐藏空白更改
内联
并排
Showing
23 changed file
with
350 addition
and
409 deletion
+350
-409
os/Cargo.toml
os/Cargo.toml
+1
-3
os/src/drivers/chardev/ns16550a.rs
os/src/drivers/chardev/ns16550a.rs
+3
-2
os/src/drivers/input/mod.rs
os/src/drivers/input/mod.rs
+2
-41
os/src/fs/pipe.rs
os/src/fs/pipe.rs
+1
-1
os/src/main.rs
os/src/main.rs
+0
-3
os/src/mm/address.rs
os/src/mm/address.rs
+0
-1
os/src/mm/frame_allocator.rs
os/src/mm/frame_allocator.rs
+1
-8
os/src/mm/memory_set.rs
os/src/mm/memory_set.rs
+11
-17
os/src/mm/mod.rs
os/src/mm/mod.rs
+2
-2
os/src/syscall/fs.rs
os/src/syscall/fs.rs
+1
-1
os/src/syscall/gui.rs
os/src/syscall/gui.rs
+14
-17
os/src/syscall/input.rs
os/src/syscall/input.rs
+8
-9
os/src/syscall/mod.rs
os/src/syscall/mod.rs
+4
-4
user/Cargo.toml
user/Cargo.toml
+2
-0
user/src/bin/gui_rect.rs
user/src/bin/gui_rect.rs
+4
-63
user/src/bin/gui_simple.rs
user/src/bin/gui_simple.rs
+12
-16
user/src/bin/gui_snake.rs
user/src/bin/gui_snake.rs
+2
-55
user/src/bin/inputdev_event.rs
user/src/bin/inputdev_event.rs
+12
-8
user/src/file.rs
user/src/file.rs
+30
-0
user/src/io.rs
user/src/io.rs
+118
-0
user/src/lib.rs
user/src/lib.rs
+8
-158
user/src/sync.rs
user/src/sync.rs
+32
-0
user/src/task.rs
user/src/task.rs
+82
-0
未找到文件。
os/Cargo.toml
浏览文件 @
1c4d488a
...
...
@@ -13,10 +13,8 @@ buddy_system_allocator = "0.6"
bitflags
=
"1.2.1"
xmas-elf
=
"0.7.0"
volatile
=
"0.3"
#virtio-drivers = { git = "https://github.com/rcore-os/virtio-drivers", rev = "4ee80e5" }
virtio-drivers
=
{
git
=
"https://github.com/rcore-os/virtio-drivers"
,
rev
=
"70b5850"
}
virtio-drivers
=
{
git
=
"https://github.com/rcore-os/virtio-drivers"
,
rev
=
"4ee80e5"
}
easy-fs
=
{
path
=
"../easy-fs"
}
#virtio-input-decoder = "0.1.4"
embedded-graphics
=
"0.7.1"
tinybmp
=
"0.3.1"
...
...
os/src/drivers/chardev/ns16550a.rs
浏览文件 @
1c4d488a
...
...
@@ -143,12 +143,13 @@ impl<const BASE_ADDR: usize> NS16550a<BASE_ADDR> {
}
pub
fn
read_buffer_is_empty
(
&
self
)
->
bool
{
self
.inner
.exclusive_session
(|
inner
|
inner
.read_buffer
.is_empty
())
self
.inner
.exclusive_session
(|
inner
|
inner
.read_buffer
.is_empty
())
}
}
impl
<
const
BASE_ADDR
:
usize
>
CharDevice
for
NS16550a
<
BASE_ADDR
>
{
fn
init
(
&
self
){
fn
init
(
&
self
)
{
let
mut
inner
=
self
.inner
.exclusive_access
();
inner
.ns16550a
.init
();
drop
(
inner
);
...
...
os/src/drivers/input/mod.rs
浏览文件 @
1c4d488a
...
...
@@ -16,41 +16,20 @@ struct VirtIOInputInner {
struct
VirtIOInputWrapper
{
inner
:
UPIntrFreeCell
<
VirtIOInputInner
>
,
//condvars: BTreeMap<u16, Condvar>,
//condvar: Arc::<Condvar> ,
condvar
:
Condvar
,
condvar
:
Condvar
,
}
pub
trait
InputDevice
:
Send
+
Sync
+
Any
{
fn
read_event
(
&
self
)
->
u64
;
fn
handle_irq
(
&
self
);
// fn events(&self) -> &VecDeque<u64>;
fn
is_empty
(
&
self
)
->
bool
;
}
lazy_static
::
lazy_static!
(
pub
static
ref
KEYBOARD_DEVICE
:
Arc
<
dyn
InputDevice
>
=
Arc
::
new
(
VirtIOInputWrapper
::
new
(
VIRTIO5
));
pub
static
ref
MOUSE_DEVICE
:
Arc
<
dyn
InputDevice
>
=
Arc
::
new
(
VirtIOInputWrapper
::
new
(
VIRTIO6
));
// pub static ref INPUT_CONDVAR: Arc::<Condvar> = Arc::new(Condvar::new());
);
// from virtio-drivers/src/input.rs
//const QUEUE_SIZE: u16 = 32;
// pub fn read_input_event() -> u64 {
// loop {
// //let mut inner = self.inner.exclusive_access();
// let kb=KEYBOARD_DEVICE.clone();
// let evs = kb.events();
// if let Some(event) = evs.pop_front() {
// return event;
// } else {
// let task_cx_ptr = INPUT_CONDVAR.clone().wait_no_sched();
// drop(inner);
// schedule(task_cx_ptr);
// }
// }
// }
impl
VirtIOInputWrapper
{
pub
fn
new
(
addr
:
usize
)
->
Self
{
let
inner
=
VirtIOInputInner
{
...
...
@@ -59,17 +38,8 @@ impl VirtIOInputWrapper {
},
events
:
VecDeque
::
new
(),
};
// let mut condvars = BTreeMap::new();
// let channels = QUEUE_SIZE;
// for i in 0..channels {
// let condvar = Condvar::new();
// condvars.insert(i, condvar);
// }
Self
{
inner
:
unsafe
{
UPIntrFreeCell
::
new
(
inner
)
},
//condvar: INPUT_CONDVAR.clone(),
condvar
:
Condvar
::
new
(),
}
}
...
...
@@ -93,29 +63,20 @@ impl InputDevice for VirtIOInputWrapper {
}
}
// fn events(&self) -> &VecDeque<u64> {
// &self.inner.exclusive_access().events
// }
fn
handle_irq
(
&
self
)
{
let
mut
count
=
0
;
let
mut
result
=
0
;
let
mut
key
=
0
;
self
.inner
.exclusive_session
(|
inner
|
{
inner
.virtio_input
.ack_interrupt
();
while
let
Some
(
(
token
,
event
)
)
=
inner
.virtio_input
.pop_pending_event
()
{
while
let
Some
(
event
)
=
inner
.virtio_input
.pop_pending_event
()
{
count
+=
1
;
key
=
token
;
result
=
(
event
.event_type
as
u64
)
<<
48
|
(
event
.code
as
u64
)
<<
32
|
(
event
.value
)
as
u64
;
inner
.events
.push_back
(
result
);
// for test
//println!("[KERN] inputdev_handle_irq: event: {:x}", result);
}
});
if
count
>
0
{
//self.condvars.get(&key).unwrap().signal();
self
.condvar
.signal
();
};
}
...
...
os/src/fs/pipe.rs
浏览文件 @
1c4d488a
...
...
@@ -170,4 +170,4 @@ impl File for Pipe {
}
}
}
}
\ No newline at end of file
}
os/src/main.rs
浏览文件 @
1c4d488a
...
...
@@ -29,7 +29,6 @@ mod trap;
use
crate
::
drivers
::
chardev
::
CharDevice
;
use
crate
::
drivers
::
chardev
::
UART
;
//use syscall::create_desktop; //for test
core
::
arch
::
global_asm!
(
include_str!
(
"entry.asm"
));
...
...
@@ -59,7 +58,6 @@ pub fn rust_main() -> ! {
UART
.init
();
println!
(
"KERN: init gpu"
);
let
_
gpu
=
GPU_DEVICE
.clone
();
//let _input_condvar = INPUT_CONDVAR.clone();
println!
(
"KERN: init keyboard"
);
let
_
keyboard
=
KEYBOARD_DEVICE
.clone
();
println!
(
"KERN: init mouse"
);
...
...
@@ -70,7 +68,6 @@ pub fn rust_main() -> ! {
timer
::
set_next_trigger
();
board
::
device_init
();
fs
::
list_apps
();
//gui::init_paint();
task
::
add_initproc
();
*
DEV_NON_BLOCKING_ACCESS
.exclusive_access
()
=
true
;
task
::
run_tasks
();
...
...
os/src/mm/address.rs
浏览文件 @
1c4d488a
...
...
@@ -260,4 +260,3 @@ where
}
}
pub
type
VPNRange
=
SimpleRange
<
VirtPageNum
>
;
pub
type
PPNRange
=
SimpleRange
<
PhysPageNum
>
;
os/src/mm/frame_allocator.rs
浏览文件 @
1c4d488a
...
...
@@ -7,7 +7,6 @@ use lazy_static::*;
pub
struct
FrameTracker
{
pub
ppn
:
PhysPageNum
,
pub
nodrop
:
bool
,
}
impl
FrameTracker
{
...
...
@@ -17,10 +16,7 @@ impl FrameTracker {
for
i
in
bytes_array
{
*
i
=
0
;
}
Self
{
ppn
,
nodrop
:
false
}
}
pub
fn
new_noalloc
(
ppn
:
PhysPageNum
)
->
Self
{
Self
{
ppn
,
nodrop
:
true
}
Self
{
ppn
}
}
}
...
...
@@ -32,9 +28,6 @@ impl Debug for FrameTracker {
impl
Drop
for
FrameTracker
{
fn
drop
(
&
mut
self
)
{
if
self
.nodrop
{
return
;
}
frame_dealloc
(
self
.ppn
);
}
}
...
...
os/src/mm/memory_set.rs
浏览文件 @
1c4d488a
use
super
::{
frame_alloc
,
FrameTracker
};
use
super
::{
PTEFlags
,
PageTable
,
PageTableEntry
};
use
super
::{
PhysAddr
,
PhysPageNum
,
VirtAddr
,
VirtPageNum
};
use
super
::{
StepByOne
,
VPNRange
,
PPNRange
};
use
super
::{
StepByOne
,
VPNRange
};
use
crate
::
config
::{
MEMORY_END
,
MMIO
,
PAGE_SIZE
,
TRAMPOLINE
};
use
crate
::
sync
::
UPIntrFreeCell
;
use
alloc
::
collections
::
BTreeMap
;
...
...
@@ -71,17 +71,16 @@ impl MemorySet {
self
.areas
.remove
(
idx
);
}
}
fn
push
(
&
mut
self
,
mut
map_area
:
MapArea
,
data
:
Option
<&
[
u8
]
>
)
{
/// Add a new MapArea into this MemorySet.
/// Assuming that there are no conflicts in the virtual address
/// space.
pub
fn
push
(
&
mut
self
,
mut
map_area
:
MapArea
,
data
:
Option
<&
[
u8
]
>
)
{
map_area
.map
(
&
mut
self
.page_table
);
if
let
Some
(
data
)
=
data
{
map_area
.copy_data
(
&
mut
self
.page_table
,
data
);
}
self
.areas
.push
(
map_area
);
}
pub
fn
push_noalloc
(
&
mut
self
,
mut
map_area
:
MapArea
,
ppn_range
:
PPNRange
)
{
map_area
.map_noalloc
(
&
mut
self
.page_table
,
ppn_range
);
self
.areas
.push
(
map_area
);
}
/// Mention that trampoline is not collected by areas.
fn
map_trampoline
(
&
mut
self
)
{
self
.page_table
.map
(
...
...
@@ -290,8 +289,10 @@ impl MapArea {
ppn
=
frame
.ppn
;
self
.data_frames
.insert
(
vpn
,
frame
);
}
MapType
::
Noalloc
=>
{
panic!
(
"Noalloc should not be mapped"
);
MapType
::
Linear
(
pn_offset
)
=>
{
// check for sv39
assert
!
(
vpn
.0
<
(
1u
size
<<
27
));
ppn
=
PhysPageNum
((
vpn
.0
as
isize
+
pn_offset
)
as
usize
);
}
}
let
pte_flags
=
PTEFlags
::
from_bits
(
self
.map_perm.bits
)
.unwrap
();
...
...
@@ -308,14 +309,6 @@ impl MapArea {
self
.map_one
(
page_table
,
vpn
);
}
}
pub
fn
map_noalloc
(
&
mut
self
,
page_table
:
&
mut
PageTable
,
ppn_range
:
PPNRange
)
{
for
(
vpn
,
ppn
)
in
core
::
iter
::
zip
(
self
.vpn_range
,
ppn_range
)
{
self
.data_frames
.insert
(
vpn
,
FrameTracker
::
new_noalloc
(
ppn
));
let
pte_flags
=
PTEFlags
::
from_bits
(
self
.map_perm.bits
)
.unwrap
();
page_table
.map
(
vpn
,
ppn
,
pte_flags
);
}
}
pub
fn
unmap
(
&
mut
self
,
page_table
:
&
mut
PageTable
)
{
for
vpn
in
self
.vpn_range
{
self
.unmap_one
(
page_table
,
vpn
);
...
...
@@ -349,7 +342,8 @@ impl MapArea {
pub
enum
MapType
{
Identical
,
Framed
,
Noalloc
,
/// offset of page num
Linear
(
isize
),
}
bitflags!
{
...
...
os/src/mm/mod.rs
浏览文件 @
1c4d488a
...
...
@@ -4,11 +4,11 @@ mod heap_allocator;
mod
memory_set
;
mod
page_table
;
pub
use
address
::
{
VPNRange
,
PPNRange
}
;
pub
use
address
::
VPNRange
;
pub
use
address
::{
PhysAddr
,
PhysPageNum
,
StepByOne
,
VirtAddr
,
VirtPageNum
};
pub
use
frame_allocator
::{
frame_alloc
,
frame_dealloc
,
FrameTracker
};
pub
use
memory_set
::
remap_test
;
pub
use
memory_set
::{
kernel_token
,
Map
Permission
,
MemorySet
,
MapArea
,
MapType
,
KERNEL_SPACE
};
pub
use
memory_set
::{
kernel_token
,
Map
Area
,
MapPermission
,
MapType
,
MemorySet
,
KERNEL_SPACE
};
use
page_table
::
PTEFlags
;
pub
use
page_table
::{
translated_byte_buffer
,
translated_ref
,
translated_refmut
,
translated_str
,
PageTable
,
...
...
os/src/syscall/fs.rs
浏览文件 @
1c4d488a
...
...
@@ -96,4 +96,4 @@ pub fn sys_dup(fd: usize) -> isize {
let
new_fd
=
inner
.alloc_fd
();
inner
.fd_table
[
new_fd
]
=
Some
(
Arc
::
clone
(
inner
.fd_table
[
fd
]
.as_ref
()
.unwrap
()));
new_fd
as
isize
}
\ No newline at end of file
}
os/src/syscall/gui.rs
浏览文件 @
1c4d488a
use
crate
::
mm
::{
MapArea
,
MapPermission
,
MapType
,
PPNRange
,
PhysAddr
};
use
crate
::
task
::
current_process
;
//use crate::gui::*;
use
crate
::
drivers
::
GPU_DEVICE
;
use
crate
::
mm
::{
MapArea
,
MapPermission
,
MapType
,
PhysAddr
,
VirtAddr
};
use
crate
::
task
::
current_process
;
const
FB_VADDR
:
usize
=
0x10000000
;
pub
fn
sys_framebuffer
()
->
isize
{
let
gpu
=
GPU_DEVICE
.clone
();
let
fb
=
gpu
.get_framebuffer
();
let
fb
=
GPU_DEVICE
.get_framebuffer
();
let
len
=
fb
.len
();
println!
(
"[kernel] FrameBuffer: addr 0x{:X}, len {}"
,
fb
.as_ptr
()
as
usize
,
len
);
let
fb_ppn
=
PhysAddr
::
from
(
fb
.as_ptr
()
as
usize
)
.floor
();
let
fb_end_ppn
=
PhysAddr
::
from
(
fb
.as_ptr
()
as
usize
+
len
)
.ceil
();
// println!("[kernel] FrameBuffer: addr 0x{:X}, len {}", fb.as_ptr() as usize , len);
let
fb_start_pa
=
PhysAddr
::
from
(
fb
.as_ptr
()
as
usize
);
assert
!
(
fb_start_pa
.aligned
());
let
fb_start_ppn
=
fb_start_pa
.floor
();
let
fb_start_vpn
=
VirtAddr
::
from
(
FB_VADDR
)
.floor
();
let
pn_offset
=
fb_start_ppn
.0
as
isize
-
fb_start_vpn
.0
as
isize
;
let
current_process
=
current_process
();
let
mut
inner
=
current_process
.inner_exclusive_access
();
let
mem_set
=
&
mut
inner
.memory_set
;
mem_set
.push_noalloc
(
inner
.memory_set
.push
(
MapArea
::
new
(
(
FB_VADDR
as
usize
)
.into
(),
(
FB_VADDR
+
len
as
usize
)
.into
(),
MapType
::
Noalloc
,
MapType
::
Linear
(
pn_offset
)
,
MapPermission
::
R
|
MapPermission
::
W
|
MapPermission
::
U
,
),
PPNRange
::
new
(
fb_ppn
,
fb_end_ppn
)
,
None
,
);
FB_VADDR
as
isize
}
pub
fn
sys_framebuffer_flush
()
->
isize
{
let
gpu
=
GPU_DEVICE
.clone
();
gpu
.flush
();
GPU_DEVICE
.flush
();
0
}
\ No newline at end of file
}
os/src/syscall/input.rs
浏览文件 @
1c4d488a
//use crate::drivers::{KEYBOARD_DEVICE,MOUSE_DEVICE,INPUT_CONDVAR,read_input_event};
use
crate
::
drivers
::{
KEYBOARD_DEVICE
,
MOUSE_DEVICE
};
use
crate
::
drivers
::{
KEYBOARD_DEVICE
,
MOUSE_DEVICE
};
pub
fn
sys_event_get
()
->
isize
{
pub
fn
sys_event_get
()
->
isize
{
let
kb
=
KEYBOARD_DEVICE
.clone
();
let
mouse
=
MOUSE_DEVICE
.clone
();
//let input=INPUT_CONDVAR.clone();
//read_input_event() as isize
if
!
kb
.is_empty
(){
if
!
kb
.is_empty
()
{
kb
.read_event
()
as
isize
}
else
if
!
mouse
.is_empty
()
{
}
else
if
!
mouse
.is_empty
()
{
mouse
.read_event
()
as
isize
}
else
{
0
}
}
use
crate
::
drivers
::
chardev
::
UART
;
/// check UART's read-buffer is empty or not
pub
fn
sys_key_pressed
()
->
isize
{
let
res
=!
UART
.read_buffer_is_empty
();
pub
fn
sys_key_pressed
()
->
isize
{
let
res
=
!
UART
.read_buffer_is_empty
();
if
res
{
1
}
else
{
0
}
}
\ No newline at end of file
}
}
os/src/syscall/mod.rs
浏览文件 @
1c4d488a
...
...
@@ -31,18 +31,18 @@ const SYSCALL_EVENT_GET: usize = 3000;
const
SYSCALL_KEY_PRESSED
:
usize
=
3001
;
mod
fs
;
mod
gui
;
mod
input
;
mod
process
;
mod
sync
;
mod
thread
;
mod
gui
;
mod
input
;
use
fs
::
*
;
use
gui
::
*
;
use
input
::
*
;
use
process
::
*
;
use
sync
::
*
;
use
thread
::
*
;
use
gui
::
*
;
use
input
::
*
;
pub
fn
syscall
(
syscall_id
:
usize
,
args
:
[
usize
;
3
])
->
isize
{
match
syscall_id
{
...
...
user/Cargo.toml
浏览文件 @
1c4d488a
...
...
@@ -12,5 +12,7 @@ bitflags = "1.2.1"
riscv
=
{
git
=
"https://github.com/rcore-os/riscv"
,
features
=
["inline-asm"]
}
embedded-graphics
=
"0.7.1"
oorandom
=
"11"
virtio-input-decoder
=
"0.1.4"
[profile.release]
debug
=
true
\ No newline at end of file
user/src/bin/gui_rect.rs
浏览文件 @
1c4d488a
#![no_std]
#![no_main]
#[macro_use]
extern
crate
user_lib
;
extern
crate
alloc
;
use
user_lib
::{
framebuffer
,
framebuffer_flush
};
use
user_lib
::{
VIRTGPU_XRES
,
VIRTGPU_YRES
,
Display
};
use
embedded_graphics
::
pixelcolor
::
Rgb888
;
use
embedded_graphics
::
prelude
::{
Drawable
,
Point
,
RgbColor
,
Size
};
use
embedded_graphics
::
primitives
::
Primitive
;
use
embedded_graphics
::
primitives
::{
PrimitiveStyle
,
Rectangle
};
use
embedded_graphics
::{
draw_target
::
DrawTarget
,
prelude
::
OriginDimensions
};
pub
const
VIRTGPU_XRES
:
usize
=
1280
;
pub
const
VIRTGPU_YRES
:
usize
=
800
;
pub
const
VIRTGPU_LEN
:
usize
=
VIRTGPU_XRES
*
VIRTGPU_YRES
*
4
;
use
embedded_graphics
::
prelude
::{
DrawTarget
,
Drawable
,
Point
,
RgbColor
,
Size
};
use
embedded_graphics
::
primitives
::{
Primitive
,
PrimitiveStyle
,
Rectangle
};
const
INIT_X
:
i32
=
640
;
const
INIT_Y
:
i32
=
400
;
const
RECT_SIZE
:
u32
=
40
;
pub
struct
Display
{
pub
size
:
Size
,
pub
point
:
Point
,
//pub fb: Arc<&'static mut [u8]>,
pub
fb
:
&
'static
mut
[
u8
],
}
impl
Display
{
pub
fn
new
(
size
:
Size
,
point
:
Point
)
->
Self
{
let
fb_ptr
=
framebuffer
()
as
*
mut
u8
;
println!
(
"Hello world from user mode program! 0x{:X} , len {}"
,
fb_ptr
as
usize
,
VIRTGPU_LEN
);
let
fb
=
unsafe
{
core
::
slice
::
from_raw_parts_mut
(
fb_ptr
as
*
mut
u8
,
VIRTGPU_LEN
as
usize
)
};
Self
{
size
,
point
,
fb
}
}
}
impl
OriginDimensions
for
Display
{
fn
size
(
&
self
)
->
Size
{
self
.size
}
}
impl
DrawTarget
for
Display
{
type
Color
=
Rgb888
;
type
Error
=
core
::
convert
::
Infallible
;
fn
draw_iter
<
I
>
(
&
mut
self
,
pixels
:
I
)
->
Result
<
(),
Self
::
Error
>
where
I
:
IntoIterator
<
Item
=
embedded_graphics
::
Pixel
<
Self
::
Color
>>
,
{
pixels
.into_iter
()
.for_each
(|
px
|
{
let
idx
=
((
self
.point.y
+
px
.0
.y
)
*
VIRTGPU_XRES
as
i32
+
self
.point.x
+
px
.0
.x
)
as
usize
*
4
;
if
idx
+
2
>=
self
.fb
.len
()
{
return
;
}
self
.fb
[
idx
]
=
px
.1
.b
();
self
.fb
[
idx
+
1
]
=
px
.1
.g
();
self
.fb
[
idx
+
2
]
=
px
.1
.r
();
});
framebuffer_flush
();
Ok
(())
}
}
pub
struct
DrawingBoard
{
disp
:
Display
,
latest_pos
:
Point
,
...
...
@@ -80,7 +22,7 @@ pub struct DrawingBoard {
impl
DrawingBoard
{
pub
fn
new
()
->
Self
{
Self
{
disp
:
Display
::
new
(
Size
::
new
(
1280
,
800
),
Point
::
new
(
0
,
0
)),
disp
:
Display
::
new
(
Size
::
new
(
VIRTGPU_XRES
,
VIRTGPU_YRES
)),
latest_pos
:
Point
::
new
(
INIT_X
,
INIT_Y
),
}
}
...
...
@@ -106,7 +48,6 @@ impl DrawingBoard {
#[no_mangle]
pub
fn
main
()
->
i32
{
// let fb_ptr = framebuffer() as *mut u8;
let
mut
board
=
DrawingBoard
::
new
();
let
_
=
board
.disp
.clear
(
Rgb888
::
BLACK
)
.unwrap
();
for
i
in
0
..
20
{
...
...
user/src/bin/gui_simple.rs
浏览文件 @
1c4d488a
#![no_std]
#![no_main]
#[macro_use]
extern
crate
user_lib
;
use
user_lib
::{
framebuffer
,
framebuffer_flush
};
pub
const
VIRTGPU_XRES
:
usize
=
1280
;
pub
const
VIRTGPU_YRES
:
usize
=
800
;
use
user_lib
::{
VIRTGPU_XRES
,
VIRTGPU_YRES
,
Display
};
use
embedded_graphics
::
prelude
::
Size
;
#[no_mangle]
pub
fn
main
()
->
i32
{
let
fb_ptr
=
framebuffer
()
as
*
mut
u8
;
println!
(
"Hello world from user mode program! 0x{:X} , len {}"
,
fb_ptr
as
usize
,
VIRTGPU_XRES
*
VIRTGPU_YRES
*
4
);
let
fb
=
unsafe
{
core
::
slice
::
from_raw_parts_mut
(
fb_ptr
as
*
mut
u8
,
VIRTGPU_XRES
*
VIRTGPU_YRES
*
4
as
usize
)};
for
y
in
0
..
800
{
for
x
in
0
..
1280
{
let
idx
=
(
y
*
1280
+
x
)
*
4
;
fb
[
idx
]
=
x
as
u8
;
fb
[
idx
+
1
]
=
y
as
u8
;
fb
[
idx
+
2
]
=
(
x
+
y
)
as
u8
;
let
mut
disp
=
Display
::
new
(
Size
::
new
(
VIRTGPU_XRES
,
VIRTGPU_YRES
))
;
disp
.paint_on_framebuffer
(|
fb
|
{
for
y
in
0
..
VIRTGPU_YRES
as
usize
{
for
x
in
0
..
VIRTGPU_XRES
as
usize
{
let
idx
=
(
y
*
VIRTGPU_XRES
as
usize
+
x
)
*
4
;
fb
[
idx
]
=
x
as
u8
;
fb
[
idx
+
1
]
=
y
as
u8
;
fb
[
idx
+
2
]
=
(
x
+
y
)
as
u8
;
}
}
}
framebuffer_flush
();
});
0
}
user/src/bin/gui_snake.rs
浏览文件 @
1c4d488a
#![no_std]
#![no_main]
#[macro_use]
extern
crate
user_lib
;
extern
crate
alloc
;
use
user_lib
::
console
::
getchar
;
use
user_lib
::{
framebuffer
,
framebuffer_flush
,
key_pressed
,
sleep
};
use
user_lib
::{
Display
,
key_pressed
,
sleep
,
VIRTGPU_XRES
,
VIRTGPU_YRES
};
use
embedded_graphics
::
pixelcolor
::
*
;
use
embedded_graphics
::
prelude
::{
Drawable
,
Point
,
RgbColor
,
Size
};
...
...
@@ -16,58 +15,6 @@ use embedded_graphics::Pixel;
use
embedded_graphics
::{
draw_target
::
DrawTarget
,
prelude
::
OriginDimensions
};
use
oorandom
;
//random generator
pub
const
VIRTGPU_XRES
:
usize
=
1280
;
pub
const
VIRTGPU_YRES
:
usize
=
800
;
pub
const
VIRTGPU_LEN
:
usize
=
VIRTGPU_XRES
*
VIRTGPU_YRES
*
4
;
pub
struct
Display
{
pub
size
:
Size
,
pub
point
:
Point
,
pub
fb
:
&
'static
mut
[
u8
],
}
impl
Display
{
pub
fn
new
(
size
:
Size
,
point
:
Point
)
->
Self
{
let
fb_ptr
=
framebuffer
()
as
*
mut
u8
;
println!
(
"Hello world from user mode program! 0x{:X} , len {}"
,
fb_ptr
as
usize
,
VIRTGPU_LEN
);
let
fb
=
unsafe
{
core
::
slice
::
from_raw_parts_mut
(
fb_ptr
as
*
mut
u8
,
VIRTGPU_LEN
as
usize
)
};
Self
{
size
,
point
,
fb
}
}
}
impl
OriginDimensions
for
Display
{
fn
size
(
&
self
)
->
Size
{
self
.size
}
}
impl
DrawTarget
for
Display
{
type
Color
=
Rgb888
;
type
Error
=
core
::
convert
::
Infallible
;
fn
draw_iter
<
I
>
(
&
mut
self
,
pixels
:
I
)
->
Result
<
(),
Self
::
Error
>
where
I
:
IntoIterator
<
Item
=
embedded_graphics
::
Pixel
<
Self
::
Color
>>
,
{
pixels
.into_iter
()
.for_each
(|
px
|
{
let
idx
=
((
self
.point.y
+
px
.0
.y
)
*
VIRTGPU_XRES
as
i32
+
self
.point.x
+
px
.0
.x
)
as
usize
*
4
;
if
idx
+
2
>=
self
.fb
.len
()
{
return
;
}
self
.fb
[
idx
]
=
px
.1
.b
();
self
.fb
[
idx
+
1
]
=
px
.1
.g
();
self
.fb
[
idx
+
2
]
=
px
.1
.r
();
});
framebuffer_flush
();
Ok
(())
}
}
struct
Snake
<
T
:
PixelColor
,
const
MAX_SIZE
:
usize
>
{
parts
:
[
Pixel
<
T
>
;
MAX_SIZE
],
len
:
usize
,
...
...
@@ -380,7 +327,7 @@ const LF: u8 = 0x0au8;
const
CR
:
u8
=
0x0du8
;
#[no_mangle]
pub
fn
main
()
->
i32
{
let
mut
disp
=
Display
::
new
(
Size
::
new
(
1280
,
800
),
Point
::
new
(
0
,
0
));
let
mut
disp
=
Display
::
new
(
Size
::
new
(
VIRTGPU_XRES
,
VIRTGPU_YRES
));
let
mut
game
=
SnakeGame
::
<
20
,
Rgb888
>
::
new
(
1280
,
800
,
20
,
20
,
Rgb888
::
RED
,
Rgb888
::
YELLOW
,
50
);
let
_
=
disp
.clear
(
Rgb888
::
BLACK
)
.unwrap
();
loop
{
...
...
user/src/bin/inputdev_event.rs
浏览文件 @
1c4d488a
#![no_std]
#![no_main]
use
user_lib
::{
event_get
};
use
user_lib
::{
event_get
,
DecodeType
,
Key
,
KeyType
};
#[macro_use]
extern
crate
user_lib
;
...
...
@@ -9,13 +9,17 @@ extern crate user_lib;
#[no_mangle]
pub
fn
main
()
->
i32
{
println!
(
"Input device event test"
);
let
mut
event
=
0
;
for
_
in
0
..
3
{
while
event
==
0
{
event
=
event_get
();
}
println!
(
"event: {:?}"
,
event
);
loop
{
if
let
Some
(
event
)
=
event_get
()
{
if
let
Some
(
decoder_type
)
=
event
.decode
()
{
println!
(
"{:?}"
,
decoder_type
);
if
let
DecodeType
::
Key
(
key
,
keytype
)
=
decoder_type
{
if
key
==
Key
::
Enter
&&
keytype
==
KeyType
::
Press
{
break
;
}
}
}
}
}
0
}
\ No newline at end of file
user/src/file.rs
0 → 100644
浏览文件 @
1c4d488a
use
super
::
*
;
bitflags!
{
pub
struct
OpenFlags
:
u32
{
const
RDONLY
=
0
;
const
WRONLY
=
1
<<
0
;
const
RDWR
=
1
<<
1
;
const
CREATE
=
1
<<
9
;
const
TRUNC
=
1
<<
10
;
}
}
pub
fn
dup
(
fd
:
usize
)
->
isize
{
sys_dup
(
fd
)
}
pub
fn
open
(
path
:
&
str
,
flags
:
OpenFlags
)
->
isize
{
sys_open
(
path
,
flags
.bits
)
}
pub
fn
close
(
fd
:
usize
)
->
isize
{
sys_close
(
fd
)
}
pub
fn
pipe
(
pipe_fd
:
&
mut
[
usize
])
->
isize
{
sys_pipe
(
pipe_fd
)
}
pub
fn
read
(
fd
:
usize
,
buf
:
&
mut
[
u8
])
->
isize
{
sys_read
(
fd
,
buf
)
}
pub
fn
write
(
fd
:
usize
,
buf
:
&
[
u8
])
->
isize
{
sys_write
(
fd
,
buf
)
}
\ No newline at end of file
user/src/io.rs
0 → 100644
浏览文件 @
1c4d488a
use
super
::
*
;
use
embedded_graphics
::
prelude
::{
RgbColor
,
Size
};
use
embedded_graphics
::{
draw_target
::
DrawTarget
,
prelude
::
OriginDimensions
};
use
embedded_graphics
::
pixelcolor
::
Rgb888
;
use
virtio_input_decoder
::
Decoder
;
pub
use
virtio_input_decoder
::{
DecodeType
,
Key
,
KeyType
,
Mouse
};
pub
const
VIRTGPU_XRES
:
u32
=
1280
;
pub
const
VIRTGPU_YRES
:
u32
=
800
;
pub
const
VIRTGPU_LEN
:
usize
=
(
VIRTGPU_XRES
*
VIRTGPU_YRES
*
4
)
as
usize
;
pub
fn
framebuffer
()
->
isize
{
sys_framebuffer
()
}
pub
fn
framebuffer_flush
()
->
isize
{
sys_framebuffer_flush
()
}
pub
struct
Display
{
pub
size
:
Size
,
pub
fb
:
&
'static
mut
[
u8
],
}
impl
Display
{
pub
fn
new
(
size
:
Size
)
->
Self
{
let
fb_ptr
=
framebuffer
()
as
*
mut
u8
;
let
fb
=
unsafe
{
core
::
slice
::
from_raw_parts_mut
(
fb_ptr
,
VIRTGPU_LEN
as
usize
)
};
Self
{
size
,
fb
}
}
pub
fn
framebuffer
(
&
mut
self
)
->
&
mut
[
u8
]
{
self
.fb
}
pub
fn
paint_on_framebuffer
(
&
mut
self
,
p
:
impl
FnOnce
(
&
mut
[
u8
])
->
())
{
p
(
self
.framebuffer
());
framebuffer_flush
();
}
}
impl
OriginDimensions
for
Display
{
fn
size
(
&
self
)
->
Size
{
self
.size
}
}
impl
DrawTarget
for
Display
{
type
Color
=
Rgb888
;
type
Error
=
core
::
convert
::
Infallible
;
fn
draw_iter
<
I
>
(
&
mut
self
,
pixels
:
I
)
->
Result
<
(),
Self
::
Error
>
where
I
:
IntoIterator
<
Item
=
embedded_graphics
::
Pixel
<
Self
::
Color
>>
,
{
pixels
.into_iter
()
.for_each
(|
px
|
{
let
idx
=
(
px
.0
.y
*
VIRTGPU_XRES
as
i32
+
px
.0
.x
)
as
usize
*
4
;
if
idx
+
2
>=
self
.fb
.len
()
{
return
;
}
self
.fb
[
idx
]
=
px
.1
.b
();
self
.fb
[
idx
+
1
]
=
px
.1
.g
();
self
.fb
[
idx
+
2
]
=
px
.1
.r
();
});
framebuffer_flush
();
Ok
(())
}
}
pub
fn
event_get
()
->
Option
<
InputEvent
>
{
let
raw_value
=
sys_event_get
();
if
raw_value
==
0
{
None
}
else
{
Some
((
raw_value
as
u64
)
.into
())
}
}
pub
fn
key_pressed
()
->
bool
{
if
sys_key_pressed
()
==
1
{
true
}
else
{
false
}
}
#[repr(C)]
pub
struct
InputEvent
{
pub
event_type
:
u16
,
pub
code
:
u16
,
pub
value
:
u32
,
}
impl
From
<
u64
>
for
InputEvent
{
fn
from
(
mut
v
:
u64
)
->
Self
{
let
value
=
v
as
u32
;
v
>>=
32
;
let
code
=
v
as
u16
;
v
>>=
16
;
let
event_type
=
v
as
u16
;
Self
{
event_type
,
code
,
value
,
}
}
}
impl
InputEvent
{
pub
fn
decode
(
&
self
)
->
Option
<
DecodeType
>
{
Decoder
::
decode
(
self
.event_type
as
usize
,
self
.code
as
usize
,
self
.value
as
usize
,
)
.ok
()
}
}
\ No newline at end of file
user/src/lib.rs
浏览文件 @
1c4d488a
...
...
@@ -8,6 +8,10 @@
pub
mod
console
;
mod
lang_items
;
mod
syscall
;
mod
file
;
mod
task
;
mod
sync
;
mod
io
;
extern
crate
alloc
;
#[macro_use]
...
...
@@ -16,6 +20,10 @@ extern crate bitflags;
use
alloc
::
vec
::
Vec
;
use
buddy_system_allocator
::
LockedHeap
;
use
syscall
::
*
;
pub
use
file
::
*
;
pub
use
task
::
*
;
pub
use
sync
::
*
;
pub
use
io
::
*
;
const
USER_HEAP_SIZE
:
usize
=
32768
;
...
...
@@ -59,164 +67,6 @@ fn main(_argc: usize, _argv: &[&str]) -> i32 {
panic!
(
"Cannot find main!"
);
}
bitflags!
{
pub
struct
OpenFlags
:
u32
{
const
RDONLY
=
0
;
const
WRONLY
=
1
<<
0
;
const
RDWR
=
1
<<
1
;
const
CREATE
=
1
<<
9
;
const
TRUNC
=
1
<<
10
;
}
}
pub
fn
dup
(
fd
:
usize
)
->
isize
{
sys_dup
(
fd
)
}
pub
fn
open
(
path
:
&
str
,
flags
:
OpenFlags
)
->
isize
{
sys_open
(
path
,
flags
.bits
)
}
pub
fn
close
(
fd
:
usize
)
->
isize
{
sys_close
(
fd
)
}
pub
fn
pipe
(
pipe_fd
:
&
mut
[
usize
])
->
isize
{
sys_pipe
(
pipe_fd
)
}
pub
fn
read
(
fd
:
usize
,
buf
:
&
mut
[
u8
])
->
isize
{
sys_read
(
fd
,
buf
)
}
pub
fn
write
(
fd
:
usize
,
buf
:
&
[
u8
])
->
isize
{
sys_write
(
fd
,
buf
)
}
pub
fn
exit
(
exit_code
:
i32
)
->
!
{
sys_exit
(
exit_code
);
}
pub
fn
yield_
()
->
isize
{
sys_yield
()
}
pub
fn
get_time
()
->
isize
{
sys_get_time
()
}
pub
fn
getpid
()
->
isize
{
sys_getpid
()
}
pub
fn
fork
()
->
isize
{
sys_fork
()
}
pub
fn
exec
(
path
:
&
str
,
args
:
&
[
*
const
u8
])
->
isize
{
sys_exec
(
path
,
args
)
}
pub
fn
wait
(
exit_code
:
&
mut
i32
)
->
isize
{
loop
{
match
sys_waitpid
(
-
1
,
exit_code
as
*
mut
_
)
{
-
2
=>
{
yield_
();
}
// -1 or a real pid
exit_pid
=>
return
exit_pid
,
}
}
}
pub
fn
waitpid
(
pid
:
usize
,
exit_code
:
&
mut
i32
)
->
isize
{
loop
{
match
sys_waitpid
(
pid
as
isize
,
exit_code
as
*
mut
_
)
{
-
2
=>
{
yield_
();
}
// -1 or a real pid
exit_pid
=>
return
exit_pid
,
}
}
}
pub
fn
waitpid_nb
(
pid
:
usize
,
exit_code
:
&
mut
i32
)
->
isize
{
sys_waitpid
(
pid
as
isize
,
exit_code
as
*
mut
_
)
}
bitflags!
{
pub
struct
SignalFlags
:
i32
{
const
SIGINT
=
1
<<
2
;
const
SIGILL
=
1
<<
4
;
const
SIGABRT
=
1
<<
6
;
const
SIGFPE
=
1
<<
8
;
const
SIGSEGV
=
1
<<
11
;
}
}
pub
fn
kill
(
pid
:
usize
,
signal
:
i32
)
->
isize
{
sys_kill
(
pid
,
signal
)
}
pub
fn
sleep
(
sleep_ms
:
usize
)
{
sys_sleep
(
sleep_ms
);
}
pub
fn
thread_create
(
entry
:
usize
,
arg
:
usize
)
->
isize
{
sys_thread_create
(
entry
,
arg
)
}
pub
fn
gettid
()
->
isize
{
sys_gettid
()
}
pub
fn
waittid
(
tid
:
usize
)
->
isize
{
loop
{
match
sys_waittid
(
tid
)
{
-
2
=>
{
yield_
();
}
exit_code
=>
return
exit_code
,
}
}
}
pub
fn
mutex_create
()
->
isize
{
sys_mutex_create
(
false
)
}
pub
fn
mutex_blocking_create
()
->
isize
{
sys_mutex_create
(
true
)
}
pub
fn
mutex_lock
(
mutex_id
:
usize
)
{
sys_mutex_lock
(
mutex_id
);
}
pub
fn
mutex_unlock
(
mutex_id
:
usize
)
{
sys_mutex_unlock
(
mutex_id
);
}
pub
fn
semaphore_create
(
res_count
:
usize
)
->
isize
{
sys_semaphore_create
(
res_count
)
}
pub
fn
semaphore_up
(
sem_id
:
usize
)
{
sys_semaphore_up
(
sem_id
);
}
pub
fn
semaphore_down
(
sem_id
:
usize
)
{
sys_semaphore_down
(
sem_id
);
}
pub
fn
condvar_create
()
->
isize
{
sys_condvar_create
(
0
)
}
pub
fn
condvar_signal
(
condvar_id
:
usize
)
{
sys_condvar_signal
(
condvar_id
);
}
pub
fn
condvar_wait
(
condvar_id
:
usize
,
mutex_id
:
usize
)
{
sys_condvar_wait
(
condvar_id
,
mutex_id
);
}
pub
fn
framebuffer
()
->
isize
{
sys_framebuffer
()
}
pub
fn
framebuffer_flush
()
->
isize
{
sys_framebuffer_flush
()
}
pub
fn
event_get
()
->
isize
{
sys_event_get
()
}
pub
fn
key_pressed
()
->
bool
{
if
sys_key_pressed
()
==
1
{
true
}
else
{
false
}
}
#[macro_export]
macro_rules!
vstore
{
(
$var_ref
:
expr
,
$value
:
expr
)
=>
{
...
...
user/src/sync.rs
0 → 100644
浏览文件 @
1c4d488a
use
super
::
*
;
pub
fn
mutex_create
()
->
isize
{
sys_mutex_create
(
false
)
}
pub
fn
mutex_blocking_create
()
->
isize
{
sys_mutex_create
(
true
)
}
pub
fn
mutex_lock
(
mutex_id
:
usize
)
{
sys_mutex_lock
(
mutex_id
);
}
pub
fn
mutex_unlock
(
mutex_id
:
usize
)
{
sys_mutex_unlock
(
mutex_id
);
}
pub
fn
semaphore_create
(
res_count
:
usize
)
->
isize
{
sys_semaphore_create
(
res_count
)
}
pub
fn
semaphore_up
(
sem_id
:
usize
)
{
sys_semaphore_up
(
sem_id
);
}
pub
fn
semaphore_down
(
sem_id
:
usize
)
{
sys_semaphore_down
(
sem_id
);
}
pub
fn
condvar_create
()
->
isize
{
sys_condvar_create
(
0
)
}
pub
fn
condvar_signal
(
condvar_id
:
usize
)
{
sys_condvar_signal
(
condvar_id
);
}
pub
fn
condvar_wait
(
condvar_id
:
usize
,
mutex_id
:
usize
)
{
sys_condvar_wait
(
condvar_id
,
mutex_id
);
}
\ No newline at end of file
user/src/task.rs
0 → 100644
浏览文件 @
1c4d488a
use
super
::
*
;
pub
fn
exit
(
exit_code
:
i32
)
->
!
{
sys_exit
(
exit_code
);
}
pub
fn
yield_
()
->
isize
{
sys_yield
()
}
pub
fn
get_time
()
->
isize
{
sys_get_time
()
}
pub
fn
getpid
()
->
isize
{
sys_getpid
()
}
pub
fn
fork
()
->
isize
{
sys_fork
()
}
pub
fn
exec
(
path
:
&
str
,
args
:
&
[
*
const
u8
])
->
isize
{
sys_exec
(
path
,
args
)
}
pub
fn
wait
(
exit_code
:
&
mut
i32
)
->
isize
{
loop
{
match
sys_waitpid
(
-
1
,
exit_code
as
*
mut
_
)
{
-
2
=>
{
yield_
();
}
// -1 or a real pid
exit_pid
=>
return
exit_pid
,
}
}
}
pub
fn
waitpid
(
pid
:
usize
,
exit_code
:
&
mut
i32
)
->
isize
{
loop
{
match
sys_waitpid
(
pid
as
isize
,
exit_code
as
*
mut
_
)
{
-
2
=>
{
yield_
();
}
// -1 or a real pid
exit_pid
=>
return
exit_pid
,
}
}
}
pub
fn
waitpid_nb
(
pid
:
usize
,
exit_code
:
&
mut
i32
)
->
isize
{
sys_waitpid
(
pid
as
isize
,
exit_code
as
*
mut
_
)
}
bitflags!
{
pub
struct
SignalFlags
:
i32
{
const
SIGINT
=
1
<<
2
;
const
SIGILL
=
1
<<
4
;
const
SIGABRT
=
1
<<
6
;
const
SIGFPE
=
1
<<
8
;
const
SIGSEGV
=
1
<<
11
;
}
}
pub
fn
kill
(
pid
:
usize
,
signal
:
i32
)
->
isize
{
sys_kill
(
pid
,
signal
)
}
pub
fn
sleep
(
sleep_ms
:
usize
)
{
sys_sleep
(
sleep_ms
);
}
pub
fn
thread_create
(
entry
:
usize
,
arg
:
usize
)
->
isize
{
sys_thread_create
(
entry
,
arg
)
}
pub
fn
gettid
()
->
isize
{
sys_gettid
()
}
pub
fn
waittid
(
tid
:
usize
)
->
isize
{
loop
{
match
sys_waittid
(
tid
)
{
-
2
=>
{
yield_
();
}
exit_code
=>
return
exit_code
,
}
}
}
\ No newline at end of file
Miykael_xxm
🚴
@xiongjiamu
mentioned in commit
970a7fa6
·
1月 14, 2023
mentioned in commit
970a7fa6
mentioned in commit 970a7fa64a99e707480b0f6c44872839f7998341
开关提交列表
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录