Replies: 5 comments 11 replies
-
分六块内容
// memory
SyscallNo::BRK => sys_brk(args[0]),
SyscallNo::MUNMAP => sys_munmap(args[0], args[1]),
SyscallNo::MMAP => {
let prot = if args[2] == 0 {
MMAPPROT::PROT_READ | MMAPPROT::PROT_WRITE
} else {
MMAPPROT::from_bits(args[2] as u32).unwrap()
};
let flags = MMAPFlags::from_bits(args[3] as u32).unwrap();
if !flags.contains(MMAPFlags::MAP_PRIVATE | MMAPFlags::MAP_ANONYMOUS) {
panic!("need advanced mmap flags = {:#?}", flags);
}
sys_mmap(
args[0],
args[1],
prot,
flags,
args[4] as i32,
args[5],
)},
SyscallNo::EXECVE => sys_execve( // 这里是 shell 去启动 redis 的时候调用的,不需要管
args[0] as *const u8,
args[1] as *const usize,
args[2] as *const usize,
),
// thread and lock
SyscallNo::EXIT | SyscallNo::EXIT_GROUP => sys_exit(args[0] as i32),
SyscallNo::SET_TID_ADDRESS => sys_set_tid_address(args[0]),
SyscallNo::CLONE => sys_clone(args[0], args[1], args[2], args[3], args[4]),
SyscallNo::FUTEX => sys_futex(
args[0],
args[1] as i32,
args[2] as u32,
args[3],
args[4],
args[5] as u32,
),
// process
SyscallNo::CLOCK_GET_TIME => timer::sys_clock_gettime(args[0], args[1] as *mut TimeSpec),
SyscallNo::YIELD => sys_yield(),
SyscallNo::GETPID => sys_getpid(),
// IO and FS
SyscallNo::READ => sys_read(args[0], args[1] as *mut u8, args[2]),
SyscallNo::WRITE => sys_write(args[0], args[1] as *const u8, args[2]),
SyscallNo::READV => sys_readv(args[0], args[1] as *mut IoVec, args[2]),
SyscallNo::WRITEV => sys_writev(args[0], args[1] as *const IoVec, args[2]),
SyscallNo::OPEN => sys_open(
args[0] as i32,
args[1] as *const u8,
args[2] as u32,
args[3] as i32,
),
SyscallNo::CLOSE => sys_close(args[0]),
SyscallNo::PIPE => sys_pipe(args[0] as *mut u32),
SyscallNo::GETCWD => sys_getcwd(args[0] as *mut u8, args[1]),
SyscallNo::FCNTL64 => sys_fcntl64(args[0], args[1], args[2]),
// epoll
SyscallNo::EPOLL_CREATE => epoll::sys_epoll_create(args[0]),
SyscallNo::EPOLL_CTL => epoll::sys_epoll_ctl(
args[0] as i32,
args[1] as i32,
args[2] as i32,
args[3] as *const EpollEvent,
),
SyscallNo::EPOLL_WAIT => epoll::sys_epoll_wait(
args[0] as i32,
args[1] as *mut EpollEvent,
args[2] as i32,
args[3] as i32,
),
//socket
SyscallNo::SOCKET => sys_socket(args[0], args[1], args[2]),
SyscallNo::SENDTO => sys_sendto(
args[0],
args[1] as *const u8,
args[2],
args[3] as i32,
args[4] as *const u8,
args[5],
),
SyscallNo::RECVFROM => sys_recvfrom(
args[0],
args[1] as *mut u8,
args[2],
args[3] as i32,
args[4] as *mut u8,
args[5] as *mut u32,
),
SyscallNo::BIND => sys_bind(args[0], args[1] as *const u8, args[2]),
SyscallNo::LISTEN => sys_listen(args[0], args[1]),
SyscallNo::CONNECT => sys_connect(args[0], args[1] as *const u8, args[2]),
SyscallNo::ACCEPT => sys_accept4(
args[0],
args[1] as *mut u8,
args[2] as *mut u32,
args[3] as i32,
),
SyscallNo::ACCEPT4 => sys_accept4(
args[0],
args[1] as *mut u8,
args[2] as *mut u32,
args[3] as i32,
), |
Beta Was this translation helpful? Give feedback.
-
将 Redis 直接放到 ArceOS 中编译的结果
其他记录
|
Beta Was this translation helpful? Give feedback.
-
目前对 redis-server 编译通过,这个分支 下进入redis目录编译,编译命令在 redis_readme 里面有写 |
Beta Was this translation helpful? Give feedback.
-
处理了除 |
Beta Was this translation helpful? Give feedback.
-
这个分支 完成了对 redis 的静态编译以及匹配当前 build 框架,在 ArceOS 根目录下执行 |
Beta Was this translation helpful? Give feedback.
-
redis 启动(通常OS)
详细的 log 见 here,它所在的这个分支 test_redis_syscall 也是可以直接进行测试的。
redis server 启动
按 "./redis-server /redis.conf"启动
其中配置文件内容为:
server 端的 syscall 输出大致概括如下
mmap:仅申请空间。有两种形态
prot=[PROT_READ | PROT_WRITE] flags=[MAP_PRIVATE | MAP_ANONYMOUS]
和prot=[(empty)] flags=[MAP_PRIVATE | MAP_ANONYMOUS]
sigaction / sigprocmask 等设置:涉及
SIGHUP = 1,
SIGINT = 2,
SIGILL = 4,
SIGABRT = 6,
SIGBUS = 7,
SIGFPE = 8,
SIGSEGV = 11,
SIGPIPE = 13,
SIGTERM = 15,
有3个 clone:
创建线程
mprotect:三句对应上面的三个线程:
每次 clone 之前,先用空权限 mmap 获取一段内存,然后 mprotect 中间一段,前后各剩下一截。
其他 syscall:fs 和 socket 相关,详细见具体 log。其他比较有特点的有:umask / pipe / getcwd / ioctl / sysinfo / prlimit64
启动后的等待循环
server 会在自己的时间片反复调用
clock_gettime / epoll_wait / futex / open
进行检查redis client 连接后
由于 maturin 中没有接到 qemu 往外走的网络驱动,所以这里需要以
./redis-server /redis.conf &
后台启动,将输入还给 busybox shell。同时,由于 server 端启动后有上述的等待循环,所以从这里开始把
clock_gettime / epoll_wait / futex / open
这四个 syscall 的输出关掉了。mmap:也是只有
prot=[PROT_READ | PROT_WRITE] flags=[MAP_PRIVATE | MAP_ANONYMOUS]
一些常规 syscall
有两个 syscall 被内核忽视,直接返回0:
getpeername / madvise
redis client 进行KV存取
比较简单,每次操作基本就是 mmap / munmap 然后读写文件(文件已被 epoll 设置好映射)。
目前还不清楚为什么每次都要 mmap,可能是它把每次 transaction 都当成新程序去跑?
redis client 进行其他操作
PING
:和上面一致CONFIG GET *
:和上面区别不大,多了getcwd
info
:和上面区别不大,多了uname
madvise
save
:将表写入 fs。fsync / renameat2 / fdatasync
。其中fdatasync
我没有实现;fsync
有实现但 redis 使用时是之后直接接close
,所以可能不是必要的。通过 kill 退出 server
这里的操作是,先通过 quit 退出 client,然后通过(busybox 给 server 发)结束进程信号退出。
这里调用了 sigreturn,此外和上述的写入 fs 的情况区别不大。
Beta Was this translation helpful? Give feedback.
All reactions