Skip to content

Commit e9030c5

Browse files
authored
Merge pull request #3 from junqi-xie/lab3
Complete User Environments
2 parents a83ed3c + 50a7856 commit e9030c5

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

80 files changed

+6150
-47
lines changed

CMakeLists.txt

+18
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ set(CHCORE_ARCH "aarch64")
88

99
mark_as_advanced(CMAKE_INSTALL_PREFIX)
1010

11+
if(TEST)
12+
add_definitions("-DTEST=${TEST}")
13+
endif()
14+
1115
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
1216
add_definitions("-DLOG_LEVEL=2")
1317
else ()
@@ -33,16 +37,25 @@ project (chos C ASM)
3337

3438
set(BOOTLOADER_PATH "boot")
3539
set(KERNEL_PATH "${CMAKE_CURRENT_SOURCE_DIR}/kernel")
40+
set(USER_PATH "${CMAKE_CURRENT_SOURCE_DIR}/user")
3641

3742

3843
set(KERNEL_ARCH_PATH "${KERNEL_PATH}")
3944
set(KERNEL_MM_PATH "${KERNEL_PATH}/mm")
45+
set(KERNEL_SYSCALL_PATH "${KERNEL_PATH}/syscall")
46+
set(KERNEL_EXCEPTION_PATH "${KERNEL_PATH}/exception")
47+
set(KERNEL_PROCESS_PATH "${KERNEL_PATH}/process")
48+
set(KERNEL_SCHED_PATH "${KERNEL_PATH}/sched")
4049

4150
include_directories(".")
4251
include_directories("${KERNEL_PATH}")
4352

4453
add_subdirectory("${KERNEL_ARCH_PATH}")
4554
add_subdirectory("${KERNEL_MM_PATH}")
55+
add_subdirectory("${KERNEL_PROCESS_PATH}")
56+
add_subdirectory("${KERNEL_SYSCALL_PATH}")
57+
add_subdirectory("${KERNEL_EXCEPTION_PATH}")
58+
add_subdirectory("${KERNEL_SCHED_PATH}")
4659

