Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
chickadee
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Incidents
Environments
Packages & Registries
Packages & Registries
Package Registry
Container Registry
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Elon Bontemps
chickadee
Commits
2e1d8076
Commit
2e1d8076
authored
Jan 26, 2021
by
Eddie Kohler
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Initial handout code for 2021.
parent
00bfb093
Changes
26
Hide whitespace changes
Inline
Side-by-side
Showing
26 changed files
with
823 additions
and
285 deletions
+823
-285
GNUmakefile
GNUmakefile
+15
-11
README.md
README.md
+45
-12
bootentry.S
bootentry.S
+3
-3
build/quietobjcopy.sh
build/quietobjcopy.sh
+11
-0
build/rules.mk
build/rules.mk
+3
-1
docker/Dockerfile
docker/Dockerfile
+102
-0
docker/README.md
docker/README.md
+119
-0
k-apic.hh
k-apic.hh
+2
-2
k-chkfsiter.hh
k-chkfsiter.hh
+12
-12
k-devices.cc
k-devices.cc
+25
-12
k-devices.hh
k-devices.hh
+12
-10
k-exception.S
k-exception.S
+15
-7
k-hardware.cc
k-hardware.cc
+33
-12
k-memviewer.cc
k-memviewer.cc
+26
-8
k-proc.cc
k-proc.cc
+2
-2
k-vmiter.cc
k-vmiter.cc
+33
-6
k-vmiter.hh
k-vmiter.hh
+119
-65
kernel.cc
kernel.cc
+29
-15
kernel.hh
kernel.hh
+21
-18
lib.cc
lib.cc
+18
-4
lib.hh
lib.hh
+74
-57
p-sh.cc
p-sh.cc
+10
-4
p-testwritefs2.cc
p-testwritefs2.cc
+2
-2
run-docker
run-docker
+74
-0
u-lib.cc
u-lib.cc
+7
-4
u-lib.hh
u-lib.hh
+11
-18
No files found.
GNUmakefile
View file @
2e1d8076
...
...
@@ -3,7 +3,8 @@ all: $(QEMUIMAGEFILES)
# Place local configuration options, such as `CC=clang`, in
# `config.mk` so you don't have to list them every time.
-include
config.mk
CONFIG
?=
config.mk
-include
$(CONFIG)
# `$(V)` controls whether the makefiles print verbose commands (the shell
# commands run by Make) or brief commands (like `COMPILE`).
...
...
@@ -33,6 +34,9 @@ QEMUOPT = -net none -parallel $(LOG) -smp $(NCPU)
ifeq
($(D),1)
QEMUOPT
+=
-d
int,cpu_reset,guest_errors
-no-reboot
endif
ifneq
($(NOGDB),1)
QEMUGDB
?=
-gdb
tcp::12949
endif
# Sets of object files
...
...
@@ -47,7 +51,7 @@ KERNEL_OBJS = $(OBJDIR)/k-exception.ko \
$(OBJDIR)
/k-ahci.ko
$(OBJDIR)
/k-chkfs.ko
$(OBJDIR)
/k-chkfsiter.ko
\
$(OBJDIR)
/k-memviewer.ko
$(OBJDIR)
/lib.ko
$(OBJDIR)
/k-initfs.ko
PROCESSES
=
$(
patsubst
%.cc,%,
$(
wildcard
p-
*
.cc
))
PROCESSES
?
=
$(
patsubst
%.cc,%,
$(
wildcard
p-
*
.cc
))
PROCESS_LIB_OBJS
=
$(OBJDIR)
/lib.uo
$(OBJDIR)
/u-lib.uo
$(OBJDIR)
/crc32c.uo
...
...
@@ -107,7 +111,7 @@ $(OBJDIR)/bootentry.o: $(OBJDIR)/%.o: \
$(OBJDIR)/%.uo
:
%.cc $(BUILDSTAMPS)
$(
call
cxxcompile,
$(CXXFLAGS)
-O1
-DCHICKADEE_PROCESS
-c
$<
-o
$@
,COMPILE
$<
)
$(OBJDIR)/%.uo
:
%.S $(OBJDIR)/u-asm.h $(
KERNEL
BUILDSTAMPS)
$(OBJDIR)/%.uo
:
%.S $(OBJDIR)/u-asm.h $(BUILDSTAMPS)
$(
call
assemble,-O2
-c
$<
-o
$@
,ASSEMBLE
$<
)
...
...
@@ -150,7 +154,7 @@ $(OBJDIR)/kernel: $(OBJDIR)/kernel.full $(OBJDIR)/mkchickadeesymtab
$(OBJDIR)/%
:
$(OBJDIR)/%.full
$(
call
run,
$(OBJDUMP)
-C
-S
-j
.text
-j
.ctors
$<
>
$@
.asm
)
$(
call
run,
$(NM)
-n
$<
>
$@
.sym
)
$(
call
run,
$(OBJCOPY)
-j
.text
-j
.rodata
-j
.data
-j
.bss
-j
.ctors
-j
.init_array
$<
,STRIP,
$@
)
$(
call
run,
$(
QUIET
OBJCOPY)
-j
.text
-j
.rodata
-j
.data
-j
.bss
-j
.ctors
-j
.init_array
$<
,STRIP,
$@
)
$(OBJDIR)/bootsector
:
$(BOOT_OBJS) boot.ld
$(
call
link
,-T boot.ld
-o
$@
.full
$(BOOT_OBJS)
,LINK
)
...
...
@@ -174,7 +178,7 @@ $(OBJDIR)/%.o: build/%.cc $(BUILDSTAMPS)
$(
call
run,
$(HOSTCXX)
$(CPPFLAGS)
$(HOSTCXXFLAGS)
$(DEPCFLAGS)
-c
-o
$@
,HOSTCOMPILE,
$<
)
$(OBJDIR)/mkchickadeefs
:
build/mkchickadeefs.cc $(BUILDSTAMPS)
$(
call
run,
$(HOSTCXX)
$(CPPFLAGS)
$(HOSTCXXFLAGS)
$(DEPCFLAGS)
-o
$@
,HOSTCOMPILE,
$<
)
$(
call
run,
$(HOSTCXX)
$(CPPFLAGS)
$(HOSTCXXFLAGS)
$(DEPCFLAGS)
-
g
-
o
$@
,HOSTCOMPILE,
$<
)
CHICKADEEFSCK_OBJS
=
$(OBJDIR)
/chickadeefsck.o
\
$(OBJDIR)
/journalreplayer.o
\
...
...
@@ -212,12 +216,12 @@ QEMUIMG = -M q35 \
run
:
run-$(QEMUDISPLAY)
@
:
run-g
raphic
:
$(QEMUIMAGEFILES) check-qemu
@
echo
'* Run `gdb -x build/chickadee.gdb` to connect gdb to qemu.'
1>&2
$(
call
run,
$(QEMU_PRELOAD)
$(QEMU)
$(QEMUOPT)
-gdb
tcp::12949
$(QEMUIMG)
,QEMU
$<
)
run-console
:
$(QEMUIMAGEFILES) check-qemu-console
@
echo
'* Run `gdb -x build/chickadee.gdb` to connect gdb to qemu.'
1>&2
$(
call
run,
$(QEMU)
$(QEMUOPT)
-curses
-gdb
tcp::12949
$(QEMUIMG)
,QEMU
$<
)
run-g
db-report
:
@
if
test
"
$(QEMUGDB)
"
=
"-gdb tcp::12949"
;
then
echo
'* Run `gdb -x build/weensyos.gdb` to connect gdb to qemu.'
1>&2
;
fi
run-graphic
:
$(QEMUIMAGEFILES) check-qemu run-gdb-report
$(
call
run,
$(QEMU_PRELOAD)
$(QEMU)
$(QEMUOPT)
$(QEMUGDB)
$(QEMUIMG)
,QEMU
$<
)
run-console
:
$(QEMUIMAGEFILES) check-qemu-console run-gdb-report
$(
call
run,
$(QEMU)
$(QEMUOPT)
-curses
$(QEMUGDB)
$(QEMUIMG)
,QEMU
$<
)
run-monitor
:
$(QEMUIMAGEFILES) check-qemu
$(
call
run,
$(QEMU_PRELOAD)
$(QEMU)
$(QEMUOPT)
-monitor
stdio
$(QEMUIMG)
,QEMU
$<
)
run-gdb
:
run-gdb-$(QEMUDISPLAY)
...
...
README.md
View file @
2e1d8076
...
...
@@ -9,13 +9,16 @@ Quickstart: `make run` or `make run-PROGRAM`
Make targets
------------
Run
`make NCPU=N run`
to run with
`N`
virtual CPUs (default is 2).
`make NCPU=N run`
will run the OS with
`N`
virtual CPUs (default is 2). Close
the QEMU window, or type
`q`
inside it, to exit the OS.
Run
`make SAN=1 run`
to run with sanitizers
.
`make run-console`
will run the OS in the console window
.
Normally Chickadee’s debug log is written to
`log.txt`
. Run
`make LOG=stdio
run`
to redirect the debug log to the standard output, or
`make
LOG=file:FILENAME run`
to redirect it to
`FILENAME`
.
`make SAN=1 run`
to run with sanitizers enabled.
Normally Chickadee’s debug log is written to
`log.txt`
.
`make LOG=stdio run`
will redirect the debug log to the standard output, and
`make
LOG=file:FILENAME run`
will redirect it to
`FILENAME`
.
Run
`make D=1 run`
to ask QEMU to print verbose information about interrupts
and CPU resets to the standard error. This setting will also cause QEMU to
...
...
@@ -29,6 +32,36 @@ default is `alloc`.
Troubleshooting
---------------
There are several ways to kill a recalcitrant QEMU (for instance, if your
OS has become unresponsive).
*
If QEMU is running in its own graphical window, then close the window. This
will kill the embedded OS.
*
If QEMU is running in a terminal window (in Docker, for instance), then
press
`Alt-2`
. This will bring up the QEMU Monitor, which looks like this:
```
compat_monitor0 console
QEMU 4.2.0 monitor - type 'help' for more information
(qemu)
```
Type `quit` and hit Return to kill the embedded OS and return to your
shell. If this leaves the terminal looking funny, enter the `reset` shell
command to restore it.
If `Alt-2` does not work, you may need to configure your terminal to
properly send the Alt key. For instance, on Mac OS X’s Terminal, go to
Terminal > Preferences > Keyboard and select “Use Option as Meta key”. You
can also configure a special keyboard shortcut that sends the `Escape 2`
sequence.
Run
`make run-gdb`
to start up the OS with support for GDB debugging. This
will start the OS, but not GDB. You must run
`gdb -x build/weensyos.gdb`
to
connect to the running emulator; when GDB connects, it will stop the OS and
wait for instructions.
If you experience runtime errors involving
`obj/libqemu-nograb.so.1`
, put
`QEMU_PRELOAD_LIBRARY=`
in
`config.mk`
. This disables a shim we use that
prevents QEMU from grabbing the mouse.
...
...
@@ -41,7 +74,7 @@ Source files
| File | Description |
| --------------- | ---------------------------- |
|
`types.h`
| Type definitions |
|
`lib.hh/cc`
| C
hickadee C library
|
|
`lib.hh/cc`
| C
library
|
|
`x86-64.h`
| x86-64 hardware definitions |
|
`elf.h`
| ELF64 structures |
...
...
@@ -103,11 +136,11 @@ The main output of the build process is a disk image,
could conceivably boot on real hardware! The build process also
produces other files that can be useful to examine.
| File
| Description |
| --------------------------
--
| ------------------------------------ |
|
`obj/kernel.asm`
| Kernel assembly (with addresses) |
|
`obj/kernel.sym`
| Kernel defined symbols |
|
`obj/p-
allocator
.asm`
,
`sym`
| Same for process binaries |
| File | Description |
| -------------------------- | ------------------------------------ |
|
`obj/kernel.asm`
| Kernel assembly (with addresses) |
|
`obj/kernel.sym`
| Kernel defined symbols |
|
`obj/p-
PROCESS
.asm`
,
`sym`
| Same for process binaries |
[
CS 161
]:
https://read.seas.harvard.edu/cs161/202
0
/
[
CS 161
]:
https://read.seas.harvard.edu/cs161/202
1
/
[
triple fault
]:
https://en.wikipedia.org/wiki/Triple_fault
bootentry.S
View file @
2e1d8076
...
...
@@ -59,9 +59,9 @@ init_boot_pagetable:
rep
stosl
#
set
up
boot
page
table
#
0x1000
:
L
1
page
table
; entries 0, 256, and 511 point to:
#
0x2000
:
L
2
page
table
; entries 0 and 510 map 1st 1GB of physmem
#
This
weird
setup
is
the
minimal
page
table
that
maps
all
of
#
0x1000
:
L
4
page
table
; entries 0, 256, and 511 point to:
#
0x2000
:
L
3
page
table
; entries 0 and 510 map 1st 1GB of physmem
#
This
is
the
minimal
page
table
that
maps
all
of
#
low
-
canonical
,
high
-
canonical
,
and
kernel
-
text
addresses
to
#
the
first
1
GB
of
physical
memory
.
movl
$BOOT_PAGETABLE
,
%
edi
...
...
build/quietobjcopy.sh
0 → 100755
View file @
2e1d8076
#! /bin/sh
onexit
()
{
test
-n
"
$tmp
"
&&
rm
-f
"
$tmp
"
}
trap
onexit 0
tmp
=
`
mktemp
/tmp/objcopy.XXXXXX
`
"
$@
"
2>
$tmp
v
=
$?
cat
$tmp
|
grep
-v
"empty loadable segment"
1>&2
exit
$v
build/rules.mk
View file @
2e1d8076
...
...
@@ -60,6 +60,8 @@ LDFLAGS := $(LDFLAGS) -Os --gc-sections -z max-page-size=0x1000 \
-static
-nostdlib
-nostartfiles
LDFLAGS
+=
$(
shell
$(LD)
-m
elf_x86_64
--help
>
/dev/null 2>&1
&&
echo
-m
elf_x86_64
)
QUIETOBJCOPY
=
sh build/quietobjcopy.sh
$(OBJCOPY)
# Dependencies
DEPSDIR
:=
.deps
...
...
@@ -154,7 +156,7 @@ always:
# These targets don't correspond to files
.PHONY
:
all always clean realclean distclean cleanfs fsck
\
run run-graphic run-console run-monitor
\
run-gdb run-gdb-graphic run-gdb-console
\
run-gdb run-gdb-graphic run-gdb-console
run-gdb-report
\
check-qemu-console check-qemu kill
\
run-% run-graphic-% run-console-% run-monitor-%
\
run-gdb-% run-gdb-graphic-% run-gdb-console-%
...
...
docker/Dockerfile
0 → 100644
View file @
2e1d8076
FROM
ubuntu:focal
# set environment variables for tzdata
ARG
TZ=America/New_York
ENV
TZ ${TZ}
# include manual pages and documentation
RUN
DEBIAN_FRONTEND
=
noninteractive apt-get update
&&
yes
| unminimize
# install GCC-related packages
RUN
DEBIAN_FRONTEND
=
noninteractive apt-get
-y
install
\
binutils-doc
\
cpp-doc
\
gcc-doc
\
g++
\
g++-multilib
\
gdb
\
gdb-doc
\
glibc-doc
\
libblas-dev
\
liblapack-dev
\
liblapack-doc
\
libstdc++-10-doc
\
make
\
make-doc
# install clang-related packages
RUN
DEBIAN_FRONTEND
=
noninteractive apt-get
-y
install
\
clang
\
clang-10-doc
\
lldb
# install qemu for pset 4 (sadly, this pulls in a lot of crap)
RUN
DEBIAN_FRONTEND
=
noninteractive apt-get
-y
install
\
qemu-system-x86
# install programs used for system exploration
RUN
DEBIAN_FRONTEND
=
noninteractive apt-get
-y
install
\
blktrace
\
linux-tools-generic
\
strace
\
tcpdump
# install interactive programs (emacs, vim, nano, man, sudo, etc.)
RUN
DEBIAN_FRONTEND
=
noninteractive apt-get
-y
install
\
bc
\
curl
\
dc
\
emacs-nox
\
git
\
git-doc
\
man
\
micro
\
nano
\
sudo
\
vim
\
wget
# set up libraries
RUN
DEBIAN_FRONTEND
=
noninteractive apt-get
-y
install
\
libreadline-dev
\
locales
\
wamerican
# install programs used for networking
RUN
DEBIAN_FRONTEND
=
noninteractive apt-get
-y
install
\
dnsutils
\
inetutils-ping
\
net-tools
\
netcat
\
telnet
\
traceroute
# set up default locale
RUN
locale-gen en_US.UTF-8
ENV
LANG en_US.UTF-8
# remove unneeded .deb files
RUN
rm
-r
/var/lib/apt/lists/
*
# set up passwordless sudo for user cs61-user
RUN
useradd
-m
-s
/bin/bash cs61-user
&&
\
echo
"cs61-user ALL=(ALL:ALL) NOPASSWD: ALL"
>
/etc/sudoers.d/cs61-init
# create binary reporting version of dockerfile
RUN
(
echo
'#\!/bin/sh'
;
echo
'echo 5'
)
>
/usr/bin/cs61-docker-version
;
chmod
ugo+rx,u+w,go-w /usr/bin/cs61-docker-version
# git build arguments
ARG
USER=CS61\ User
ARG
EMAIL=nobody@example.com
# configure your environment
USER
cs61-user
RUN
git config
--global
user.name
"
${
USER
}
"
&&
\
git config
--global
user.email
"
${
EMAIL
}
"
&&
\
(
echo
"(custom-set-variables"
;
echo
" '(c-basic-offset 4)"
;
echo
" '(indent-tabs-mode nil))"
)
>
~/.emacs
&&
\
(
echo
"set expandtab"
;
echo
"set shiftwidth=4"
;
echo
"set softtabstop=4"
)
>
~/.vimrc
&&
\
echo
"add-auto-load-safe-path ~"
>
~/.gdbinit
WORKDIR
/home/cs61-user
# Initial version of this Dockerfile by Todd Morrill, CS 61 DCE student
docker/README.md
0 → 100644
View file @
2e1d8076
CS 61/161 Docker
================
> **tl;dr**:
> * `docker build -t cs61:latest -f Dockerfile .` to build a Docker image
> * `docker system prune -a` to remove old Docker images
The
[
Docker
][]
container-based virtualization service lets you run a
minimal CS 161 environment, including a virtual Linux host, on a Mac
OS X or Windows host, without the overhead of a full virtual machine
solution like
[
VMware Workstation
][]
,
[
VMware Fusion
][]
, or
[
VirtualBox
][]
.
It should be possible to do
*all*
CS 161 problem sets on CS 61 Docker.
(However, you may prefer to set up a local environent.)
Advantages of Docker:
*
Docker can start and stop virtual machines incredibly quickly.
*
Docker-based virtual machines are leaner and take less space on your
machine.
*
With Docker, you can easily
*edit*
your code in your home
*environment, but compile and run*
it on a Linux host.
Disadvantages of Docker:
*
Docker does not offer a full graphical environment. You will need to
run QEMU exclusively in the terminal.
*
Docker technology is less user-friendly than virtual machines.
You’ll have to type weird commands.
*
It will run slower.
## Preparing CS 161 Docker
To prepare to build your Docker environment:
1.
Download and install
[
Docker
][]
.
2.
Clone a copy of the
[
chickadee repository
][]
.
3.
Change into the
`chickadee/docker`
directory.
To build your Docker environment, run this command. It will take a couple
minutes. You’ll want to re-run this command every time the Docker image
changes, but later runs should be much faster since they’ll take advantage of
your previous work.
```
shellsession
$ docker build -t cs61:latest -f Dockerfile .
```
## Running Docker by script
The Chickadee repository contains a
`run-docker`
script that
provides good arguments and boots Docker into a view of the current
directory.
For example:
```
shellsession
$ cd ~/chickadee
$ ./run-docker
cs61-user@a47f05ea5085:~/chickadee$ echo Hello, Linux
Hello, Linux
cs61-user@a47f05ea5085:~/chickadee$ exit
exit
$
```
The script plonks you into a virtual machine! A prompt like
`cs61-user@a47f05ea5085:~$`
means that your terminal is connected to the VM.
You can execute any commands you want. To escape from the VM, type Control-D
or run the
`exit`
command.
The script assumes your Docker container is named
`cs61:latest`
, as it
was above.
### Running Docker by hand
If you don’t want to use the script, use a command like the following.
```
shellsession
$ docker run -it --rm -v ~/chickadee:/home/cs61-user/chickadee cs61:latest
```
Explanation:
*
`docker run`
tells Docker to start a new virtual machine.
*
`-it`
says Docker should run interactively (
`-i`
) using a terminal (
`-t`
).
*
`--rm`
says Docker should remove the virtual machine when it is done.
*
`-v LOCALDIR:LINUXDUR`
says Docker should share a directory between your
host and the Docker virtual machine. Here, I’ve asked for the host’s
`~/chickadee`
directory to be mapped inside the virtual machine onto the
`/home/cs61-user/chickadee`
directory, which is the virtual machine
user’s
`~/chickadee`
directory.
*
`cs61:latest`
names the Docker image to run (namely, the one you built).
Here’s an example session:
```
shellsession
$ docker run -it --rm -v ~/chickadee:/home/cs61-user/chickadee cs61:latest
cs61-user@a15e6c4c8dbe:~$ ls
cs61-lectures
cs61-user@a15e6c4c8dbe:~$ echo "Hello, world"
Hello, world
cs61-user@a15e6c4c8dbe:~$ cs61-docker-version
3
cs61-user@a15e6c4c8dbe:~$ exit
exit
$
```
[
Docker
]:
https://docker.com/
[
VMware Workstation
]:
https://www.vmware.com/products/workstation-player.html
[
VMware Fusion
]:
https://www.vmware.com/products/fusion.html
[
VirtualBox
]:
https://www.virtualbox.org/
[
Chickadee repository
]:
https://github.com/cs161/chickadee/
k-apic.hh
View file @
2e1d8076
...
...
@@ -136,7 +136,7 @@ class ioapicstate {
inline
lapicstate
&
lapicstate
::
get
()
{
return
*
reinterpret_cast
<
lapicstate
*>
(
pa2ka
(
lapic_pa
)
);
return
*
pa2kptr
<
lapicstate
*>
(
lapic_pa
);
}
inline
uint32_t
lapicstate
::
id
()
const
{
return
read
(
reg_id
)
>>
24
;
...
...
@@ -168,7 +168,7 @@ inline void lapicstate::write(int reg, uint32_t v) {
}
inline
ioapicstate
&
ioapicstate
::
get
()
{
return
*
reinterpret_cast
<
ioapicstate
*>
(
pa2ka
(
ioapic_pa
)
);
return
*
pa2kptr
<
ioapicstate
*>
(
ioapic_pa
);
}
inline
uint32_t
ioapicstate
::
id
()
const
{
return
read
(
reg_id
)
>>
24
;
...
...
k-chkfsiter.hh
View file @
2e1d8076
...
...
@@ -8,21 +8,21 @@ class chkfs_fileiter {
static
constexpr
size_t
blocksize
=
chkfs
::
blocksize
;
//
initialize an iterator for `ino` at file offset `off`
//
Initialize an iterator for `ino` at file offset `off`.
// The caller must have a reference on `ino`.
chkfs_fileiter
(
chkfs
::
inode
*
ino
,
off_t
off
=
0
);
NO_COPY_OR_ASSIGN
(
chkfs_fileiter
);
~
chkfs_fileiter
();
//
r
eturn the inode
//
R
eturn the inode
inline
chkfs
::
inode
*
inode
()
const
;
//
r
eturn the current file offset
//
R
eturn the current file offset
inline
off_t
offset
()
const
;
//
r
eturn true iff the offset is within the file (i.e., in some extent)
//
R
eturn true iff the offset is within the file (i.e., in some extent)
inline
bool
active
()
const
;
//
return true iff the offset points
at data
inline
bool
present
()
const
;
//
Return true iff the offset does not point
at data
inline
bool
empty
()
const
;
// Return the block number corresponding to the current file offset.
// Returns 0 if there is no block stored for the current offset.
...
...
@@ -30,15 +30,15 @@ class chkfs_fileiter {
// Return a buffer cache entry containing the current file offset’s data.
// Returns nullptr if there is no block stored for the current offset.
inline
bcentry
*
get_disk_entry
()
const
;
//
r
eturn the file offset relative to the current block
//
R
eturn the file offset relative to the current block
inline
unsigned
block_relative_offset
()
const
;
// Move the iterator to file offset `off`. Returns `*this`.
chkfs_fileiter
&
find
(
off_t
off
);
// Like `find(offset() + delta)`
.
// Like `find(offset() + delta)`
inline
chkfs_fileiter
&
operator
+=
(
ssize_t
delta
);
// Like `find(offset() - delta)`
.
// Like `find(offset() - delta)`
inline
chkfs_fileiter
&
operator
-=
(
ssize_t
delta
);
...
...
@@ -104,11 +104,11 @@ inline bool chkfs_fileiter::active() const {
inline
unsigned
chkfs_fileiter
::
block_relative_offset
()
const
{
return
off_
%
blocksize
;
}
inline
bool
chkfs_fileiter
::
present
()
const
{
return
eptr_
&&
eptr_
->
first
!
=
0
;
inline
bool
chkfs_fileiter
::
empty
()
const
{
return
!
eptr_
||
eptr_
->
first
=
=
0
;
}
inline
auto
chkfs_fileiter
::
blocknum
()
const
->
blocknum_t
{
if
(
eptr_
&&
eptr_
->
first
!=
0
)
{
if
(
!
empty
()
)
{
return
eptr_
->
first
+
(
off_
-
eoff_
)
/
blocksize
;
}
else
{
return
0
;
...
...
k-devices.cc
View file @
2e1d8076
...
...
@@ -27,7 +27,7 @@
#define KEY_NUMLOCK 0xFE
#define KEY_SCROLLLOCK 0xFF
#define CKEY(cn)
0x80 + cn
#define CKEY(cn)
(0x80 + cn)
static
const
uint8_t
keymap
[
256
]
=
{
/*0x00*/
0
,
033
,
CKEY
(
0
),
CKEY
(
1
),
CKEY
(
2
),
CKEY
(
3
),
CKEY
(
4
),
CKEY
(
5
),
...
...
@@ -122,10 +122,6 @@ int keyboard_readc() {
// the global `keyboardstate` singleton
keyboardstate
keyboardstate
::
kbd
;
keyboardstate
::
keyboardstate
()
:
pos_
(
0
),
len_
(
0
),
eol_
(
0
),
state_
(
boot
)
{
}
void
keyboardstate
::
handle_interrupt
()
{
auto
irqs
=
lock_
.
lock
();
...
...
@@ -209,22 +205,39 @@ void keyboardstate::consume(size_t n) {
consolestate
consolestate
::
console
;
// console
_show_
cursor()
// console
state::
cursor()
// Displays the console cursor at the current `cursorpos` position.
void
console_show_cursor
()
{
static
std
::
atomic
<
int
>
displayed_cpos
=
-
1
;
static
spinlock
cursor_lock
;
void
consolestate
::
cursor
()
{
int
cpos
=
cursorpos
;
if
(
cpos
>=
0
&&
cpos
<
CONSOLE_ROWS
*
CONSOLE_COLUMNS
&&
displayed_cpos
.
load
(
std
::
memory_order_relaxed
)
!=
cpos
)
{
spinlock_guard
guard
(
cursor_lock
);
&&
cursor_show_
.
load
(
std
::
memory_order_relaxed
)
&&
displayed_cpos_
.
load
(
std
::
memory_order_relaxed
)
!=
cpos
)
{
spinlock_guard
guard
(
cursor_lock_
);
outb
(
0x3D4
,
15
);
outb
(
0x3D5
,
cpos
%
256
);
outb
(
0x3D4
,
14
);
outb
(
0x3D5
,
cpos
/
256
);
displayed_cpos
=
cpos
;
displayed_cpos_
=
cpos
;
}
}
// consolestate::cursor(show)
// Enables or disables the cursor depending on `show`.
void
consolestate
::
cursor
(
bool
show
)
{
{
spinlock_guard
guard
(
cursor_lock_
);
cursor_show_
.
store
(
show
,
std
::
memory_order_relaxed
);
outb
(
0x3D4
,
10
);
outb
(
0x3D5
,
show
?
0x0E
:
0x20
);
outb
(
0x3D4
,
11
);
outb
(
0x3D5
,
show
?
0x0F
:
0x20
);
}
if
(
show
)
{
cursor
();
}
}
...
...
k-devices.hh
View file @
2e1d8076
...
...
@@ -2,11 +2,6 @@
#define CHICKADEE_K_DEVICES_HH
#include "kernel.hh"
// console_show_cursor()
// Displays the console cursor to the current position (`cursorpos`).
void
console_show_cursor
();
// keyboardstate: keyboard buffer and keyboard interrupts
#define KEY_UP 0xC0
...
...
@@ -23,10 +18,10 @@ void console_show_cursor();
struct
keyboardstate
{
spinlock
lock_
;
char
buf_
[
256
];
unsigned
pos_
;
// next position to read
unsigned
len_
;
// number of characters in buffer
unsigned
eol_
;
// position in buffer of most recent \n
enum
{
boot
,
input
,
fail
}
state_
;
unsigned
pos_
=
0
;
// next position to read
unsigned
len_
=
0
;
// number of characters in buffer
unsigned
eol_
=
0
;
// position in buffer of most recent \n
enum
{
boot
,
input
,
fail
}
state_
=
boot
;
static
keyboardstate
&
get
()
{
return
kbd
;
...
...
@@ -46,7 +41,7 @@ struct keyboardstate {
private:
static
keyboardstate
kbd
;
keyboardstate
();
keyboardstate
()
=
default
;
void
maybe_echo
(
int
ch
);
};
...
...
@@ -61,9 +56,16 @@ struct consolestate {
return
console
;
}
void
cursor
();
void
cursor
(
bool
show
);
private:
static
consolestate
console
;
consolestate
()
=
default
;
spinlock
cursor_lock_
;
std
::
atomic
<
bool
>
cursor_show_
=
true
;
std
::
atomic
<
int
>
displayed_cpos_
=
-
1
;
};
...
...
k-exception.S
View file @
2e1d8076
...
...
@@ -172,11 +172,11 @@ restore_and_iret:
testb
$
1
,
12
(%
rsp
)
//
`
reg_swapgs
&
1
`
jnz
1
f
//
return
ing
to
kernel
mode
//
return
to
kernel
mode
addq
$
24
,
%
rsp
iretq
1
:
//
return
ing
to
user
mode
1
:
//
return
to
user
mode
cli
//
prevent
interr