《操作系统原理》实验报告
Table of Contents
Don't forget to answer the sum up questions in your email message!
1 Approaching to the Linux kernel
1.2 实验步骤及思考题
1.2.1 proc file-system
- Questions
What's the CPU type and model?
/proc/cpuinfocat /proc/cpuinfo | grep model | head -2 model name : 11th Gen Intel(R) Core(TM) i5-11400H @ 2.70GHz
What version of the Linux kernel are you using?
unameuname -r 5.15.90.4-microsoft-standard-WSL2
How long has it been since your PC last booted?
uptimeuptime -p up 49 minutes
How much of the total CPU time has been spent executing in user mode? kernel mode? idle?
toptop top - 21:02:29 up 14:11, 1 user, load average: 0.00, 0.02, 0.00 %Cpu(s): 0.1 us, 0.1 sy, 0.0 ni, 99.7 id.. As above text I got, I should also find out how many cores my processor has and how long has cpus been since your PC last booted. So we can got the total CPU time has been spent executing: user mode : 0.1% * 7:32 * 12 = 5.4(minutes) kernel mode : 0.1% * 7:32 * 12 = 5.4(minutes) idle : 99.7% * 7:32 * 12 = 441.1(minutes)
How much memory is configured in your PC?
top,free,/proc/meminfofree -m
total used free shared buff/cache available Mem 7869 859 6261 3 747 6773 Swap 2048 0 2048 How much memory is currently available?
top,free,/proc/meminfo6773M
How many disk read/write requests have been made?
/proc/diskstatscat /proc/diskstats 8 0 sda 1139 433 148122 312 0 0 0 0 0 520 312 0 0 0 0 0 0 8 16 sdb 103 0 4712 35 2 0 8 12 0 70 56 0 0 0 0 1 8 8 32 sdc 17949 2499 827194 5304 21834 14325 504136 89556 0 142210 123451 496 6 238608 140 15626 28449 read requests = 433 + 0 + 2499; write requests = 0 + 0 + 14325;
How many context switches has the kernel performed?
/proc/statgrep ctxt /proc/stat 31663371
How many context switches has a process had?
/proc/[pid]/statusI choose a process which pid equels 100383. cat /proc/100383/status | grep ctxt voluntary_ctxt_switches: 331 nonvoluntary_ctxt_switches: 7 So we can get PID 100383 had *338* context switches
How many processes have been created since the system was booted?
/proc/statcat stat | grep processes processes 129854
How many processes are there in the ready queue?
/proc/statcat /proc/loadavg 0.04 0.06 0.01 1/344 134664 So there are *344* processes in the ready queue
How many processes are blocked waiting for I/O to complete?
/proc/statcat stat | grep cpu | head -1 cpu 91918 208 76901 46373253 15067 0 19846 0 0 0 So *15067* processes are blocked waiting for I/O to complete.
What does the following command do?
cd /proc/`ps | head -2 | tail -1 | cut -f1 -d' '` && ls -l First look at words in single quotation marks: Commod 'ps' report a snapshot of the current processes. Commod 'head -2' and 'tail -1' get the first process --- bash. Commod 'cut -f5 -d' '' get the first fields --- PID of bash So we can make it simpler : *cd /proc/[PID of bash]/ && ls -l* The purpose of this command is to enter the /proc/[PID of bash]/ directory and list the detailed contents of the folder.
- Sum up
In your email message, please answer the following questions.
- How many hours you spent in this section?
- It took me about 12 hours to do this.
- What's the major difficulties you met in this section?
- Not being familiar with many commands is the major difficulty I met.
- How did you solve (or try solving) them?
- Through Google, related manuals to solve this problem.
- Have you learnt anything? Or your time was just wasted?
- I gradually understood 'Everything is a file'.
- How many hours you spent in this section?
1.2.2 Play with the kernel
- 实验内容
- http://cs6.swfu.edu.cn/~wx672/lecture_notes/os/lab.html#sec-2-2
- 实验环境
- OS version:
Linux 5.15.123.1-microsoft-standard-WSL2 - Kernel source version:
WSL2-Linux-Kernel-linux-msft-wsl-5.15.y - GCC version:
gcc version 11.4.0
- OS version:
- Sum up
In your email message, please answer the following questions.
- How many hours you spent in this section?
- In lab 2 I spent about 6 hours finishing.
- What's the major difficulties you met in this section?
- It's hard to find the following "famous" code.
- How did you solve (or try solving) them?
- Google, someone's blog and the 'pahole' command helped me a lot.
- Have you learnt anything? Or your time was just wasted?
- I learned the meaning of the 'famous' code, and why they're famous.
- How many hours you spent in this section?
1.2.3 Hello, kernel Module!
- 实验内容
- http://cs6.swfu.edu.cn/~wx672/lecture_notes/os/lab.html#sec-2-3
- 实验环境
- OS version:
Linux 5.15.123.1-microsoft-standard-WSL2 - Kernel source version:
WSL2-Linux-Kernel-linux-msft-wsl-5.15.y - GCC version:
gcc version 11.4.0
- OS version:
- 实验步骤
Input command
sudo apt-get dist-upgrade sudo apt-get install linux-generic sudo apt-get install linux-headers-generic mkdir hello-lkm && cd hello-lkm
Write code
write a hello-1.c write Makefile
make Makefile
make
Install the module into the running kernel
sudo insmod hello-1.ko
- Questions
What's a kernel module?
Kernel modules are pieces of code that can be loaded and unloaded into the kernel upon demand. They extend the functionality of the kernel without the need to reboot the system.
How do modules get into the kernel?
In this lab, 'make' command generate file calls hello-1.ko. Than, install the module into the kernel sudo insmod hello-1.ko
How do you know a kernel module is loaded?
I can see what modules are already loaded into the kernel by running 'lsmod'. lsmod
Module Size Used by hello_1 16384 0 How do you know a module is working properly or not?
By running 'lsmod | grep moduleName' lsmod | grep moduleName
How do you unload a module?
By running 'sudo rmmod moduleName' sudo rmmod moduleName
in hello-1.c, what does __init, __exit mean? (include/linux/init.h)
The kernel can take __init as hint that the function is used only during the initialization phase and free up used memory resources after.
:__exit sections will be used only if module support is disabled.
why printk()? why not printf()?
printf() is a function in the GNU C Library. Kernel Space is not directly accessible to user space. So, The kernel cannot use printf().
- Sum up
In your email message, please answer the following questions.
- How many hours you spent in this section?
- I spent about 7 hours in lab 3.
- What's the major difficulties you met in this section?
- When I enter the command sudo install linux-headers-`uname -r`, there is an error in my terminal.
- How did you solve (or try solving) them?
- I searched for this in Stackoverflow. Fortunately, this problem has been solved.
- Have you learnt anything? Or your time was just wasted?
- I have learned the knowledge of kernel modules and writing a simple kernel module.
- How many hours you spent in this section?
1.2.4 System calls
- 实验内容
- http://cs6.swfu.edu.cn/~wx672/lecture_notes/os/lab.html#sec-2-4
- 实验环境
- OS version:
Linux 5.15.123.1-microsoft-standard-WSL2 - Kernel source version:
WSL2-Linux-Kernel-linux-msft-wsl-5.15.y - GCC version:
gcc version 9.4.0
- OS version:
- 实验步骤
Download the source code of the latest stable version of the Linux kernel (which is https://github.com/microsoft/WSL2-Linux-Kernel/tree/linux-msft-wsl-5.15.y) to the home folder.
cd /usr/src git clone https://github.com/microsoft/WSL2-Linux-Kernel.git cd /WSL2-Linux-Kernel-linux-msft-wsl-5.15.y
Write a basic system call in C and integrate it into the new kernel.
mkdir identity
Create a C file for the system call.
vim identity/identity.c
Write the following code in it.
#include <linux/kernel.h> #include <linux/syscalls.h> SYSCALL_DEFINE0(identity) { printk("I am Jihan Jasper Al-rashid.\n"); return 0; }Create a Makefile.
vim identity/Makefile
Write the following code in it.
obj-y := identity.o
Add the home directory of the system call to the main Makefile of the kernel.
vim Makefile
Search for
core-y. In the second result, see a series of directories.kernel/ certs/ mm/ fs/ ipc/ security/ crypto/Add the home directory of my system call at the end like the following.kernel/ certs/ mm/ fs/ ipc/ security/ crypto/ identity/
Add a corresponding function prototype for my system call to the header file of system calls.
include/linux/syscalls.h
Navigate to the bottom of it and write the following code just above #endif.
asmlinkage long sys_identity(void);
Add my system call to the kernel's system call table.
vim arch/x86/entry/syscalls/syscall_64.tbl
Go to the bottom of the first group (it ends at syscall 447 in linux-msft-wsl-5.15), and add the following line:
448 common identity sys_identity
Installation the new kernel and prepare your operating system to boot into it.
Compile the kernel's source code.
make KCONFIG_CONFIG=Microsoft/config-wsl
Prepare the installer of the kernel.
sudo make modules_install -j4
Install the kernel.
sudo make install -j4
then wait. When the compilation done, copy the compiled image to somewhere on the Windows filesystem (i.e., outside WSL).
cp arch/x86/boot/bzImage /mnt/c/Users/luoju/bzImage
Exit WSL and reboot it
write a C program to check whether the system call works or not.
vim report.c
#include <linux/kernel.h> #include <sys/syscall.h> #include <stdio.h> #include <unistd.h> #include <string.h> #include <errno.h> #define __NR_identity 440 long identity_syscall(void) { return syscall(__NR_identity); } int main(int argc, char *argv[]) { long activity; activity = identity_syscall(); if(activity < 0) { perror("Sorry, Jasper. Your system call appears to have failed."); } else { printf("Congratulations, Jasper! Your system call is functional. Run the command dmesg in the terminal and find out!\n"); } return 0; }Compile the C file.
gcc -o report report.c
Run the C file you just compiled
./report
it displays the following
Congratulations, Jasper! Your system call is functional. Run the command dmesg in the terminal and find out!Check the last line of thedmesgoutput.dmesg | tail -1
see the following
[ 4273.313106] I am Jihan Jasper Al-rashid.
- Sum up
In your email message, please answer the following questions.
- How many hours you spent in this section?
- About 7 or 8 hours
- What's the major difficulties you met in this section?
- When I try to update the bootloader of the operating system with the new kernel by using "sudo update-grub", but Ubuntu on metal while WSL2 is a lightweight virtual machine and doesn't even need it to boot.
- How did you solve (or try solving) them?
- I search this question in google. In this page(https://gist.github.com/cerebrate/d40c89d3fa89594e1b1538b2ce9d2720), I copy the 'bzImage' of the kernel which have been compiled and move it to somewhere on the Windows filesystem. Then create and modify .wslconfig.
- Have you learnt anything? Or your time was just wasted?
- I become more clear about 'image' in linux, although still abstract. Also, learned making my syscall.
- How many hours you spent in this section?
2 Process management
2.1 Process creation
- 实验内容
- http://cs6.swfu.edu.cn/~wx672/lecture_notes/os/lab.html#sec-3-1-1
- 实验环境
- OS version: (
Linux 5.15.123.1-microsoft-standard-WSL2) - Kernel source version: (
WSL2-Linux-Kernel-linux-msft-wsl-5.15.y) - GCC version: (
gcc version 11.4.0)
- OS version: (
2.1.1 实验步骤
- Using man command to get a sense of the command;
2.1.2 Questions
Both exit() and _exit() are used in the program. What's the difference?
_exit() terminates the calling process "immediately". Any open file descriptors belonging to the process are closed. exit() flushes io buffers and removes tempfile.
Tell me about the following line of code:
w = waitpid(cpid, &status, WUNTRACED | WCONTINUED);Parent process wait for state changes in a child of the calling process. Function of waitpid will return the pid of the child whose state has change, if a child has stopped or a stopped child has been resumed by delivery of SIGCONT. The status for traced children which have stopped is provided even if this option is not specified.
Compile and run the following 4 programs. Tell me what they do? And their differences:
1. To see every process on the system using BSD syntax. 2. It did the same thing as No.1. But it used execlp function to execute without system(). 3. It used 2 processes to print every process on the system using BSD syntax. 4. it used child process to execute.
more on fork() and wait()
Compile and run this program. Tell me why the output is weird (mixed with the $ prompt)? And fix it with the wait() system call.
$ ./fork_blp fork program starting This is the parent This is the child This is the child This is the parent This is the child This is the parent This is the child This is the child This is the child This is the child
Parent process created child process. But we don't know who has control over the CPU.
Fixed code
#include <sys/types.h> #include <sys/wait.h> #include <stdlib.h> #include <unistd.h> #include <stdio.h> int main() { pid_t pid; char *message; int n; int status; printf("fork program starting\n"); pid = fork(); switch(pid) { case -1: perror("fork failed"); exit(1); case 0: message = "This is the child"; n = 7; break; default: message = "This is the parent"; n = 3; wait(&status); break; } for(; n > 0; n--) { puts(message); sleep(1); } /* It's not necessasry to have both parent and child process do wait() though it doesn't hurt.*/ // wait(&status); exit(0); }- zombies and waitpid()
Read the NOTES section in the wait manual page (man 2 wait) to get a clear idea about zombie processes. And tell me why zombie is not welcomed.
As long as a zombie is not removed from the system via a wait, it will consume a slot in the kernel process table, and if this table fills, it will not be possible to create further processes.
- At the end of wait manual page (man 2 wait), there is an example program. Play with it, and tell me about
WUNTRACED,WCONTINUED,WIFEXITED,WEXITSTATUS,WIFSIGNALED,WTERMSIG,WIFSTOPPED,WSTOPSIG,WIFCONTINUED,pause().WUNTRACED
return if child has stopped.
WCONTINUED
return if a stopped child has been resumed by delivery of SIGCONT.
WIFEXITED
returns true if the child terminated normall
WEXITSTATUS
returns the exit status of the child.
WIFSIGNALED
returns true if the child process was terminated by a signal.
WTERMSIG
returns the number of the signal that caused the child process to terminate.
WIFSTOPPED
returns true if the child process was stopped by delivery of a signal.
WSTOPSIG
returns the number of the signal which caused the child to stop.
WIFCONTINUED
returns true if the child process was resumed by delivery of SIGCONT.
pause()
causes the calling process to sleep until a signal is delivered.
- Compile and run this small program. This program can leave a zombie process in the system. You can see it with
Write a similar program that leaves 5 zombies.
#include <sys/wait.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> int main(void) { pid_t pids[5]; for (int i = 4; i >= 0; --i) { pids[i] = fork(); if (pids[i] == 0) { printf("Child%d\n", i); _exit(0); } } sleep(60); return 0; }Tell me what's the difference between a zombie process and a orphan process?
A child that terminates, but has not been waited becomes a "zombie". Parent process has finished or terminated, though child process remains running itself.
Read Beginning Linux Programming (last visited: ), Chapter 11, page 503 to learn how to avoid zombies with waitpid() system call. And correct the above program.
#include <sys/wait.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> int main(void) { pid_t pids[5]; int status; for (int i = 4; i >= 0; --i) { pids[i] = fork(); if (pids[i] == 0) { printf("Child%d\n", i); _exit(0); } else { waitpid(pids[i], &status, WNOHANG); } } return 0; }Tell me the difference between exit() and return.
return returns from the current function. exit() terminates the whole process.
2.1.3 Sum up
In your email message, please answer the following questions.
- How many hours you spent in this section?
- About 5 hours.
- What's the major difficulties you met in this section?
- Poor knowledge of fork makes it difficult to program.
- How did you solve (or try solving) them?
forkmanual page- Wiki of zombie process (https://en.wikipedia.org/wiki/Zombie_process)
- Have you learnt anything? Or your time was just wasted?
- Learn how to use fork(), waitpid(), and various options of waitpid.
2.2 Thread
- 实验内容
- http://cs6.swfu.edu.cn/~wx672/lecture_notes/os/lab.html#sec-3-2
- 实验环境
- OS version: (
Linux 5.15.123.1-microsoft-standard-WSL2) - Kernel source version: (
WSL2-Linux-Kernel-linux-msft-wsl-5.15.y) - GCC version: (
gcc version 11.4.0)
- OS version: (
2.2.1 Questions
- At the end of pthread_create manual page (man 3 pthread_create), there is an example program. Play with it, and then tell me:
What's the tinfo[]?
List of tread infomation.
What's the res?
Return the value of thread_start.
- At the end of pthread_attr_init manual page (man 3 pthread_attr_init), there is an example program. Compile and run it.
Compile and run this program. Now, remove the pthread_join call, i.e. comment out line 29-32. Compile and run it again for multiple times. Tell me the difference, and why?
In the original code, the two threads will keep running unless there is an interrupt signal. When removing the pthread_join call in the code, the process will return soon without waiting for threads and kill threads which it created.
2.2.2 Sum up
In your email message, please answer the following questions.
- How many hours you spent in this section?
- About 3 hours.
- What's the major difficulties you met in this section?
- Reading example code is difficulty.
- How did you solve (or try solving) them?
- Using Google and relevant manule page.
- Have you learnt anything? Or your time was just wasted?
- The konwleage about thread.
2.3 IPC
- 实验内容
- http://cs6.swfu.edu.cn/~wx672/lecture_notes/os/lab.html#sec-3-3
- 实验环境
- OS version: (
Linux 5.15.123.1-microsoft-standard-WSL2) - Kernel source version: (
WSL2-Linux-Kernel-linux-msft-wsl-5.15.y) - GCC version: (
gcc version 11.4.0)
- OS version: (
2.3.1 Questions
- Signals
Now, tell me your understanding about the following function prototype:
void (*signal(int sig, void (*func)(int)))(int) signal(...) is a function pointer. For using the signal function, we need input a integer and a funtion pointer as arguments.
Following Beej's Guide to Unix IPC, section 3 to play with signals. And then tell me details about the following code:
int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact)"signum" specifies the signal, except SIGKILL and SIGINT... A new action is defined at "act" to handle the situation that something traps the signal. "oldact" has saved the previous action.
- Pipe
Modify pipe3.c in Beej's Guide to Unix IPC, section 4 to make the child does the wc -l, and the parent does the ls.
if (!fork()) { // parent close(1); /* close normal stdout */ dup(pfds[1]); /* make stdout same as pfds[1] */ close(pfds[0]); /* we don't need this */ execlp("ls", "ls", NULL); } else { // child close(0); /* close normal stdin */ dup(pfds[0]); /* make stdin same as pfds[0] */ close(pfds[1]); /* we don't need this */ execlp("wc", "wc", "-l", NULL); }At the end of pipe manual page (man 2 pipe), there is an example program. Compile it, run it, understand it, and then, modify the program, let parent do read, and child do write.
if (!cpid) { // parent close(pipefd[1]); while (read(pipefd[0], &buf, 1) > 0) write(STDOUT_FILENO, &buf, 1); write(STDOUT_FILENO, "\n", 1); close(pipefd[0]); _exit(EXIT_SUCCESS); } else { // child close(pipefd[0]); write(pipefd[1], argv[1], strlen(argv[1])); close(pipefd[1]); wait(NULL); exit(EXIT_SUCCESS); }
- FIFO
When you run the example programs (speak and tick), there should be a new file named american_maid appear in your working directory ($PWD). What will happen if you delete this FIFO file while the two programs running? Why?
The speak and tick will continue working. When I delete the FIFO file while the two programs running, the file still lie in the file desciptor table. I use lsof to list open files of speak, after removing american_maid.
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME s 8744 a cwd DIR 8,32 4096 19889 /home/a/.../20211152002_lab7/fifo ... s 8744 a 3w FIFO 8,32 0t0 19646 /home/a/.../20211152002_lab7/fifo/american_maid (deleted) #+end_src c - Modify the example programs to use mkfifo instead of mknod. Modifed the example programs: #+begin_src c int main(int argc, char *argv[]) { ... char * FIFO_NAME = argv[1]; ... }than
$ mkfifo a $ gcc speakModified.c -o sM & ./sM a $ gcc tickModified.c -o tM & ./tM a
Extend the example programs, and make it have 3 writers.
#include <stdio.h> #include <stdlib.h> #include <errno.h> #include <string.h> #include <fcntl.h> #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> #include <pthread.h> pthread_mutex_t lock; char s[300]; int num, fd; #define FIFO_NAME "american_maid" int cnt = 0; void* fun() { pthread_mutex_lock(&lock); int n = ++cnt; pthread_mutex_unlock(&lock); printf("%d \n", n); while(1){ gets(s); feof(stdin); num = write(fd, s, strlen(s)); printf("%d-th speak: wrote %d bytes\n", n, num); } } int main(void) { mknod(FIFO_NAME, S_IFIFO | 0666, 0); printf("waiting for readers...\n"); fd = open(FIFO_NAME, O_WRONLY); printf("got a reader--type some stuff\n"); pthread_mutex_unlock(&lock); pthread_t pids[3]; int number[1]; for (int i = 0; i < 3; ++i) { // printf("%d \n", i); number[0] = i; pthread_create(&pids[i], NULL, *fun, NULL); } for (int i = 2; i >= 0; --i) pthread_join(pids[i], NULL); return 0; }
- File Locking
Tell me whether the locked file, e.g. lockdemo.c can be delete while the programs are running? And why?
The file name won’t be visible in the file system, but our file handle will point to the inode, which still exists. refence https://www.baeldung.com/linux/open-file-handle-after-move-delete
- Message Queues
What happens when you're running both in separate windows and you kill one or the other?
When killing kirk, spock will not stop. When killing spock, kirk still be able to write massages. Then we restart spock, the massage will be sent suceessfully.
Also try running two copies of
kirkor two copies ofspockto get an idea of what happens when you have two readers or two writers.spock will accept massages which be sent from two copies of kirk. Two copies of spock will compete to accept massages which be sent from kirk.
Another interesting demonstration is to run kirk, enter a bunch of messages, then run spock and see it retrieve all the messages in one swoop. Just messing around with these toy programs will help you gain an understanding of what is really going on.
In this case, if the size of message exceeds buffer(200B), the massage will be spilted mutil-parts.
What happens if you
ipcrmthe queue while it's in use? Why?If I remove the message queue by msgid, there are some errors(terminal will print "msgrcv: Identifier removed"). I try to send some massage by inputing words in kirk, but the terminal will print "msgsnd: Invalid argument".
Create a message queue with
ipcmk, and use it in your programs.To create and get message queue id by using
$ ipcmk -Q Message queue id: 6
In my programs, the Message queue id is from argv[1].
int msqid = atoi((char *)argv[1]);
- Semaphores
Semaphores are used to lock some shared resources to enforce mutual-exclusion. In the demo program semdemo.c, what's locked?
Semaphore value is a locker.If sem_op is negative, its absolute value is subtracted from the semaphore value. If sem_op is positive, the value is added to the semaphore value. If the result would become negative, the call blocks till the time semaphore value increases to a level that the calculation would result in non-negative semaphore value.
- Draw a flow chart to show how the demo program works.
2.3.2 Sum up
In your email message, please answer the following questions.
- How many hours you spent in this section?
- About 12 hours.
- What's the major difficulties you met in this section?
- In the task of 3 writers, it's difficult for me to code multithreading program.
- Reading code and relevant information is hard.
- How did you solve (or try solving) them?
- Conduct a search on Google and enhance my understanding of multithreading programming by studying examples of code. Reading slowly and understanding each function is my best solution. I have to say, Google has been incredibly helpful to me. It’s the perfect tool for my needs.
- Have you learnt anything? Or your time was just wasted?
- I establish preliminary understanding of IPC and know more clearly about relationship of c program and linux.
3 Memory management
3.1 Basic commands
- 实验内容
- http://cs6.swfu.edu.cn/~wx672/lecture_notes/os/lab.html#sec-4-1
- 实验环境
- OS version: (
Linux 5.15.123.1-microsoft-standard-WSL2) - Kernel source version: (
WSL2-Linux-Kernel-linux-msft-wsl-5.15.y) - GCC version: (
gcc version 11.4.0)
- OS version: (
3.1.1 Questions
If you exam its size with ls -l, you should get something similar to the following line
-rwxr-xr-x 1 wx672 wx672 6627 Oct 18 18:05 a.outWhat does the 6627 mean?this means size of a.out is 6627 byte
Then, use size to see the size of its text, data, and bss segments.
size a.outThe output should be something like
text data bss dec hex filename 1200 520 1024032 1025752 fa6d8 a.out
What do the 1200, 520, 1024032, and 1025752 mean?
the size of the text segment is 1200 bytes. the size of the data segment is 520 bytes. the size of the block started by symbol segmen is 1024032 bytes. the sum of the "text", "data", and "bss" columns in decimal is 1025752 bytes.
3.2 Shared Memory Segments
- 实验内容
- http://cs6.swfu.edu.cn/~wx672/lecture_notes/os/lab.html#sec-4-2
- 实验环境
- OS version: (
Linux 5.15.123.1-microsoft-standard-WSL2) - Kernel source version: (
WSL2-Linux-Kernel-linux-msft-wsl-5.15.y) - GCC version: (
gcc version 11.4.0)
- OS version: (
3.2.1 实验步骤
Use
ipcrmto remove the segment you just created while running the example code. Add some c program sentence inshmdemo.cprintf("%d", shmid); fflush(stdout); sleep(10);When running the example code, input
ipcrm -m shmid
The terminal will print
shmat: Invalid argument
And specific share memory will fail.
Add semaphore mechanism into the sample program (
shmdemo.c) to enforce mutual-exclusive access to the shared data area.Here’s the code for
shmdemo_semaphore.c... int initsem(key_t key, int nsems); int main(int argc, char *argv[]) { ... if ((semid = initsem(key, 1)) == -1) { perror("initsem"); exit(1); } if (semop(semid, &sb, 1) == -1) { perror("semop"); exit(1); } int shmid4shdemo; char *data; if (argc > 2) { fprintf(stderr, "usage: shmdemo [data_to_write]\n"); exit(1); } if ((shmid4shdemo = shmget(key, SHM_SIZE, 0644 | IPC_CREAT)) == -1) { perror("shmget"); exit(1); } data = shmat(shmid4shdemo, (void *)0, 0); if (data == (void *)(-1)) { perror("shmat"); exit(1); } if (argc == 2) { printf("writing to segment: \"%s\"\n", argv[1]); strncpy(data, argv[1], SHM_SIZE); data[SHM_SIZE-1] = '\0'; } else printf("segment contains: \"%s\"\n", data); if (shmdt(data) == -1) { perror("shmdt"); exit(1); } sleep(10); sb.sem_op = 1; /* free resource */ if (semop(semid, &sb, 1) == -1) { perror("semop"); exit(1); } return 0; }
3.3 Memory Mapped Files
- 实验内容
- http://cs6.swfu.edu.cn/~wx672/lecture_notes/os/lab.html#sec-4-3
- 实验环境
- OS version: (
Linux 5.15.123.1-microsoft-standard-WSL2) - Kernel source version: (
WSL2-Linux-Kernel-linux-msft-wsl-5.15.y) - GCC version: (
gcc version 11.4.0)
- OS version: (
3.3.1 实验步骤
Write a small program to find out the page size of your Linux PC.
#include <stdio.h> #include <unistd.h> void main() { printf("Page size (sysconf) %ld\n", sysconf(_SC_PAGESIZE)); printf("Page size (getpagesize) %d\n", getpagesize()); return ; }Add semaphore mechanism into the sample program (mmapdemo.c) to enforce mutual-exclusive access to the shared data area.
Here’s the code for
mmapdemo.c... int main(){ ... struct sembuf sb = {.sem_num = 0, .sem_op = -1, .sem_flg = SEM_UNDO}; key = ftok("mmapdemo.c", 'J'); semid = initsem(key, 1); semop(semid, &sb, 1); fd = open("mmapdemo.c", O_RDONLY); ... data = mmap((void*)0, sbuf.st_size, PROT_READ, MAP_SHARED, fd, 0) sb.sem_op = 1; semop(semid, &sb, 1); }
3.3.2 Sum up
In your email message, please answer the following questions.
- How many hours you spent in this section?
- 3 hours.
- What's the major difficulties you met in this section?
- Engilsh is major difficulty.
- How did you solve (or try solving) them?
- I tried my best to read and comprehend it.
4 File system
- 实验内容 http://cs6.swfu.edu.cn/~wx672/lecture_notes/os/lab.html#sec-5
- 实验环境
- OS version: (
Linux 5.15.123.1-microsoft-standard-WSL2) - Kernel source version: (
WSL2-Linux-Kernel-linux-msft-wsl-5.15.y) - GCC version: (
gcc version 11.4.0)
- OS version: (
4.1 实验步骤
Create a initialized file
dd if=/dev/zero of=fs.img bs=1k count=10000
Creating an ext2 file system
mkfs.ext2 my.img
Creating a directory on where the img mount
mkdir mymount
Mount the newly created file system onto
/mymountdirectorysudo mount my.img mymount/
4.2 Questions
Plug your USB disk into your PC's USB port, and check what file system it is and which directory it's mounted on?
I mount usb disk on
/mnt/luo/sudo mount -t drvfs D: /mnt/luo
Using
dfcommand to check$ df -Th Filesystem Type Size Used Avail Use% Mounted on ... D: 9p 30G 837M 29G 3% /mnt/luo
After you do
cat helloat the command line, you will see on the screen the content of filehello, in our case it ishelloworld. Now give me a detailed picture about what is happened in the OS fromcat hellotohelloworldis shown on the screen.In my new file system, the block size is
4k (0x1000)and the inode size is256 (0x0100)byte.
4.2.1 Sum up
In your email message, please answer the following questions.
- How many hours you spent in this section?
- About 6 hours
- What's the major difficulties you met in this section?
- When I first met 'mount' , it's too abstract to understand for me.
- How did you solve (or try solving) them?
- I do a lot practice to make 'mount' more specific.
- Have you learnt anything? Or your time was just wasted?
- I've learnt the definition of 'mount' in cs. And how ext2 find file datas.