4760
set(BINARY_KERNEL_IMG_PATH "CMakeFiles/kernel.img.dir")
4861
set(init_object
@@ -62,6 +75,11 @@ include("${BOOTLOADER_PATH}/config.cmake")
6275
add_executable(kernel.img ${files}
6376
$<TARGET_OBJECTS:${PROJECT_NAME}-arch>
6477
$<TARGET_OBJECTS:${PROJECT_NAME}-mm>
78+
$<TARGET_OBJECTS:${PROJECT_NAME}-object>
79+
$<TARGET_OBJECTS:${PROJECT_NAME}-syscall>
80+
$<TARGET_OBJECTS:${PROJECT_NAME}-sched>
81+
$<TARGET_OBJECTS:${PROJECT_NAME}-exception>
82+
${USER_PATH}/binary_include.S
6583
)
6684

6785
set_property(

Makefile

+19-3
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,22 @@ ifndef QEMU
33
QEMU := qemu-system-aarch64
44
endif
55

6-
LAB := 2
6+
LAB := 3
77
# try to generate a unique GDB port
88
GDBPORT := 1234
99
QEMUOPTS = -machine raspi3 -serial null -serial mon:stdio -m size=1G -kernel $(BUILD_DIR)/kernel.img -gdb tcp::1234
1010
IMAGES = $(BUILD_DIR)/kernel.img
1111

12-
all: build
12+
all: user build
1313

1414
gdb:
1515
gdb-multiarch -n -x .gdbinit
1616

1717
build: FORCE
18-
./scripts/docker_build.sh
18+
./scripts/docker_build.sh $(bin)
19+
20+
user: FORCE
21+
./scripts/docker_build_user.sh
1922

2023
qemu: $(IMAGES)
2124
$(QEMU) $(QEMUOPTS)
@@ -46,5 +49,18 @@ clean:
4649
@rm -rf build
4750
@rm -rf chcore.out
4851

52+
prep-%:
53+
@echo "*** Now building application $*"
54+
./scripts/docker_build.sh $*
55+
./scripts/create_gdbinit.sh $*
56+
57+
run-%: prep-%
58+
@echo "*** Now starting qemu"
59+
$(QEMU) $(QEMUOPTS)
60+
61+
run-%-gdb: prep-%
62+
@echo "*** Now starting qemu-gdb"
63+
$(QEMU) $(QEMUOPTS) -S
64+
4965
.PHONY: FORCE
5066
FORCE:

kernel/CMakeLists.txt

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
cmake_minimum_required(VERSION 3.14)
22

3-
add_library(${PROJECT_NAME}-arch OBJECT
3+
add_library(${PROJECT_NAME}-arch process
44
head.S
55
main.c
66
monitor.c
77
common/tools.S
8+
common/cpio.c
9+
common/elf.c
810
common/uart.c
911
common/printk.c
10-
mm/page_table.S
12+
common/radix.c
1113
)

kernel/common/bitops.h

+107
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
/*
2+
* Copyright (c) 2020 Institute of Parallel And Distributed Systems (IPADS), Shanghai Jiao Tong University (SJTU)
3+
* OS-Lab-2020 (i.e., ChCore) is licensed under the Mulan PSL v1.
4+
* You can use this software according to the terms and conditions of the Mulan PSL v1.
5+
* You may obtain a copy of Mulan PSL v1 at:
6+
* http://license.coscl.org.cn/MulanPSL
7+
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
8+
* IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
9+
* PURPOSE.
10+
* See the Mulan PSL v1 for more details.
11+
*/
12+
13+
#pragma once
14+
15+
#define BITS_PER_BYTE 8
16+
#define BITS_PER_LONG (sizeof(unsigned long) * BITS_PER_BYTE)
17+
#define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_LONG)
18+
19+
#define get_bit_in_slot(u64slot, bit) ((u64slot) & (1UL<<(bit)))
20+
21+
#define clear_bit_in_slot(u64slot, bit) ((u64slot) = (u64slot) & ~(1UL<<(bit)))
22+
23+
#define set_bit_in_slot(u64slot, bit) ((u64slot) = (u64slot) | (1UL<<(bit)))
24+
25+
/* set No'nr bit to 1 in slot pointed by p */
26+
static inline void set_bit(unsigned int nr, volatile unsigned long *p)
27+
{
28+
unsigned nlongs = nr / BITS_PER_LONG;
29+
unsigned ilongs = nr % BITS_PER_LONG;
30+
p[nlongs] |= 1UL << ilongs;
31+
}
32+
33+
/* get No'nr bit in slot pointed by p */
34+
static inline int get_bit(unsigned int nr, volatile unsigned long *p)
35+
{
36+
unsigned nlongs = nr / BITS_PER_LONG;
37+
unsigned ilongs = nr % BITS_PER_LONG;
38+
return (p[nlongs] >> ilongs) & 0x1;
39+
}
40+
41+
/* clear No'nr bit in slot pointed by p */
42+
static inline void clear_bit(unsigned int nr, volatile unsigned long *p)
43+
{
44+
unsigned nlongs = nr / BITS_PER_LONG;
45+
unsigned ilongs = nr % BITS_PER_LONG;
46+
p[nlongs] &= ~(1UL << ilongs);
47+
}
48+
49+
/* return the first zero bit start from the lowerst bit */
50+
static inline int ctzl(unsigned long x)
51+
{
52+
return x == 0 ? sizeof(x) * BITS_PER_BYTE : __builtin_ctzl(x);
53+
}
54+
55+
static inline int find_next_bit_helper(unsigned long *p, unsigned long size,
56+
unsigned long start, int invert)
57+
{
58+
long cur_elem_index, cur_bit,
59+
max_elem_index, max_bit, cur_bit_value, res = 0;
60+
61+
max_elem_index = (size - 1) / BITS_PER_LONG;
62+
cur_elem_index = start / BITS_PER_LONG;
63+
cur_bit = start % BITS_PER_LONG;
64+
res = start;
65+
66+
while (cur_elem_index <= max_elem_index) {
67+
if (cur_elem_index < max_elem_index)
68+
max_bit = BITS_PER_LONG - 1;
69+
else
70+
max_bit = (size - 1) % BITS_PER_LONG;
71+
for (; cur_bit <= max_bit; cur_bit++, res++) {
72+
cur_bit_value =
73+
get_bit_in_slot(p[cur_elem_index], cur_bit);
74+
if (invert ? !cur_bit_value : cur_bit_value)
75+
return res;
76+
}
77+
cur_elem_index++;
78+
cur_bit = 0;
79+
}
80+
return size;
81+
}
82+
83+
/*
84+
* From lowest bit side, starting from 'start',
85+
* this function find the first zero bit of the slot pointed by p.
86+
*/
87+
static inline int find_next_zero_bit(unsigned long *p, unsigned long size,
88+
unsigned long start)
89+
{
90+
return find_next_bit_helper(p, size, start, 1);
91+
}
92+
93+
/*
94+
* From lowest bit side, starting from 'start',
95+
* this function find the first bit of the slot pointed by p.
96+
*/
97+
static inline int find_next_bit(unsigned long *p, unsigned long size,
98+
unsigned long start)
99+
{
100+
return find_next_bit_helper(p, size, start, 0);
101+
}
102+
103+
/* From the first 1 bit to the last 1 bit in slot pointed by addr */
104+
#define for_each_set_bit(pos, addr, size) \
105+
for ((pos) = find_next_bit((addr), (size), 0); \
106+
(pos) < (size); \
107+
(pos) = find_next_bit((addr), (size), (pos) + 1))

kernel/common/cpio.c

+161
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
/*
2+
* Copyright (c) 2020 Institute of Parallel And Distributed Systems (IPADS), Shanghai Jiao Tong University (SJTU)
3+
* OS-Lab-2020 (i.e., ChCore) is licensed under the Mulan PSL v1.
4+
* You can use this software according to the terms and conditions of the Mulan PSL v1.
5+
* You may obtain a copy of Mulan PSL v1 at:
6+
* http://license.coscl.org.cn/MulanPSL
7+
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
8+
* IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
9+
* PURPOSE.
10+
* See the Mulan PSL v1 for more details.
11+
*/
12+
13+
#include <common/cpio.h>
14+
#include <common/macro.h>
15+
#include <common/kprint.h>
16+
#include <common/util.h>
17+
#include <common/kmalloc.h>
18+
#include <common/errno.h>
19+
20+
#define cpio_info(fmt, ...) kdebug(fmt, ## __VA_ARGS__)
21+
#define cpio_zalloc(sz) kzalloc(sz)
22+
#define cpio_free(obj) kfree(obj)
23+
24+
static u64 hex8_u64(const char s[8])
25+
{
26+
u64 u = 0;
27+
for (int i = 0; i < 8; ++i) {
28+
u <<= 4;
29+
if (s[i] >= 'A' && s[i] <= 'F')
30+
u += s[i] - 'A' + 10;
31+
else
32+
u += s[i] - '0';
33+
}
34+
return u;
35+
}
36+
37+
static int cpio_parse_header(const void *addr, struct cpio_header *header)
38+
{
39+
const struct cpio_newc_header *newc = addr;
40+
41+
cpio_info("print in text: %s\n", addr);
42+
/* headers other than newc are not supported */
43+
BUG_ON(strncmp(newc->c_magic, "070701", 6));
44+
45+
header->c_ino = hex8_u64(newc->c_ino);
46+
header->c_mode = hex8_u64(newc->c_mode);
47+
header->c_uid = hex8_u64(newc->c_uid);
48+
header->c_gid = hex8_u64(newc->c_gid);
49+
header->c_nlink = hex8_u64(newc->c_nlink);
50+
header->c_mtime = hex8_u64(newc->c_mtime);
51+
header->c_filesize = hex8_u64(newc->c_filesize);
52+
header->c_devmajor = hex8_u64(newc->c_devmajor);
53+
header->c_devminor = hex8_u64(newc->c_devminor);
54+
header->c_rdevmajor = hex8_u64(newc->c_rdevmajor);
55+
header->c_rdevminor = hex8_u64(newc->c_rdevminor);
56+
header->c_namesize = hex8_u64(newc->c_namesize);
57+
header->c_check = hex8_u64(newc->c_check);
58+
59+
cpio_info("header address is 0x%lx\n", (u64) header);
60+
return 0;
61+
}
62+
63+
int cpio_extract_file(const void *addr, const char *dirat)
64+
{
65+
return 0;
66+
}
67+
68+
void cpio_init_g_files(void)
69+
{
70+
g_files.head.next = NULL;
71+
g_files.tail = &g_files.head;
72+
}
73+
74+
static struct cpio_file *cpio_alloc_file(void)
75+
{
76+
return cpio_zalloc(sizeof(struct cpio_file));
77+
}
78+
79+
static void cpio_add_file(struct cpio_file *f)
80+
{
81+
f->next = NULL;
82+
g_files.tail->next = f;
83+
g_files.tail = f;
84+
}
85+
86+
#define ALIGN4_UP(x) ((((u64)x) & (~3llu)) + ((!!(((u64)x) & 3)) << 2))
87+
88+
void cpio_extract(const void *addr, const char *dirat)
89+
{
90+
const char *p = addr;
91+
struct cpio_file *f;
92+
int err;
93+
94+
for (;;) {
95+
f = cpio_alloc_file();
96+
if (f == NULL) {
97+
kwarn("cpio_alloc_file fails due to lack of memory.\n");
98+
return;
99+
}
100+
101+
BUG_ON(!f);
102+
103+
err = cpio_parse_header(p, &f->header);
104+
BUG_ON(err);
105+
p += sizeof(struct cpio_newc_header);
106+
107+
if (0 == strcmp(p, "TRAILER!!!")) {
108+
cpio_free(f);
109+
break;
110+
}
111+
112+
f->name = p;
113+
p += f->header.c_namesize;
114+
p = (void *)ALIGN4_UP(p);
115+
116+
f->data = p;
117+
p += f->header.c_filesize;
118+
p = (void *)ALIGN4_UP(p);
119+
120+
cpio_add_file(f);
121+
}
122+
}
123+
124+
void *cpio_extract_single(const void *addr, const char *target,
125+
void *(*cpio_single_file_filler) (const void *start,
126+
size_t size,
127+
void *data),
128+
void *data)
129+
{
130+
const char *p = addr;
131+
struct cpio_header header;
132+
const char *filename;
133+
134+
/* Skip leading '/' */
135+
target = target + 1;
136+
137+
for (;;) {
138+
int err;
139+
140+
err = cpio_parse_header(p, &header);
141+
BUG_ON(err);
142+
p += sizeof(struct cpio_newc_header);
143+
144+
if (0 == strcmp(p, "TRAILER!!!"))
145+
break;
146+
147+
filename = p;
148+
p += header.c_namesize;
149+
p = (void *)ALIGN4_UP(p);
150+
151+
if (0 == strcmp(filename, target)) {
152+
return cpio_single_file_filler(p, header.c_filesize,
153+
data);
154+
}
155+
156+
p += header.c_filesize;
157+
p = (void *)ALIGN4_UP(p);
158+
159+
}
160+
return ERR_PTR(-ENOENT);
161+
}

0 commit comments

Comments
 (0)