📄 operating_systems.html
字号:
Using <code>mkdir</code>, make a directory hierarchy in your home directory e.g.</p><pre class="code">mkdir projectsmkdir projects/proj0mkdir projects/proj1</pre><p>and so on, adding breadth and depth. Then try the <code>tree</code> command, if it’s present on your system, e.g. <code>tree projects</code></p></div><h4><a name="tar" id="tar">tar</a></h4><div class="level4"><p>Archive and compress your directory hierarchy from the prior problem i.e. </p><pre class="code">tar cvfz proj.tgz projects/</pre><p> Now try to remove the directory e.g. </p><pre class="code">rmdir projects/</pre><p> Why didn’t that work?</p><p>Now try </p><pre class="code">rm -rf projects/</pre><p> Was it removed this time?</p><p>Now restore it via </p><pre class="code">tar xvfz proj.tgz</pre><p>In the two instances where we used tar, the switches used were c, v, f, z, and x.</p><p>What does each mean?</p></div><h4><a name="use_vi" id="use_vi">Use vi</a></h4><div class="level4"><p>Create two different multi line files with <code>vi</code>, <code>file1.txt</code> and <code>file2.txt</code>. We’ll use them subsequently.</p></div><h4><a name="the_cp_and_mv_commands" id="the_cp_and_mv_commands">The cp and mv commands</a></h4><div class="level4"><p>Try the <code>cp</code> command: </p><pre class="code">cp file1.txt file3.txtcp file2.txt file4.txt</pre><p> Use <code>ls -l</code> to verify that the new files were made. Then try </p><pre class="code">mv file3.txt file5.txtmv file4.txt file6.txt</pre><p> Now what does <code>ls -l </code>tell you?</p></div><h4><a name="using_chmod_chown_chgrp" id="using_chmod_chown_chgrp">Using chmod, chown, chgrp</a></h4><div class="level4"><p>See the man pages for these commands. Make some files and try them out.</p></div><h4><a name="using_pipes" id="using_pipes">Using pipes</a></h4><div class="level4"><p>Try something like </p><pre class="code">cat file1.txt file2.txt | sort > file12.txt.</pre><p> Describe what this command has done. Now try this </p><pre class="code">ls -l | wc -w</pre><p> What does this do? Does the result make sense? [see <code>man wc</code>]</p></div><!-- SECTION [26565-29171] --><h3><a name="introduction_to_uclinux" id="introduction_to_uclinux">Introduction to uClinux</a></h3><div class="level3"><p><a href="http://www.uclinux.org/" class="urlextern" title="http://www.uclinux.org/" rel="nofollow">uClinux</a> stands for microcontroller Linux (<em>u</em> for the Greek letter <em>mu </em>denoting micro<em> </em>and <em>C</em> for controller). This is a port of the Linux kernel designed for use on devices without a Memory Management Unit (MMU). Considering that the absence of full MMU support in uClinux constitutes a fundamental difference from mainstream Linux, surprisingly little kernel and user space software is affected. Two differences, the lack of memory protection and the lack of a virtual memory model, between mainstream Linux and uClinux are a consequence of the removal of MMU support from uClinux. Specifically, becuase Blackfin has part of a MMU (offers some memory protection, but not virtual memory), Blackfin/uClinux has better protection than other noMMU systems, and will not crash as often as uClinux running on different processors.</p></div><h4><a name="memory_protection" id="memory_protection">Memory Protection</a></h4><div class="level4"><p>One consequence of operating without memory protection is that an invalid pointer reference (null pointer, or pointer to an odd address), even by an unprivileged process, may trigger an address error, and potentially corrupt or even shut down the system. Obviously code running on such a system must be programmed carefully and tested diligently to ensure robustness and security.</p><p>The Blackfin MMU does provide partial memory protection, and can segment user space from kernel space, so this less likily to be an issue on the Blackfin architecture like it is on other devices that run uClinux. </p><p>On Blackfin/uClinux, we start the kernel at <code>0×1000</code>, leaving 4k as a buffer for bad pointers. If an application gets a bad pointer that reads or writes into the first 4k of memory, the application will optionally halt. To understand this, if we take the trival application:</p><pre class="code c"><span class="kw4">int</span> main <span class="br0">(</span><span class="br0">)</span><span class="br0">{</span> <span class="kw4">int</span> *i; i=<span class="nu0">0</span>; *i=0xDEAD; <a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span class="kw3">printf</span></a><span class="br0">(</span><span class="st0">"%i : %x<span class="es0">\n</span>"</span>, i, *i<span class="br0">)</span>;<span class="br0">}</span></pre><p>If I run that on a Linux host (x86), I get: </p><pre class="code">rgetz@test:~/test> gcc -O3 test.c -o testrgetz@test:~/test> ./testSegmentation fault</pre><p>If I cross compile, </p><pre class="code">rgetz@test:~/test> bfin-uclinux-gcc -Wl,-elf2flt -O3 ./test.c -o ./test</pre><p>and run it on the target, I get: </p><pre class="code">root:~> ./test0 : dead</pre><p>Or </p><pre class="code">root:~> ./testSIGSEGV</pre><p>This is controlled by the kernel configuration option: <code>Halt on reads/writes to null Pointer (DEBUG_HUNT_FOR_ZERO)</code>, under <strong>Kernel Hacking → Debug kernel</strong>. By default, this option is turned off, as setting this, occupies an additional locked CPLB entry, and will effect the speed and efficeny of the kernel. It is recommened to turn this option on for debugging and development, and off for deployment.</p><p>Additional protection is provided when an application gets a bad pointer that reads or writes into main memory, but does it unalighned (accessing a 32 bit value, in a 16 bit address), the application will halt. Other implmentation of uClinux may start writing over the kernel. This will ensure that random crashes due to pointer corruption are less likily to happen on Blackfin/uClinux.</p><p>The Blackfin MMU also protects uClinux applicaitons from writing into kernel space, but does not protect them from writing from one application into the space of another application. This means if an application tries to read or write from kernel space, it will be killed.</p></div><h4><a name="virtual_memory" id="virtual_memory">Virtual Memory</a></h4><div class="level4"><p>When Linux is running on an architecture where a full MMU exists, the MMU provides Linux programs basically unlimited stack and heap space. This is done by the the virtualization of physical memory. When an Linux application needs more memory, it asks the memory manager; the memory manager finds empty physical memory (if it can’t find physical memory, it swaps physical memory to the hard drive, and frees it), and maps to this physical memory to the virutal memory of the application. </p><p>Because most 碌Clinux do not have storage media for swap, memory usage is limited to the amount of physical memory. Because it can not support virtual memory (MMUless), it allocates stack space at the end of the data for the executable. If the stack grows too large on 碌Clinux, it will overwrite the static data and code areas. This means that the developer, who previously was oblivious to stack usage within the application, must now be aware of the stack requirements.</p><p>On Blackfin/碌Clinux - there is a compiler option to turn on <a href="debuging_applications.html#stack_checking" class="wikilink1" title="debuging_applications.html">stack checking</a>. If the option <code>-fstack-limit-symbol=_stack_start</code>, the compiler will add in extra code, which checks to ensure that the stack is not exceeded. This will ensure that random crashes due to stack corruption will not happen on Blackfin/uClinux.</p><p>One consequence of running Linux with out virtual memory is that processes which are loaded by the kernel must be able to run independently of their position in memory. One way to achieve this is to <em>fix-up</em> address references in a program once it is loaded into RAM, the other is to generate code that uses only relative addressing (referred to as PIC, or Position Independent Code). uClinux supports both of these methods. </p><p>Another consequence arises from memory allocation and deallocation occurring within a flat memory model. A lot of dynamic memory allocation can result in fragmentation which can starve the system. One way to improve the robustness of applications that perform dynamic memory allocation, is to replace <em>malloc</em><em>()</em> calls with requests from a preallocated buffer pool. Swapping pages in and out of memory is not implemented since it cannot be guaranteed that the pages would be loaded to the same location in RAM. In embedded systems it is also unlikely that it would be acceptable to suspend an application in order to use more RAM than is physically available.</p></div><h4><a name="system_interfaces" id="system_interfaces">System Interfaces</a></h4><div class="level4"><p>The lack of memory management hardware on uClinux target processors requires some changes to the Linux system interface. Perhaps the greatest difference is the absence of the <em>fork() </em>and <em>brk</em><em>()</em> system calls. A call to <em>fork()</em> clones a process to create a child. Under Linux, <em>fork()</em> is implemented using copy-on-write pages. Without an MMU uClinux cannot completely and reliably clone a process, nor does it have access to copy-on-write. uClinux implements <em>vfork</em><em>()</em> in order to compensate for the lack of <em>fork()</em>. When a parent process calls <em>vfork()</em> to create a child, both processes share all their memory space including the stack. <em>vfork()</em> then suspends the parent’s execution until the child process either calls <em>exit()</em> or <em>execve</em><em>()</em>. Note that multitasking is not otherwise affected. Programs which rely heavily on the <em>fork()</em> system call may require substantial reworking to perform the same task under uClinux. Also, uClinux has neither an autogrow stack nor <em>brk() </em>and so user space programs must use the <em>mmap</em><em>()</em> command to allocate memory. For convenience, the C library implements <em>malloc()</em> as a wrapper to <em>mmap(). </em>There is a compile-time option as well as a run time application (<code>flthdr</code>) to set the stack size of a program.</p></div><h4><a name="memory_subsystem" id="memory_subsystem">Memory Subsystem</a></h4><div class="level4"><p>The architecture-generic memory management subsystem of uClinux has been modified to remove reliance on MMU hardware and provides basic memory management functions within the kernel software itself. This is the role of the directory <code>/</code><code>mmnommu</code>, derived from and replacing the directory <code>/mm</code>. Several subsystems were modified, added, removed or rewritten; kernel and user memory allocation and deallocation routines have been reimplemented; and support for transparent swapping / paging has been removed. Program loaders which support Position Independent Code (PIC) have been added and a new binary object code format named <em>flat</em>, which supports PIC, was created. Other program loaders, such as that for ELF, have been modified to support other formats which, instead of using PIC, use absolute references. It is then the responsibility of the kernel to <em>fix-up</em> these references during run time. Both methods have advantages and disadvantages. Traditionally PIC is quick and compact but has a size restriction on some architectures. The runtime <em>fix-up</em> technique removes this size restriction, but incurs overhead when the program is loaded by the kernel. </p></div><!-- SECTION [29172-] --></body></html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -