提交 1c4d488a 编写于 作者: Y Yifan Wu

updates from ch9

上级 b2627812
...@@ -13,10 +13,8 @@ buddy_system_allocator = "0.6" ...@@ -13,10 +13,8 @@ buddy_system_allocator = "0.6"
bitflags = "1.2.1" bitflags = "1.2.1"
xmas-elf = "0.7.0" xmas-elf = "0.7.0"
volatile = "0.3" 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 = "4ee80e5" }
virtio-drivers = { git = "https://github.com/rcore-os/virtio-drivers", rev = "70b5850" }
easy-fs = { path = "../easy-fs" } easy-fs = { path = "../easy-fs" }
#virtio-input-decoder = "0.1.4"
embedded-graphics = "0.7.1" embedded-graphics = "0.7.1"
tinybmp = "0.3.1" tinybmp = "0.3.1"
......
...@@ -143,12 +143,13 @@ impl<const BASE_ADDR: usize> NS16550a<BASE_ADDR> { ...@@ -143,12 +143,13 @@ impl<const BASE_ADDR: usize> NS16550a<BASE_ADDR> {
} }
pub fn read_buffer_is_empty(&self) -> bool { 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> { impl<const BASE_ADDR: usize> CharDevice for NS16550a<BASE_ADDR> {
fn init(&self){ fn init(&self) {
let mut inner = self.inner.exclusive_access(); let mut inner = self.inner.exclusive_access();
inner.ns16550a.init(); inner.ns16550a.init();
drop(inner); drop(inner);
......
...@@ -16,41 +16,20 @@ struct VirtIOInputInner { ...@@ -16,41 +16,20 @@ struct VirtIOInputInner {
struct VirtIOInputWrapper { struct VirtIOInputWrapper {
inner: UPIntrFreeCell<VirtIOInputInner>, inner: UPIntrFreeCell<VirtIOInputInner>,
//condvars: BTreeMap<u16, Condvar>, condvar: Condvar,
//condvar: Arc::<Condvar> ,
condvar:Condvar,
} }
pub trait InputDevice: Send + Sync + Any { pub trait InputDevice: Send + Sync + Any {
fn read_event(&self) -> u64; fn read_event(&self) -> u64;
fn handle_irq(&self); fn handle_irq(&self);
// fn events(&self) -> &VecDeque<u64>;
fn is_empty(&self) -> bool; fn is_empty(&self) -> bool;
} }
lazy_static::lazy_static!( lazy_static::lazy_static!(
pub static ref KEYBOARD_DEVICE: Arc<dyn InputDevice> = Arc::new(VirtIOInputWrapper::new(VIRTIO5)); 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 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 { impl VirtIOInputWrapper {
pub fn new(addr: usize) -> Self { pub fn new(addr: usize) -> Self {
let inner = VirtIOInputInner { let inner = VirtIOInputInner {
...@@ -59,17 +38,8 @@ impl VirtIOInputWrapper { ...@@ -59,17 +38,8 @@ impl VirtIOInputWrapper {
}, },
events: VecDeque::new(), 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 { Self {
inner: unsafe { UPIntrFreeCell::new(inner) }, inner: unsafe { UPIntrFreeCell::new(inner) },
//condvar: INPUT_CONDVAR.clone(),
condvar: Condvar::new(), condvar: Condvar::new(),
} }
} }
...@@ -93,29 +63,20 @@ impl InputDevice for VirtIOInputWrapper { ...@@ -93,29 +63,20 @@ impl InputDevice for VirtIOInputWrapper {
} }
} }
// fn events(&self) -> &VecDeque<u64> {
// &self.inner.exclusive_access().events
// }
fn handle_irq(&self) { fn handle_irq(&self) {
let mut count = 0; let mut count = 0;
let mut result = 0; let mut result = 0;
let mut key = 0;
self.inner.exclusive_session(|inner| { self.inner.exclusive_session(|inner| {
inner.virtio_input.ack_interrupt(); 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; count += 1;
key = token;
result = (event.event_type as u64) << 48 result = (event.event_type as u64) << 48
| (event.code as u64) << 32 | (event.code as u64) << 32
| (event.value) as u64; | (event.value) as u64;
inner.events.push_back(result); inner.events.push_back(result);
// for test
//println!("[KERN] inputdev_handle_irq: event: {:x}", result);
} }
}); });
if count > 0 { if count > 0 {
//self.condvars.get(&key).unwrap().signal();
self.condvar.signal(); self.condvar.signal();
}; };
} }
......
...@@ -170,4 +170,4 @@ impl File for Pipe { ...@@ -170,4 +170,4 @@ impl File for Pipe {
} }
} }
} }
} }
\ No newline at end of file
...@@ -29,7 +29,6 @@ mod trap; ...@@ -29,7 +29,6 @@ mod trap;
use crate::drivers::chardev::CharDevice; use crate::drivers::chardev::CharDevice;
use crate::drivers::chardev::UART; use crate::drivers::chardev::UART;
//use syscall::create_desktop; //for test
core::arch::global_asm!(include_str!("entry.asm")); core::arch::global_asm!(include_str!("entry.asm"));
...@@ -59,7 +58,6 @@ pub fn rust_main() -> ! { ...@@ -59,7 +58,6 @@ pub fn rust_main() -> ! {
UART.init(); UART.init();
println!("KERN: init gpu"); println!("KERN: init gpu");
let _gpu = GPU_DEVICE.clone(); let _gpu = GPU_DEVICE.clone();
//let _input_condvar = INPUT_CONDVAR.clone();
println!("KERN: init keyboard"); println!("KERN: init keyboard");
let _keyboard = KEYBOARD_DEVICE.clone(); let _keyboard = KEYBOARD_DEVICE.clone();
println!("KERN: init mouse"); println!("KERN: init mouse");
...@@ -70,7 +68,6 @@ pub fn rust_main() -> ! { ...@@ -70,7 +68,6 @@ pub fn rust_main() -> ! {
timer::set_next_trigger(); timer::set_next_trigger();
board::device_init(); board::device_init();
fs::list_apps(); fs::list_apps();
//gui::init_paint();
task::add_initproc(); task::add_initproc();
*DEV_NON_BLOCKING_ACCESS.exclusive_access() = true; *DEV_NON_BLOCKING_ACCESS.exclusive_access() = true;
task::run_tasks(); task::run_tasks();
......
...@@ -260,4 +260,3 @@ where ...@@ -260,4 +260,3 @@ where
} }
} }
pub type VPNRange = SimpleRange<VirtPageNum>; pub type VPNRange = SimpleRange<VirtPageNum>;
pub type PPNRange = SimpleRange<PhysPageNum>;
...@@ -7,7 +7,6 @@ use lazy_static::*; ...@@ -7,7 +7,6 @@ use lazy_static::*;
pub struct FrameTracker { pub struct FrameTracker {
pub ppn: PhysPageNum, pub ppn: PhysPageNum,
pub nodrop: bool,
} }
impl FrameTracker { impl FrameTracker {
...@@ -17,10 +16,7 @@ impl FrameTracker { ...@@ -17,10 +16,7 @@ impl FrameTracker {
for i in bytes_array { for i in bytes_array {
*i = 0; *i = 0;
} }
Self { ppn, nodrop: false } Self { ppn }
}
pub fn new_noalloc(ppn: PhysPageNum) -> Self {
Self { ppn, nodrop: true }
} }
} }
...@@ -32,9 +28,6 @@ impl Debug for FrameTracker { ...@@ -32,9 +28,6 @@ impl Debug for FrameTracker {
impl Drop for FrameTracker { impl Drop for FrameTracker {
fn drop(&mut self) { fn drop(&mut self) {
if self.nodrop {
return;
}
frame_dealloc(self.ppn); frame_dealloc(self.ppn);
} }
} }
......
use super::{frame_alloc, FrameTracker}; use super::{frame_alloc, FrameTracker};
use super::{PTEFlags, PageTable, PageTableEntry}; use super::{PTEFlags, PageTable, PageTableEntry};
use super::{PhysAddr, PhysPageNum, VirtAddr, VirtPageNum}; 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::config::{MEMORY_END, MMIO, PAGE_SIZE, TRAMPOLINE};
use crate::sync::UPIntrFreeCell; use crate::sync::UPIntrFreeCell;
use alloc::collections::BTreeMap; use alloc::collections::BTreeMap;
...@@ -71,17 +71,16 @@ impl MemorySet { ...@@ -71,17 +71,16 @@ impl MemorySet {
self.areas.remove(idx); 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); map_area.map(&mut self.page_table);
if let Some(data) = data { if let Some(data) = data {
map_area.copy_data(&mut self.page_table, data); map_area.copy_data(&mut self.page_table, data);
} }
self.areas.push(map_area); 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. /// Mention that trampoline is not collected by areas.
fn map_trampoline(&mut self) { fn map_trampoline(&mut self) {
self.page_table.map( self.page_table.map(
...@@ -290,8 +289,10 @@ impl MapArea { ...@@ -290,8 +289,10 @@ impl MapArea {
ppn = frame.ppn; ppn = frame.ppn;
self.data_frames.insert(vpn, frame); self.data_frames.insert(vpn, frame);
} }
MapType::Noalloc => { MapType::Linear(pn_offset) => {
panic!("Noalloc should not be mapped"); // check for sv39
assert!(vpn.0 < (1usize << 27));
ppn = PhysPageNum((vpn.0 as isize + pn_offset) as usize);
} }
} }
let pte_flags = PTEFlags::from_bits(self.map_perm.bits).unwrap(); let pte_flags = PTEFlags::from_bits(self.map_perm.bits).unwrap();
...@@ -308,14 +309,6 @@ impl MapArea { ...@@ -308,14 +309,6 @@ impl MapArea {
self.map_one(page_table, vpn); 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) { pub fn unmap(&mut self, page_table: &mut PageTable) {
for vpn in self.vpn_range { for vpn in self.vpn_range {
self.unmap_one(page_table, vpn); self.unmap_one(page_table, vpn);
...@@ -349,7 +342,8 @@ impl MapArea { ...@@ -349,7 +342,8 @@ impl MapArea {
pub enum MapType { pub enum MapType {
Identical, Identical,
Framed, Framed,
Noalloc, /// offset of page num
Linear(isize),
} }
bitflags! { bitflags! {
......
...@@ -4,11 +4,11 @@ mod heap_allocator; ...@@ -4,11 +4,11 @@ mod heap_allocator;
mod memory_set; mod memory_set;
mod page_table; mod page_table;
pub use address::{VPNRange, PPNRange}; pub use address::VPNRange;
pub use address::{PhysAddr, PhysPageNum, StepByOne, VirtAddr, VirtPageNum}; pub use address::{PhysAddr, PhysPageNum, StepByOne, VirtAddr, VirtPageNum};
pub use frame_allocator::{frame_alloc, frame_dealloc, FrameTracker}; pub use frame_allocator::{frame_alloc, frame_dealloc, FrameTracker};
pub use memory_set::remap_test; pub use memory_set::remap_test;
pub use memory_set::{kernel_token, MapPermission, MemorySet, MapArea, MapType, KERNEL_SPACE}; pub use memory_set::{kernel_token, MapArea, MapPermission, MapType, MemorySet, KERNEL_SPACE};
use page_table::PTEFlags; use page_table::PTEFlags;
pub use page_table::{ pub use page_table::{
translated_byte_buffer, translated_ref, translated_refmut, translated_str, PageTable, translated_byte_buffer, translated_ref, translated_refmut, translated_str, PageTable,
......
...@@ -96,4 +96,4 @@ pub fn sys_dup(fd: usize) -> isize { ...@@ -96,4 +96,4 @@ pub fn sys_dup(fd: usize) -> isize {
let new_fd = inner.alloc_fd(); let new_fd = inner.alloc_fd();
inner.fd_table[new_fd] = Some(Arc::clone(inner.fd_table[fd].as_ref().unwrap())); inner.fd_table[new_fd] = Some(Arc::clone(inner.fd_table[fd].as_ref().unwrap()));
new_fd as isize new_fd as isize
} }
\ No newline at end of file
use crate::mm::{MapArea, MapPermission, MapType, PPNRange, PhysAddr};
use crate::task::current_process;
//use crate::gui::*;
use crate::drivers::GPU_DEVICE; use crate::drivers::GPU_DEVICE;
use crate::mm::{MapArea, MapPermission, MapType, PhysAddr, VirtAddr};
use crate::task::current_process;
const FB_VADDR: usize = 0x10000000; const FB_VADDR: usize = 0x10000000;
pub fn sys_framebuffer() -> isize { pub fn sys_framebuffer() -> isize {
let gpu = GPU_DEVICE.clone(); let fb = GPU_DEVICE.get_framebuffer();
let fb = gpu.get_framebuffer();
let len = fb.len(); let len = fb.len();
println!("[kernel] FrameBuffer: addr 0x{:X}, len {}", fb.as_ptr() as usize , 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_start_pa = PhysAddr::from(fb.as_ptr() as usize);
let fb_end_ppn = PhysAddr::from(fb.as_ptr() as usize + len).ceil(); 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 current_process = current_process();
let mut inner = current_process.inner_exclusive_access(); let mut inner = current_process.inner_exclusive_access();
let mem_set = &mut inner.memory_set; inner.memory_set.push(
mem_set.push_noalloc(
MapArea::new( MapArea::new(
(FB_VADDR as usize).into(), (FB_VADDR as usize).into(),
(FB_VADDR + len as usize).into(), (FB_VADDR + len as usize).into(),
MapType::Noalloc, MapType::Linear(pn_offset),
MapPermission::R | MapPermission::W | MapPermission::U, MapPermission::R | MapPermission::W | MapPermission::U,
), ),
PPNRange::new(fb_ppn, fb_end_ppn), None,
); );
FB_VADDR as isize FB_VADDR as isize
} }
pub fn sys_framebuffer_flush() -> isize { pub fn sys_framebuffer_flush() -> isize {
let gpu = GPU_DEVICE.clone(); GPU_DEVICE.flush();
gpu.flush();
0 0
} }
\ No newline at end of file
//use crate::drivers::{KEYBOARD_DEVICE,MOUSE_DEVICE,INPUT_CONDVAR,read_input_event}; //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 kb = KEYBOARD_DEVICE.clone();
let mouse = MOUSE_DEVICE.clone(); let mouse = MOUSE_DEVICE.clone();
//let input=INPUT_CONDVAR.clone(); //let input=INPUT_CONDVAR.clone();
//read_input_event() as isize //read_input_event() as isize
if !kb.is_empty(){ if !kb.is_empty() {
kb.read_event() as isize kb.read_event() as isize
} else if !mouse.is_empty() { } else if !mouse.is_empty() {
mouse.read_event() as isize mouse.read_event() as isize
} else { } else {
0 0
} }
} }
use crate::drivers::chardev::UART; use crate::drivers::chardev::UART;
/// check UART's read-buffer is empty or not /// check UART's read-buffer is empty or not
pub fn sys_key_pressed() -> isize { pub fn sys_key_pressed() -> isize {
let res =!UART.read_buffer_is_empty(); let res = !UART.read_buffer_is_empty();
if res { if res {
1 1
} else { } else {
0 0
} }
} }
\ No newline at end of file
...@@ -31,18 +31,18 @@ const SYSCALL_EVENT_GET: usize = 3000; ...@@ -31,18 +31,18 @@ const SYSCALL_EVENT_GET: usize = 3000;
const SYSCALL_KEY_PRESSED: usize = 3001; const SYSCALL_KEY_PRESSED: usize = 3001;
mod fs; mod fs;
mod gui;
mod input;
mod process; mod process;
mod sync; mod sync;
mod thread; mod thread;
mod gui;
mod input;
use fs::*; use fs::*;
use gui::*;
use input::*;
use process::*; use process::*;
use sync::*; use sync::*;
use thread::*; use thread::*;
use gui::*;
use input::*;
pub fn syscall(syscall_id: usize, args: [usize; 3]) -> isize { pub fn syscall(syscall_id: usize, args: [usize; 3]) -> isize {
match syscall_id { match syscall_id {
......
...@@ -12,5 +12,7 @@ bitflags = "1.2.1" ...@@ -12,5 +12,7 @@ bitflags = "1.2.1"
riscv = { git = "https://github.com/rcore-os/riscv", features = ["inline-asm"] } riscv = { git = "https://github.com/rcore-os/riscv", features = ["inline-asm"] }
embedded-graphics = "0.7.1" embedded-graphics = "0.7.1"
oorandom ="11" oorandom ="11"
virtio-input-decoder = "0.1.4"
[profile.release] [profile.release]
debug = true debug = true
\ No newline at end of file
#![no_std] #![no_std]
#![no_main] #![no_main]
#[macro_use]
extern crate user_lib; extern crate user_lib;
extern crate alloc; 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::pixelcolor::Rgb888;
use embedded_graphics::prelude::{Drawable, Point, RgbColor, Size}; use embedded_graphics::prelude::{DrawTarget, Drawable, Point, RgbColor, Size};
use embedded_graphics::primitives::Primitive; use embedded_graphics::primitives::{Primitive, PrimitiveStyle, Rectangle};
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;
const INIT_X: i32 = 640; const INIT_X: i32 = 640;
const INIT_Y: i32 = 400; const INIT_Y: i32 = 400;
const RECT_SIZE: u32 = 40; 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 { pub struct DrawingBoard {
disp: Display, disp: Display,
latest_pos: Point, latest_pos: Point,
...@@ -80,7 +22,7 @@ pub struct DrawingBoard { ...@@ -80,7 +22,7 @@ pub struct DrawingBoard {
impl DrawingBoard { impl DrawingBoard {
pub fn new() -> Self { pub fn new() -> Self {
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), latest_pos: Point::new(INIT_X, INIT_Y),
} }
} }
...@@ -106,7 +48,6 @@ impl DrawingBoard { ...@@ -106,7 +48,6 @@ impl DrawingBoard {
#[no_mangle] #[no_mangle]
pub fn main() -> i32 { pub fn main() -> i32 {
// let fb_ptr = framebuffer() as *mut u8;
let mut board = DrawingBoard::new(); let mut board = DrawingBoard::new();
let _ = board.disp.clear(Rgb888::BLACK).unwrap(); let _ = board.disp.clear(Rgb888::BLACK).unwrap();
for i in 0..20 { for i in 0..20 {
......
#![no_std] #![no_std]
#![no_main] #![no_main]
#[macro_use]
extern crate user_lib; extern crate user_lib;
use user_lib::{framebuffer, framebuffer_flush}; use user_lib::{VIRTGPU_XRES, VIRTGPU_YRES, Display};
use embedded_graphics::prelude::Size;
pub const VIRTGPU_XRES: usize = 1280;
pub const VIRTGPU_YRES: usize = 800;
#[no_mangle] #[no_mangle]
pub fn main() -> i32 { pub fn main() -> i32 {
let fb_ptr =framebuffer() as *mut u8; let mut disp = Display::new(Size::new(VIRTGPU_XRES, VIRTGPU_YRES));
println!("Hello world from user mode program! 0x{:X} , len {}", fb_ptr as usize, VIRTGPU_XRES*VIRTGPU_YRES*4); disp.paint_on_framebuffer(|fb| {
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..VIRTGPU_YRES as usize {
for y in 0..800 { for x in 0..VIRTGPU_XRES as usize {
for x in 0..1280 { let idx = (y * VIRTGPU_XRES as usize + x) * 4;
let idx = (y * 1280 + x) * 4; fb[idx] = x as u8;
fb[idx] = x as u8; fb[idx + 1] = y as u8;
fb[idx + 1] = y as u8; fb[idx + 2] = (x + y) as u8;
fb[idx + 2] = (x + y) as u8; }
} }
} });
framebuffer_flush();
0 0
} }
#![no_std] #![no_std]
#![no_main] #![no_main]
#[macro_use]
extern crate user_lib; extern crate user_lib;
extern crate alloc; extern crate alloc;
use user_lib::console::getchar; 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::pixelcolor::*;
use embedded_graphics::prelude::{Drawable, Point, RgbColor, Size}; use embedded_graphics::prelude::{Drawable, Point, RgbColor, Size};
...@@ -16,58 +15,6 @@ use embedded_graphics::Pixel; ...@@ -16,58 +15,6 @@ use embedded_graphics::Pixel;
use embedded_graphics::{draw_target::DrawTarget, prelude::OriginDimensions}; use embedded_graphics::{draw_target::DrawTarget, prelude::OriginDimensions};
use oorandom; //random generator 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> { struct Snake<T: PixelColor, const MAX_SIZE: usize> {
parts: [Pixel<T>; MAX_SIZE], parts: [Pixel<T>; MAX_SIZE],
len: usize, len: usize,
...@@ -380,7 +327,7 @@ const LF: u8 = 0x0au8; ...@@ -380,7 +327,7 @@ const LF: u8 = 0x0au8;
const CR: u8 = 0x0du8; const CR: u8 = 0x0du8;
#[no_mangle] #[no_mangle]
pub fn main() -> i32 { 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 mut game = SnakeGame::<20, Rgb888>::new(1280, 800, 20, 20, Rgb888::RED, Rgb888::YELLOW, 50);
let _ = disp.clear(Rgb888::BLACK).unwrap(); let _ = disp.clear(Rgb888::BLACK).unwrap();
loop { loop {
......
#![no_std] #![no_std]
#![no_main] #![no_main]
use user_lib::{event_get}; use user_lib::{event_get, DecodeType, Key, KeyType};
#[macro_use] #[macro_use]
extern crate user_lib; extern crate user_lib;
...@@ -9,13 +9,17 @@ extern crate user_lib; ...@@ -9,13 +9,17 @@ extern crate user_lib;
#[no_mangle] #[no_mangle]
pub fn main() -> i32 { pub fn main() -> i32 {
println!("Input device event test"); println!("Input device event test");
let mut event=0; loop {
for _ in 0..3 { if let Some(event) = event_get() {
while event==0 { if let Some(decoder_type) = event.decode() {
event = event_get(); println!("{:?}", decoder_type);
} if let DecodeType::Key(key, keytype) = decoder_type {
println!("event: {:?}", event); if key == Key::Enter && keytype == KeyType::Press {
break;
}
}
}
}
} }
0 0
} }
\ No newline at end of file
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
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
...@@ -8,6 +8,10 @@ ...@@ -8,6 +8,10 @@
pub mod console; pub mod console;
mod lang_items; mod lang_items;
mod syscall; mod syscall;
mod file;
mod task;
mod sync;
mod io;
extern crate alloc; extern crate alloc;
#[macro_use] #[macro_use]
...@@ -16,6 +20,10 @@ extern crate bitflags; ...@@ -16,6 +20,10 @@ extern crate bitflags;
use alloc::vec::Vec; use alloc::vec::Vec;
use buddy_system_allocator::LockedHeap; use buddy_system_allocator::LockedHeap;
use syscall::*; use syscall::*;
pub use file::*;
pub use task::*;
pub use sync::*;
pub use io::*;
const USER_HEAP_SIZE: usize = 32768; const USER_HEAP_SIZE: usize = 32768;
...@@ -59,164 +67,6 @@ fn main(_argc: usize, _argv: &[&str]) -> i32 { ...@@ -59,164 +67,6 @@ fn main(_argc: usize, _argv: &[&str]) -> i32 {
panic!("Cannot find main!"); 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_export]
macro_rules! vstore { macro_rules! vstore {
($var_ref: expr, $value: expr) => { ($var_ref: expr, $value: expr) => {
......
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
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
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册