forked from xuos/xiuos
Merge branch 'smp' of https://gitlink.org.cn/tuyuyang/xiuos into lwip
This commit is contained in:
commit
a66d833cea
|
@ -1,2 +1,22 @@
|
|||
# XIZI_AIOT
|
||||
### XiZi_AIoT Microkernel
|
||||
|
||||
XiZi_AIoT is a microkernel designed to facilitate task management, memory management, IPC, and various userland sample applications.
|
||||
|
||||
### Building Instructions
|
||||
|
||||
To build the XiZi_AIoT microkernel, navigate to the directory xiuos/Ubiquitous/XiZi_AIoT and run the command `make BOARD=$(BOARD)`. By default, running `make` is equivalent to `make BOARD=imx6q-sabrelite`. For building XiZi_AIoT specifically for the imx6q-sabrelite board, you'll need the gcc-arm-none-eabi toolchain. We recommend using version "arm-none-eabi-gcc (GNU Tools for ARM Embedded Processors 6-2017-q1-update) 6.3.1 20170215 (release)", as this version was used during development. If the build process is successful, the generated files can be found in the "build" directory. Use either XiZi-$(BOARD).elf or XiZi-$(BOARD).bin as the image to run on the board or QEMU.
|
||||
|
||||
### Running on QEMU
|
||||
|
||||
QEMU is a useful tool for emulating boards while testing or developing XiZi_AIoT. Use the following command:
|
||||
|
||||
```
|
||||
qemu-system-arm -M sabrelite -m 1G -smp 4 -cpu cortex-a9 \
|
||||
-display none -serial null -serial stdio \
|
||||
-kernel xiuos/Ubiquitous/XiZi_AIoT/build/XiZi-imx6q-sabrelite.elf
|
||||
```
|
||||
Replace "xiuos/Ubiquitous/XiZi_AIoT/build/XiZi-imx6q-sabrelite.elf" with the appropriate path in your directory. We recommend using version "QEMU emulator version 7.2.0" for successful emulation of the sabrelite board.
|
||||
|
||||
### Makefile Usage
|
||||
|
||||
XiZi_AIoT utilizes a Makefile to build all its files, including .c and .S files. The compiler.mk file enables the make tool to iterate through all sub-directories defined by *SRC_DIR* and compile files defined by *SRC_FILES* using parameters defined in config.mk. Each board independently defines its config.mk file in hardkernel/arch/.../config.mk. Additionally, path_kernel.mk defines all include paths needed by XiZi_AIoT, and link.mk manages the linking process after all .c and .S files are compiled.
|
|
@ -26,7 +26,7 @@ INC_DIR = -I$(KERNEL_ROOT)/services/shell/letter-shell \
|
|||
-I$(KERNEL_ROOT)/services/app
|
||||
|
||||
ifeq ($(BOARD), imx6q-sabrelite)
|
||||
all: init test_fs simple_client simple_server shell fs_server test_irq_hdlr test_irq_block test_irq_send eth_driver timer_server readme.txt | bin
|
||||
all: init test_fs simple_client simple_server shell fs_server test_irq_hdlr test_irq_block test_irq_send eth_driver epit_server readme.txt | bin
|
||||
else
|
||||
all: init test_fs simple_client simple_server shell fs_server test_irq_hdlr readme.txt | bin
|
||||
endif
|
||||
|
@ -47,7 +47,7 @@ eth_driver: enet_drv.o enet_test.o board_network.o enet_iomux_config.o imx6dq_gp
|
|||
@${ld} ${user_ldflags} -e main -o $@ $^ ${board_specs}
|
||||
@${objdump} -S $@ > $@.asm
|
||||
|
||||
timer_server: timer.o epit.o ccm_pll.o usyscall.o arch_usyscall.o libserial.o printf.o libipc.o session.o
|
||||
epit_server: timer.o epit.o ccm_pll.o usyscall.o arch_usyscall.o libserial.o printf.o libipc.o session.o
|
||||
@${ld} ${user_ldflags} -e main -o $@ $^ ${board_specs}
|
||||
@${objdump} -S $@ > $@.asm
|
||||
endif
|
||||
|
|
|
@ -28,7 +28,7 @@ int main(int argc, char* argv[])
|
|||
char* shell_task_param[2] = { "/shell", 0 };
|
||||
if ((fd = open(&session, shell_task_param[0])) < 0) {
|
||||
printf("Open %s failed\n", shell_task_param[0]);
|
||||
exit();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (spawn(&session, fd, read, fsize, shell_task_param[0], shell_task_param) < 0) {
|
||||
|
@ -37,6 +37,6 @@ int main(int argc, char* argv[])
|
|||
|
||||
close(&session, fd);
|
||||
|
||||
exit();
|
||||
exit(0);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "libfs_to_client.h"
|
||||
#include "libserial.h"
|
||||
|
@ -90,7 +91,7 @@ int main(int argc, char** argv)
|
|||
struct Session session_nowait;
|
||||
if (connect_session(&session_wait, "SimpleServer", 4096) < 0 || connect_session(&session_nowait, "SimpleServer", 4096) < 0) {
|
||||
printf("connect session failed\n");
|
||||
exit();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
char *buf1 = NULL, *buf2 = NULL;
|
||||
|
@ -138,5 +139,5 @@ int main(int argc, char** argv)
|
|||
free_session(&session_wait);
|
||||
free_session(&session_nowait);
|
||||
|
||||
exit();
|
||||
exit(0);
|
||||
}
|
||||
|
|
|
@ -38,10 +38,10 @@ int main(int argc, char* argv[])
|
|||
{
|
||||
if (register_server("SimpleServer") < 0) {
|
||||
printf("register server name: %s failed.\n", "SimpleServer");
|
||||
exit();
|
||||
exit(1);
|
||||
}
|
||||
ipc_server_loop(&IpcSimpleServer);
|
||||
|
||||
// never reached
|
||||
exit();
|
||||
exit(0);
|
||||
}
|
||||
|
|
|
@ -48,6 +48,6 @@ int main(int argc, char* argv[])
|
|||
printf("Test memry error %s.\n", 0x50000000);
|
||||
printf("After error computing.\n");
|
||||
|
||||
exit();
|
||||
exit(0);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -24,12 +24,12 @@ int main(int argc, char* argv[])
|
|||
struct Session session;
|
||||
if (connect_session(&session, "TestIRQ", 4096) < 0) {
|
||||
printf("connect session failed\n");
|
||||
exit();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
printf("%s start waiting for IRQ.\n", prog_name);
|
||||
wait_intr(&session);
|
||||
printf("%s return from waiting for IRQ.\n", prog_name);
|
||||
|
||||
exit();
|
||||
exit(0);
|
||||
}
|
|
@ -40,16 +40,16 @@ int main()
|
|||
{
|
||||
if (register_irq(SW_INTERRUPT_3, Ipc_intr_3) < 0) {
|
||||
printf("TEST_SW_HDLR: bind failed");
|
||||
exit();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static char prog_name[] = "TestIRQ";
|
||||
if (register_server("TestIRQ") < 0) {
|
||||
printf("register server name: %s failed.\n", prog_name);
|
||||
exit();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
ipc_server_loop(&IpcSwIntrHandler);
|
||||
|
||||
exit();
|
||||
exit(0);
|
||||
}
|
|
@ -39,6 +39,6 @@ int main(int argc, char* argv[])
|
|||
// test function
|
||||
count_down();
|
||||
|
||||
exit();
|
||||
exit(0);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -96,5 +96,5 @@ int main()
|
|||
printf("%s: Soft interrupt send 1 time\n", prog_name);
|
||||
}
|
||||
printf("%s: Soft interrupt send done\n", prog_name);
|
||||
exit();
|
||||
exit(0);
|
||||
}
|
|
@ -109,20 +109,21 @@ void system_time_init(void)
|
|||
|
||||
int IPC_DO_SERVE_FUNC(Ipc_delay_us)(uint32_t* usecs)
|
||||
{
|
||||
// uint32_t instance = g_system_timer_port;
|
||||
// if (*usecs == 0) {
|
||||
// return 0;
|
||||
// }
|
||||
uint32_t instance = g_system_timer_port;
|
||||
if (*usecs == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// /* enable the counter first */
|
||||
// epit_counter_enable(instance, *usecs, POLLING_MODE);
|
||||
/* enable the counter first */
|
||||
epit_counter_enable(instance, *usecs, POLLING_MODE);
|
||||
|
||||
// /* wait for the compare event */
|
||||
// while (!epit_get_compare_event(instance))
|
||||
// ;
|
||||
/* wait for the compare event */
|
||||
while (!epit_get_compare_event(instance)) {
|
||||
yield(SYS_TASK_YIELD_NO_REASON);
|
||||
}
|
||||
|
||||
// /* disable the counter to save power */
|
||||
// epit_counter_disable(instance);
|
||||
/* disable the counter to save power */
|
||||
epit_counter_disable(instance);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -177,7 +178,7 @@ int main(int argc, char** argv)
|
|||
static char server_name[] = "TimerServer";
|
||||
if (register_server(server_name) < 0) {
|
||||
printf("register server name %s failed\n", server_name);
|
||||
exit();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static uint32_t epit_instance = HW_EPIT2;
|
||||
|
@ -187,7 +188,7 @@ int main(int argc, char** argv)
|
|||
|
||||
ipc_server_loop(&IpcSabreliteTimer);
|
||||
|
||||
exit();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -18,7 +18,7 @@ cflags = -std=c11 -march=armv7-a -mcpu=cortex-a9 -mtune=cortex-a9 -g \
|
|||
# cflags = -std=c11 -march=armv7-a -mtune=cortex-a9 -nostdlib -nodefaultlibs -mfloat-abi=soft -fno-pic \
|
||||
# -static -fno-builtin -fno-strict-aliasing -Wall -ggdb -Wno-unused -Werror -fno-omit-frame-pointer -fno-stack-protector -fno-pie
|
||||
|
||||
c_useropts = -O2
|
||||
c_useropts = -O0
|
||||
|
||||
INC_DIR = -I$(KERNEL_ROOT)/services/app \
|
||||
-I$(KERNEL_ROOT)/services/boards/$(BOARD) \
|
||||
|
|
|
@ -555,8 +555,6 @@ void imx_enet_start(imx_enet_priv_t* dev, unsigned char* enaddr)
|
|||
dev->tx_busy = 0;
|
||||
dev->enet_reg->ECR.U |= ENET_ETHER_EN | ENET_ETHER_SPEED_1000M | ENET_ETHER_LITTLE_ENDIAN;
|
||||
dev->enet_reg->RDAR.U |= ENET_RX_TX_ACTIVE;
|
||||
HW_ENET_RDAR_WR(ENET_RX_TX_ACTIVE);
|
||||
printf("addr1: %x, addr2: %x\n", &dev->enet_reg->RDAR.U, HW_ENET_RDAR_ADDR);
|
||||
printf("EIR: %08x, ECR: %08x, TDAR.U: %08x, RDAR.U: %08x (%08x)\n", dev->enet_reg->EIR.U, dev->enet_reg->ECR.U, dev->enet_reg->TDAR.U, dev->enet_reg->RDAR.U, ENET_RX_TX_ACTIVE);
|
||||
}
|
||||
|
||||
|
|
|
@ -145,7 +145,6 @@ void print_hw_enet(const hw_enet_t* enet)
|
|||
*/
|
||||
int enet_test()
|
||||
{
|
||||
|
||||
imx_enet_priv_t* dev0 = &enet0;
|
||||
int pkt_len_send = 0, pkt_len_recv = 0, ret = 0, i;
|
||||
unsigned int enet_events = 0;
|
||||
|
@ -251,23 +250,23 @@ int main(int argc, char** argv)
|
|||
{
|
||||
if (connect_session(&timer_session, timer_server_name, 4096) < 0) {
|
||||
printf("%s connect server: %s failed\n", enet_server_name, timer_server_name);
|
||||
exit();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
printf("%s: Mapping %08x(size: %x) to %08x\n", enet_server_name, AIPS1_ARB_PHY_BASE_ADDR, AIPS1_ARB_END_ADDR - AIPS1_ARB_BASE_ADDR, AIPS1_ARB_BASE_ADDR);
|
||||
if (!mmap(AIPS1_ARB_BASE_ADDR, AIPS1_ARB_PHY_BASE_ADDR, AIPS1_ARB_END_ADDR - AIPS1_ARB_BASE_ADDR, true)) {
|
||||
printf("%s: mmap AIPS1 ARB(%8x) failed\n", enet_server_name, AIPS1_ARB_PHY_BASE_ADDR);
|
||||
exit();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
printf("%s: Mapping %08x(size: %x) to %8x\n", enet_server_name, AIPS2_ARB_PHY_BASE_ADDR, AIPS2_ARB_END_ADDR - AIPS2_ARB_BASE_ADDR, AIPS2_ARB_BASE_ADDR);
|
||||
if (!mmap(AIPS2_ARB_BASE_ADDR, AIPS2_ARB_PHY_BASE_ADDR, AIPS2_ARB_END_ADDR - AIPS2_ARB_BASE_ADDR, true)) {
|
||||
printf("%s: mmap AIPS1 ARB(%08x) failed\n", enet_server_name, AIPS2_ARB_PHY_BASE_ADDR);
|
||||
exit();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
enet_test();
|
||||
|
||||
exit();
|
||||
exit(0);
|
||||
return 0;
|
||||
}
|
|
@ -358,10 +358,10 @@ int main(int argc, char* argv[])
|
|||
|
||||
if (register_server("MemFS") < 0) {
|
||||
printf("register server name: %s failed.\n", "MemFs");
|
||||
exit();
|
||||
exit(1);
|
||||
}
|
||||
ipc_server_loop(&IpcFsServer);
|
||||
|
||||
// never reached
|
||||
exit();
|
||||
exit(0);
|
||||
}
|
||||
|
|
|
@ -18,12 +18,13 @@
|
|||
|
||||
// Block size
|
||||
#define BLOCK_SIZE 512
|
||||
#define NR_BIT_BLOCKS 2
|
||||
|
||||
// bits size
|
||||
#define BITS 8
|
||||
|
||||
// Bitmap size of one block
|
||||
#define BITMAP_SIZE (BLOCK_SIZE * BITS)
|
||||
#define BITMAP_SIZE (BLOCK_SIZE * BITS * NR_BIT_BLOCKS)
|
||||
|
||||
// Inode size of one block
|
||||
#define INODE_SIZE (BLOCK_SIZE / sizeof(struct Inode))
|
||||
|
|
|
@ -77,6 +77,7 @@ struct SuperBlock {
|
|||
uint32_t size; // Number of total blocks of file system image
|
||||
uint32_t nblocks; // Number of data blocks
|
||||
uint32_t ninodes; // Number of inodes.
|
||||
uint32_t nbitblocks;
|
||||
};
|
||||
|
||||
// Inode structure
|
||||
|
|
|
@ -145,6 +145,7 @@ int ipc_session_wait(struct Session* session)
|
|||
}
|
||||
|
||||
static int cur_sess_id = -1;
|
||||
static struct IpcMsg* ipc_server_loop_cur_msg = NULL;
|
||||
int cur_session_id(void)
|
||||
{
|
||||
return cur_sess_id;
|
||||
|
@ -161,6 +162,20 @@ bool is_cur_session_delayed(void)
|
|||
return session_delayed;
|
||||
}
|
||||
|
||||
bool is_cur_handler_been_delayed()
|
||||
{
|
||||
if (ipc_server_loop_cur_msg == NULL) {
|
||||
return false;
|
||||
}
|
||||
return ipc_server_loop_cur_msg->header.delayed == 1;
|
||||
}
|
||||
|
||||
bool server_set_cycle_handler(struct IpcNode* ipc_node, void (*handler)())
|
||||
{
|
||||
ipc_node->cycle_handler = handler;
|
||||
return true;
|
||||
}
|
||||
|
||||
void ipc_server_loop(struct IpcNode* ipc_node)
|
||||
{
|
||||
struct Session session_list[NR_MAX_SESSION];
|
||||
|
@ -183,39 +198,43 @@ void ipc_server_loop(struct IpcNode* ipc_node)
|
|||
break;
|
||||
}
|
||||
cur_sess_id = session_list[i].id;
|
||||
struct IpcMsg* msg = IPCSESSION_MSG(&session_list[i]);
|
||||
ipc_server_loop_cur_msg = IPCSESSION_MSG(&session_list[i]);
|
||||
/* handle every message in current session
|
||||
a session could be delay in case one of its message(current message) needs to wait for an interrupt message's arrival
|
||||
interfaces[opcode] should explicitly call delay_session() and return to delay this session
|
||||
*/
|
||||
while (msg->header.magic == IPC_MSG_MAGIC && msg->header.valid == 1 && msg->header.done == 0) {
|
||||
while (ipc_server_loop_cur_msg->header.magic == IPC_MSG_MAGIC && ipc_server_loop_cur_msg->header.valid == 1 && ipc_server_loop_cur_msg->header.done == 0) {
|
||||
// printf("session %d [%d, %d]\n", session_list[i].id, session_list[i].head, session_list[i].tail);
|
||||
if (session_used_size(&session_list[i]) == 0 && session_forward_tail(&session_list[i], msg->header.len) < 0) {
|
||||
if (session_used_size(&session_list[i]) == 0 && session_forward_tail(&session_list[i], ipc_server_loop_cur_msg->header.len) < 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
// this is a message needs to handle
|
||||
if (ipc_node->interfaces[msg->header.opcode]) {
|
||||
ipc_node->interfaces[msg->header.opcode](msg);
|
||||
if (ipc_node->interfaces[ipc_server_loop_cur_msg->header.opcode]) {
|
||||
ipc_node->interfaces[ipc_server_loop_cur_msg->header.opcode](ipc_server_loop_cur_msg);
|
||||
// check if this session is delayed by op handler, all messages after the delayed message in current session is blocked.
|
||||
if (is_cur_session_delayed()) {
|
||||
msg->header.delayed = 1;
|
||||
ipc_server_loop_cur_msg->header.delayed = 1;
|
||||
has_delayed = true;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
printf("Unsupport opcode(%d) for server: %s\n", msg->header.opcode, ipc_node->name);
|
||||
printf("Unsupport opcode(%d) for server: %s\n", ipc_server_loop_cur_msg->header.opcode, ipc_node->name);
|
||||
}
|
||||
// current msg is a message that needs to ignore
|
||||
// finish this message in server's perspective
|
||||
if (session_forward_head(&session_list[i], msg->header.len) < 0) {
|
||||
if (session_forward_head(&session_list[i], ipc_server_loop_cur_msg->header.len) < 0) {
|
||||
break;
|
||||
}
|
||||
msg = IPCSESSION_MSG(&session_list[i]);
|
||||
ipc_server_loop_cur_msg = IPCSESSION_MSG(&session_list[i]);
|
||||
}
|
||||
// stop handle this session
|
||||
cur_sess_id = -1;
|
||||
ipc_server_loop_cur_msg = NULL;
|
||||
}
|
||||
}
|
||||
if (ipc_node->cycle_handler) {
|
||||
ipc_node->cycle_handler();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -76,6 +76,7 @@ typedef int (*IpcInterface)(struct IpcMsg* msg);
|
|||
struct IpcNode {
|
||||
char* name;
|
||||
IpcInterface interfaces[UINT8_MAX];
|
||||
void (*cycle_handler)();
|
||||
} __attribute__((packed));
|
||||
|
||||
#define IPC_SERVER_LOOP(ipc_node_name) rpc_server_loop_##rpc_node_name
|
||||
|
@ -242,4 +243,6 @@ bool is_cur_session_delayed(void);
|
|||
}
|
||||
|
||||
int cur_session_id(void);
|
||||
void delay_session(void);
|
||||
bool server_set_cycle_handler(struct IpcNode* ipc_node, void (*handler)());
|
||||
void delay_session(void);
|
||||
bool is_cur_handler_been_delayed();
|
|
@ -26,9 +26,9 @@ int spawn(struct Session* session, int fd, ipc_read_fn ipc_read, ipc_fsize_fn ip
|
|||
return ret;
|
||||
}
|
||||
|
||||
int exit()
|
||||
void exit(int status)
|
||||
{
|
||||
return syscall(SYSCALL_EXIT, 0, 0, 0, 0);
|
||||
syscall(SYSCALL_EXIT, (uintptr_t)status, 0, 0, 0);
|
||||
}
|
||||
|
||||
int yield(task_yield_reason reason)
|
||||
|
|
|
@ -65,7 +65,7 @@ typedef int (*ipc_write_fn)(struct Session* session, int fd, char* src, int offs
|
|||
int syscall(int sys_num, intptr_t a1, intptr_t a2, intptr_t a3, intptr_t a4);
|
||||
|
||||
int spawn(struct Session* session, int fd, ipc_read_fn ipc_read, ipc_fsize_fn ipc_fsize, char* name, char** argv);
|
||||
int exit();
|
||||
void exit(int status);
|
||||
int yield(task_yield_reason reason);
|
||||
int kill(int pid);
|
||||
int register_server(char* name);
|
||||
|
|
|
@ -52,7 +52,7 @@ Modification:
|
|||
|
||||
int fsfd;
|
||||
struct SuperBlock sb;
|
||||
char zeroes[512];
|
||||
char zeroes[BLOCK_SIZE];
|
||||
uint freeblock;
|
||||
uint usedblocks;
|
||||
uint bitblocks;
|
||||
|
@ -93,7 +93,7 @@ int main(int argc, char* argv[])
|
|||
int i, cc, fd;
|
||||
uint rootino, inum, off;
|
||||
struct DirEntry de;
|
||||
char buf[512];
|
||||
char buf[BLOCK_SIZE];
|
||||
struct Inode din;
|
||||
int size, nblocks;
|
||||
|
||||
|
@ -104,8 +104,8 @@ int main(int argc, char* argv[])
|
|||
exit(1);
|
||||
}
|
||||
|
||||
assert((512 % sizeof(struct Inode)) == 0);
|
||||
assert((512 % sizeof(struct DirEntry)) == 0);
|
||||
assert((BLOCK_SIZE % sizeof(struct Inode)) == 0);
|
||||
assert((BLOCK_SIZE % sizeof(struct DirEntry)) == 0);
|
||||
|
||||
fsfd = open(argv[1], O_RDWR | O_CREAT | O_TRUNC, 0666);
|
||||
if (fsfd < 0) {
|
||||
|
@ -114,7 +114,7 @@ int main(int argc, char* argv[])
|
|||
}
|
||||
|
||||
size = nr_blocks_total;
|
||||
bitblocks = size / (512 * 8) + 1;
|
||||
bitblocks = NR_BIT_BLOCKS;
|
||||
usedblocks = 2 + (nr_inodes / INODE_SIZE + 1) + bitblocks;
|
||||
nblocks = nr_blocks_total - usedblocks;
|
||||
freeblock = usedblocks;
|
||||
|
@ -122,6 +122,7 @@ int main(int argc, char* argv[])
|
|||
sb.size = xint(size);
|
||||
sb.nblocks = xint(nblocks);
|
||||
sb.ninodes = xint(nr_inodes);
|
||||
sb.nbitblocks = xint(NR_BIT_BLOCKS);
|
||||
|
||||
printf("block 0 is unused, block 1 is for super block, used %d (bit %d ninode %zu) free %u total %d\n", usedblocks,
|
||||
bitblocks, nr_inodes / INODE_SIZE + 1, size - usedblocks, nblocks + usedblocks);
|
||||
|
@ -192,11 +193,11 @@ int main(int argc, char* argv[])
|
|||
|
||||
void wsect(uint sec, void* buf)
|
||||
{
|
||||
if (lseek(fsfd, sec * 512L, 0) != sec * 512L) {
|
||||
if (lseek(fsfd, sec * BLOCK_SIZE, 0) != sec * BLOCK_SIZE) {
|
||||
perror("lseek");
|
||||
exit(1);
|
||||
}
|
||||
if (write(fsfd, buf, 512) != 512) {
|
||||
if (write(fsfd, buf, BLOCK_SIZE) != BLOCK_SIZE) {
|
||||
perror("write");
|
||||
exit(1);
|
||||
}
|
||||
|
@ -209,7 +210,7 @@ uint i2b(uint inum)
|
|||
|
||||
void winode(uint inum, struct Inode* ip)
|
||||
{
|
||||
char buf[512];
|
||||
char buf[BLOCK_SIZE];
|
||||
uint bn;
|
||||
struct Inode* dip;
|
||||
|
||||
|
@ -222,7 +223,7 @@ void winode(uint inum, struct Inode* ip)
|
|||
|
||||
void rinode(uint inum, struct Inode* ip)
|
||||
{
|
||||
char buf[512];
|
||||
char buf[BLOCK_SIZE];
|
||||
uint bn;
|
||||
struct Inode* dip;
|
||||
|
||||
|
@ -234,11 +235,11 @@ void rinode(uint inum, struct Inode* ip)
|
|||
|
||||
void rsect(uint sec, void* buf)
|
||||
{
|
||||
if (lseek(fsfd, sec * 512L, 0) != sec * 512L) {
|
||||
if (lseek(fsfd, sec * BLOCK_SIZE, 0) != sec * BLOCK_SIZE) {
|
||||
perror("lseek");
|
||||
exit(1);
|
||||
}
|
||||
if (read(fsfd, buf, 512) != 512) {
|
||||
if (read(fsfd, buf, BLOCK_SIZE) != BLOCK_SIZE) {
|
||||
perror("read");
|
||||
exit(1);
|
||||
}
|
||||
|
@ -259,17 +260,18 @@ uint ialloc(ushort type)
|
|||
|
||||
void balloc(int used)
|
||||
{
|
||||
uchar buf[512];
|
||||
uchar buf[BLOCK_SIZE];
|
||||
int i;
|
||||
|
||||
printf("balloc: first %d blocks have been allocated\n", used);
|
||||
assert(used < 512 * 8);
|
||||
bzero(buf, 512);
|
||||
for (i = 0; i < used; i++) {
|
||||
buf[i / 8] = buf[i / 8] | (0x1 << (i % 8));
|
||||
bzero(buf, BLOCK_SIZE);
|
||||
for (int bmsec = 0; bmsec < bitblocks; bmsec++) {
|
||||
for (i = 0; i < ((used > NR_BIT_PER_BYTE * BLOCK_SIZE) ? NR_BIT_PER_BYTE * BLOCK_SIZE : used); i++) {
|
||||
buf[i / NR_BIT_PER_BYTE] = buf[i / NR_BIT_PER_BYTE] | (0x1 << (i % NR_BIT_PER_BYTE));
|
||||
}
|
||||
printf("balloc: write bitmap block at sector %zu\n", nr_inodes / INODE_SIZE + 3 + bmsec);
|
||||
wsect(nr_inodes / INODE_SIZE + 3 + bmsec, buf);
|
||||
used -= NR_BIT_PER_BYTE * BLOCK_SIZE;
|
||||
}
|
||||
printf("balloc: write bitmap block at sector %zu\n", nr_inodes / INODE_SIZE + 3);
|
||||
wsect(nr_inodes / INODE_SIZE + 3, buf);
|
||||
}
|
||||
|
||||
#define min(a, b) ((a) < (b) ? (a) : (b))
|
||||
|
@ -279,7 +281,7 @@ void iappend(uint inum, void* xp, int n)
|
|||
char* p = (char*)xp;
|
||||
uint fbn, off, n1;
|
||||
struct Inode din;
|
||||
char buf[512];
|
||||
char buf[BLOCK_SIZE];
|
||||
uint indirect[NR_INDIRECT_BLOCKS * MAX_INDIRECT_BLOCKS];
|
||||
uint x;
|
||||
|
||||
|
@ -287,7 +289,7 @@ void iappend(uint inum, void* xp, int n)
|
|||
|
||||
off = xint(din.size);
|
||||
while (n > 0) {
|
||||
fbn = off / 512;
|
||||
fbn = off / BLOCK_SIZE;
|
||||
assert(fbn < MAX_FILE_SIZE);
|
||||
assert(usedblocks < nr_blocks_total);
|
||||
if (fbn < NR_DIRECT_BLOCKS) {
|
||||
|
@ -315,9 +317,9 @@ void iappend(uint inum, void* xp, int n)
|
|||
x = xint(indirect[idx]);
|
||||
}
|
||||
}
|
||||
n1 = min(n, (fbn + 1) * 512 - off);
|
||||
n1 = min(n, (fbn + 1) * BLOCK_SIZE - off);
|
||||
rsect(x, buf);
|
||||
bcopy(p, buf + off - (fbn * 512), n1);
|
||||
bcopy(p, buf + off - (fbn * BLOCK_SIZE), n1);
|
||||
wsect(x, buf);
|
||||
n -= n1;
|
||||
off += n1;
|
||||
|
|
|
@ -48,8 +48,9 @@ Modification:
|
|||
|
||||
#define ROOT_INUM 1 // root inode number
|
||||
#define BLOCK_SIZE 512 // block size
|
||||
#define BITMAP_SIZE 1024
|
||||
#define nr_blocks_total 8192 // total number of blocks (including used blocks and free blocks)
|
||||
#define NR_BIT_PER_BYTE 8
|
||||
#define NR_BIT_BLOCKS 2
|
||||
#define nr_blocks_total (BLOCK_SIZE * NR_BIT_PER_BYTE * NR_BIT_BLOCKS) // total number of blocks (including used blocks and free blocks)
|
||||
#define nr_inodes 200 // total number of inodes
|
||||
|
||||
#define NR_DIRECT_BLOCKS 4
|
||||
|
@ -70,6 +71,7 @@ struct SuperBlock {
|
|||
uint size; // Size of file system image (blocks)
|
||||
uint nblocks; // Number of data blocks
|
||||
uint ninodes; // Number of inodes.
|
||||
uint nbitblocks;
|
||||
};
|
||||
|
||||
// Inode structure
|
||||
|
|
Loading…
Reference in New Issue