Skip to content

Commit 737d07d

Browse files
committed
simple gui app can run now!
1 parent d56c5d1 commit 737d07d

File tree

11 files changed

+119
-3
lines changed

11 files changed

+119
-3
lines changed

os/src/gui/graphic.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ impl Graphics {
2727
let fb = self.drv.get_framebuffer();
2828
fb.fill(0u8);
2929
}
30+
31+
pub fn get_framebuffer(&self)-> &mut [u8] {
32+
self.drv.get_framebuffer()
33+
}
3034
}
3135

3236
impl OriginDimensions for Graphics {

os/src/mm/address.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,3 +260,4 @@ where
260260
}
261261
}
262262
pub type VPNRange = SimpleRange<VirtPageNum>;
263+
pub type PPNRange = SimpleRange<PhysPageNum>;

os/src/mm/frame_allocator.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ impl FrameTracker {
1818
}
1919
Self { ppn }
2020
}
21+
pub fn new_nowrite(ppn: PhysPageNum) -> Self {
22+
Self { ppn }
23+
}
2124
}
2225

2326
impl Debug for FrameTracker {

os/src/mm/memory_set.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use super::{frame_alloc, FrameTracker};
22
use super::{PTEFlags, PageTable, PageTableEntry};
33
use super::{PhysAddr, PhysPageNum, VirtAddr, VirtPageNum};
4-
use super::{StepByOne, VPNRange};
4+
use super::{StepByOne, VPNRange, PPNRange};
55
use crate::config::{MEMORY_END, MMIO, PAGE_SIZE, TRAMPOLINE};
66
use crate::sync::UPIntrFreeCell;
77
use alloc::collections::BTreeMap;
@@ -78,6 +78,10 @@ impl MemorySet {
7878
}
7979
self.areas.push(map_area);
8080
}
81+
pub fn push_noalloc(&mut self, mut map_area: MapArea, ppn_range: PPNRange) {
82+
map_area.map_noalloc(&mut self.page_table, ppn_range);
83+
self.areas.push(map_area);
84+
}
8185
/// Mention that trampoline is not collected by areas.
8286
fn map_trampoline(&mut self) {
8387
self.page_table.map(
@@ -301,6 +305,14 @@ impl MapArea {
301305
self.map_one(page_table, vpn);
302306
}
303307
}
308+
pub fn map_noalloc(&mut self, page_table: &mut PageTable,ppn_range:PPNRange) {
309+
for (vpn,ppn) in core::iter::zip(self.vpn_range,ppn_range) {
310+
self.data_frames.insert(vpn, FrameTracker::new_nowrite(ppn));
311+
let pte_flags = PTEFlags::from_bits(self.map_perm.bits).unwrap();
312+
page_table.map(vpn, ppn, pte_flags);
313+
}
314+
}
315+
304316
pub fn unmap(&mut self, page_table: &mut PageTable) {
305317
for vpn in self.vpn_range {
306318
self.unmap_one(page_table, vpn);

os/src/mm/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ mod heap_allocator;
44
mod memory_set;
55
mod page_table;
66

7-
use address::VPNRange;
7+
pub use address::{VPNRange, PPNRange};
88
pub use address::{PhysAddr, PhysPageNum, StepByOne, VirtAddr, VirtPageNum};
99
pub use frame_allocator::{frame_alloc, frame_dealloc, FrameTracker};
1010
pub use memory_set::remap_test;
11-
pub use memory_set::{kernel_token, MapPermission, MemorySet, KERNEL_SPACE};
11+
pub use memory_set::{kernel_token, MapPermission, MemorySet, MapArea, MapType, KERNEL_SPACE};
1212
use page_table::PTEFlags;
1313
pub use page_table::{
1414
translated_byte_buffer, translated_ref, translated_refmut, translated_str, PageTable,

os/src/syscall/gui.rs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
use crate::mm::{MapArea, MapPermission, MapType, PPNRange, PhysAddr};
2+
use crate::task::current_process;
3+
4+
//use crate::gui::*;
5+
use crate::drivers::GPU_DEVICE;
6+
7+
const FB_VADDR: usize = 0x10000000;
8+
9+
pub fn sys_framebuffer() -> isize {
10+
let gpu = GPU_DEVICE.clone();
11+
let fb = gpu.get_framebuffer();
12+
let len = fb.len();
13+
println!("[kernel] FrameBuffer: addr 0x{:X}, len {}", fb.as_ptr() as usize , len);
14+
let fb_ppn = PhysAddr::from(fb.as_ptr() as usize).floor();
15+
let fb_end_ppn = PhysAddr::from(fb.as_ptr() as usize + len).ceil();
16+
17+
let current_process = current_process();
18+
let mut inner = current_process.inner_exclusive_access();
19+
let mem_set = &mut inner.memory_set;
20+
21+
mem_set.push_noalloc(
22+
MapArea::new(
23+
(FB_VADDR as usize).into(),
24+
(FB_VADDR + len as usize).into(),
25+
MapType::Framed,
26+
MapPermission::R | MapPermission::W | MapPermission::U,
27+
),
28+
PPNRange::new(fb_ppn, fb_end_ppn),
29+
);
30+
FB_VADDR as isize
31+
}
32+
33+
pub fn sys_framebuffer_flush() -> isize {
34+
let gpu = GPU_DEVICE.clone();
35+
gpu.flush();
36+
0
37+
}

os/src/syscall/mod.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,16 +25,20 @@ const SYSCALL_SEMAPHORE_DOWN: usize = 1022;
2525
const SYSCALL_CONDVAR_CREATE: usize = 1030;
2626
const SYSCALL_CONDVAR_SIGNAL: usize = 1031;
2727
const SYSCALL_CONDVAR_WAIT: usize = 1032;
28+
const SYSCALL_FRAMEBUFFER: usize = 2000;
29+
const SYSCALL_FRAMEBUFFER_FLUSH: usize = 2001;
2830

2931
mod fs;
3032
mod process;
3133
mod sync;
3234
mod thread;
35+
mod gui;
3336

3437
use fs::*;
3538
use process::*;
3639
use sync::*;
3740
use thread::*;
41+
use gui::*;
3842

3943
pub fn syscall(syscall_id: usize, args: [usize; 3]) -> isize {
4044
match syscall_id {
@@ -65,6 +69,8 @@ pub fn syscall(syscall_id: usize, args: [usize; 3]) -> isize {
6569
SYSCALL_CONDVAR_CREATE => sys_condvar_create(args[0]),
6670
SYSCALL_CONDVAR_SIGNAL => sys_condvar_signal(args[0]),
6771
SYSCALL_CONDVAR_WAIT => sys_condvar_wait(args[0], args[1]),
72+
SYSCALL_FRAMEBUFFER => sys_framebuffer(),
73+
SYSCALL_FRAMEBUFFER_FLUSH => sys_framebuffer_flush(),
6874
_ => panic!("Unsupported syscall_id: {}", syscall_id),
6975
}
7076
}

user/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ edition = "2018"
1010
buddy_system_allocator = "0.6"
1111
bitflags = "1.2.1"
1212
riscv = { git = "https://github.com/rcore-os/riscv", features = ["inline-asm"] }
13+
embedded-graphics = "0.7.1"
1314

1415
[profile.release]
1516
debug = true

user/src/bin/gui_simple.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#![no_std]
2+
#![no_main]
3+
4+
use user_lib::{framebuffer, framebuffer_flush};
5+
6+
#[macro_use]
7+
extern crate user_lib;
8+
9+
// use embedded_graphics::pixelcolor::Rgb888;
10+
// use embedded_graphics::prelude::{Drawable, Point, RgbColor, Size};
11+
// use embedded_graphics::primitives::Primitive;
12+
// use embedded_graphics::primitives::{PrimitiveStyle, Rectangle};
13+
// use embedded_graphics::{
14+
// draw_target::DrawTarget,
15+
// prelude::{OriginDimensions},
16+
// };
17+
pub const VIRTGPU_XRES: usize = 1280;
18+
pub const VIRTGPU_YRES: usize = 800;
19+
20+
#[no_mangle]
21+
pub fn main() -> i32 {
22+
let fb_ptr =framebuffer() as *mut u8;
23+
println!("Hello world from user mode program! 0x{:X} , len {}", fb_ptr as usize, VIRTGPU_XRES*VIRTGPU_YRES*4);
24+
let fb= unsafe {core::slice::from_raw_parts_mut(fb_ptr as *mut u8, VIRTGPU_XRES*VIRTGPU_YRES*4 as usize)};
25+
for y in 0..800 {
26+
for x in 0..1280 {
27+
let idx = (y * 1280 + x) * 4;
28+
fb[idx] = x as u8;
29+
fb[idx + 1] = y as u8;
30+
fb[idx + 2] = (x + y) as u8;
31+
}
32+
}
33+
framebuffer_flush();
34+
0
35+
}

user/src/lib.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,12 @@ pub fn condvar_signal(condvar_id: usize) {
198198
pub fn condvar_wait(condvar_id: usize, mutex_id: usize) {
199199
sys_condvar_wait(condvar_id, mutex_id);
200200
}
201+
pub fn framebuffer() -> isize {
202+
sys_framebuffer()
203+
}
204+
pub fn framebuffer_flush() -> isize {
205+
sys_framebuffer_flush()
206+
}
201207

202208
#[macro_export]
203209
macro_rules! vstore {

0 commit comments

Comments
 (0)