INITIALIZATION Knowledgebase: ki-dev-large Base Query: Hi can you explain to me the Communications Theory? Model: gemini-1.5-pro-preview-0409 Use Curl?: None ================================================== **Elapsed Time: 0.00 seconds** ================================================== ROUTING Query type: summary ================================================== **Elapsed Time: 1.99 seconds** ================================================== RAG PARAMETERS Max Context To Include: 100 Lowest Score to Consider: 0.1 ================================================== **Elapsed Time: 0.14 seconds** ================================================== VECTOR SEARCH ALGORITHM TO USE Use MMR search?: True Use Similarity search?: False ================================================== **Elapsed Time: 0.10 seconds** ================================================== VECTOR SEARCH DONE ================================================== **Elapsed Time: 6.58 seconds** ================================================== FILENAMES AND KEYWORDS Keywords Found: [] All file names: ['Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf', 'The%20Little%20Book%20About%20OS%20Development%20-%20Erik%20Helin%2C%20Adam%20Renberg%20-%20%28PDF%2C%20HTML%29.pdf', 'The%20Little%20Book%20About%20OS%20Development%20-%20Erik%20Helin%2C%20Adam%20Renberg%20-%20%28PDF%2C%20HTML%29.pdf', 'Web%20API%20Design%20-%20Brian%20Mulloy%20%28PDF%29.pdf', 'Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf', 'The%20Little%20Book%20About%20OS%20Development%20-%20Erik%20Helin%2C%20Adam%20Renberg%20-%20%28PDF%2C%20HTML%29.pdf', 'The%20Little%20Book%20About%20OS%20Development%20-%20Erik%20Helin%2C%20Adam%20Renberg%20-%20%28PDF%2C%20HTML%29.pdf', 'Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf', 'Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf', 'Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf', 'Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf', 'Web%20API%20Design%20-%20Brian%20Mulloy%20%28PDF%29.pdf', 'Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf', 'The%20Little%20Book%20About%20OS%20Development%20-%20Erik%20Helin%2C%20Adam%20Renberg%20-%20%28PDF%2C%20HTML%29.pdf', 'Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf', 'Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf', 'The%20Little%20Book%20About%20OS%20Development%20-%20Erik%20Helin%2C%20Adam%20Renberg%20-%20%28PDF%2C%20HTML%29.pdf', 'Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf', 'The%20Little%20Book%20About%20OS%20Development%20-%20Erik%20Helin%2C%20Adam%20Renberg%20-%20%28PDF%2C%20HTML%29.pdf', 'The%20Little%20Book%20About%20OS%20Development%20-%20Erik%20Helin%2C%20Adam%20Renberg%20-%20%28PDF%2C%20HTML%29.pdf', 'Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf', 'The%20Little%20Book%20About%20OS%20Development%20-%20Erik%20Helin%2C%20Adam%20Renberg%20-%20%28PDF%2C%20HTML%29.pdf', 'Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf', 'Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf', 'Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf', 'Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf', 'Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf', 'Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf', 'The%20Little%20Book%20About%20OS%20Development%20-%20Erik%20Helin%2C%20Adam%20Renberg%20-%20%28PDF%2C%20HTML%29.pdf', 'Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf', 'Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf', 'Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf', 'Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf', 'Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf', 'The%20Little%20Book%20About%20OS%20Development%20-%20Erik%20Helin%2C%20Adam%20Renberg%20-%20%28PDF%2C%20HTML%29.pdf', 'The%20Little%20Book%20About%20OS%20Development%20-%20Erik%20Helin%2C%20Adam%20Renberg%20-%20%28PDF%2C%20HTML%29.pdf', 'Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf', 'Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf', 'Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf', 'Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf', 'Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf', 'Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf', 'Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf', 'Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf', 'Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf', 'The%20Little%20Book%20About%20OS%20Development%20-%20Erik%20Helin%2C%20Adam%20Renberg%20-%20%28PDF%2C%20HTML%29.pdf', 'The%20Little%20Book%20About%20OS%20Development%20-%20Erik%20Helin%2C%20Adam%20Renberg%20-%20%28PDF%2C%20HTML%29.pdf', 'The%20Little%20Book%20About%20OS%20Development%20-%20Erik%20Helin%2C%20Adam%20Renberg%20-%20%28PDF%2C%20HTML%29.pdf', 'Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf', 'Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf', 'Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf', 'Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf', 'Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf', 'Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf', 'Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf', 'Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf', 'Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf', 'The%20Little%20Book%20About%20OS%20Development%20-%20Erik%20Helin%2C%20Adam%20Renberg%20-%20%28PDF%2C%20HTML%29.pdf', 'The%20Little%20Book%20About%20OS%20Development%20-%20Erik%20Helin%2C%20Adam%20Renberg%20-%20%28PDF%2C%20HTML%29.pdf', 'Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf', 'Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf', 'The%20Little%20Book%20About%20OS%20Development%20-%20Erik%20Helin%2C%20Adam%20Renberg%20-%20%28PDF%2C%20HTML%29.pdf', 'Web%20API%20Design%20-%20Brian%20Mulloy%20%28PDF%29.pdf', 'Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf', 'The%20Little%20Book%20About%20OS%20Development%20-%20Erik%20Helin%2C%20Adam%20Renberg%20-%20%28PDF%2C%20HTML%29.pdf', 'Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf', 'Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf', 'Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf', 'Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf', 'Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf', 'The%20Little%20Book%20About%20OS%20Development%20-%20Erik%20Helin%2C%20Adam%20Renberg%20-%20%28PDF%2C%20HTML%29.pdf', 'Web%20API%20Design%20-%20Brian%20Mulloy%20%28PDF%29.pdf', 'Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf', 'The%20Little%20Book%20About%20OS%20Development%20-%20Erik%20Helin%2C%20Adam%20Renberg%20-%20%28PDF%2C%20HTML%29.pdf', 'Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf', 'Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf', 'The%20Little%20Book%20About%20OS%20Development%20-%20Erik%20Helin%2C%20Adam%20Renberg%20-%20%28PDF%2C%20HTML%29.pdf', 'Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf', 'Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf', 'Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf', 'Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf', 'Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf', 'The%20Little%20Book%20About%20OS%20Development%20-%20Erik%20Helin%2C%20Adam%20Renberg%20-%20%28PDF%2C%20HTML%29.pdf', 'Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf', 'The%20Little%20Book%20About%20OS%20Development%20-%20Erik%20Helin%2C%20Adam%20Renberg%20-%20%28PDF%2C%20HTML%29.pdf', 'Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf', 'Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf', 'Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf', 'Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf', 'Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf', 'The%20Little%20Book%20About%20OS%20Development%20-%20Erik%20Helin%2C%20Adam%20Renberg%20-%20%28PDF%2C%20HTML%29.pdf', 'The%20Little%20Book%20About%20OS%20Development%20-%20Erik%20Helin%2C%20Adam%20Renberg%20-%20%28PDF%2C%20HTML%29.pdf', 'The%20Little%20Book%20About%20OS%20Development%20-%20Erik%20Helin%2C%20Adam%20Renberg%20-%20%28PDF%2C%20HTML%29.pdf', 'Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf', 'Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf', 'Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf', 'Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf', 'Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf', 'Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf', 'Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf'] File names to FILTER: [] ================================================== **Elapsed Time: 1.08 seconds** ================================================== PRIMER Primer: You are Simon, a highly intelligent personal assistant in a system called KIOS. You are a chatbot that can read knowledgebases through the "CONTEXT" that is included in the user's chat message. Your role is to act as an expert at summarization and analysis. In your responses to enterprise users, prioritize clarity, trustworthiness, and appropriate formality. Be honest by admitting when a topic falls outside your scope of knowledge, and suggest alternative avenues for obtaining information when necessary. Make effective use of chat history to avoid redundancy and enhance response relevance, continuously adapting to integrate all necessary details in your interactions. Use as much tokens as possible to provide a detailed response. ================================================== **Elapsed Time: 0.00 seconds** ================================================== FINAL QUERY Final Query: CONTEXT: ########## File: Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf Page: 1 Context: ```markdown # Introduction to Quantum Information **Stephen M. Barnett** School of Physics and Astronomy, University of Glasgow, Glasgow G12 8QQ, UK --- **OXFORD** *UNIVERSITY PRESS* ``` #################### File: Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf Page: 3 Context: ```markdown # Contents 1. **Classical Information Theory** 1 1.1 A very short history 1 1.2 Probabilities and conditional probabilities 2 1.3 Entropy and information 3 1.4 Information and thermodynamics 4 1.5 Communications Theory 8 2. **Quantum Communications and Quantum Key Distribution** 11 2.1 Qubits 11 2.2 Information security 12 2.3 Quantum copying? 15 2.4 Optical polarization 16 2.5 Quantum cryptography 16 3. **Generalized Measurements** 21 3.1 Ideal von Neumann measurements 21 3.2 Non-ideal measurements 23 3.3 Probability operator measures 23 3.4 Optimized measurements 26 3.5 Operations and the post-measurement state 31 4. **Entanglement and its Applications** 33 4.1 Entangled states and non-locality 33 4.2 Quantum "magic tricks" 37 4.3 Ebits and shared entanglement 38 4.4 Quantum dense coding 39 4.5 Teleportation 41 5. **Quantum Computation** 44 5.1 Digital electronics 44 5.2 Quantum gates 45 5.3 Principles of quantum computation 48 5.4 Quantum algorithms 52 5.5 Errors and decoherence 55 **References** 57 ``` #################### File: Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf Page: 4 Context: ```markdown # 1 Classical Information Theory In these five lectures I shall give a short introduction to the field of quantum information. The lectures are drawn from my book *Quantum Information* (Barnett 2009). My aim is to make these notes self-contained, but cannot hope to cover the totality of what is now a large and active field of research. In these notes I aim, rather, to give a taster of the subject to whet the appetite of the reader. A more complete introduction may be found in (Barnett 2009) or in any of a now large collection of books and review papers devoted to the topic (far too many for me to attempt to make a list and to risk offence by innocent omission). One text that needs to be mentioned, however, is that by Nielsen and Chuang (2000), which did so much both to popularise the field and to lay out its founding principles. I am grateful to Oxford University Press for their permission and, indeed, encouragement to reproduce some of the material from (Barnett 2009). I wish to express also my gratitude to Allison Yao for her help in preparing these notes. ## 1.1 A very short history Our field starts with the work of the Reverend Thomas Bayes (1702–1761) and the celebrated theorem that bears his name (of which more below) (Bayes 1763). His key idea was that probabilities depend on what you know; if we acquire additional *information* then this modifies the probabilities. Today such reasoning is uncontentious and forms part of the prevailing paradigm in much of probability theory (Jeffreys, 1939; Box and Tiao 1973; Bretherton 1989; Lee 1989; Jaynes 2003). This was not the case, however, for most of the 350 years of its history. An entertaining and informative presentation of its troubled history may be found in (McGraven 2011). The picture is completed by identifying, or formulating the quantity of information. It was Claude Shannon (1916–2001) who solved this problem and, by using it to devise his two coding theorems, founded information theory (Shannon 1948). Perhaps I can give an indication of the magnitude of Shannon's achievement by relating that the title of his paper was *A Mathematical Theory of Communication*, but a year later the paper was republished as a book (Shannon and Weaver 1949); apart from correcting a few typographical errors, there are only two changes, the inclusion of a short introductory article by Weaver and a change of title to *The Mathematical Theory of Communication*. The theory was born complete, the numerous textbooks on the topic have greatly broadened the scope and application of Shannon’s ideas but have not departed from the fundamentals as explained by Shannon in his first paper (Brillouin 1956; Kleene 1957; Kullback 1959; Hamming 1980; Cover and Thomas 1991; Goldie and Pinch 1991). ``` #################### File: Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf Page: 5 Context: ```markdown # Classical Information Theory Shannon’s information has a simple and familiar form. For a given set of probabilities \(\{p_i\}\), the information is \[ H = -\sum p_i \log p_i \tag{1.1} \] Remarkably, this is simply Boltzmann’s formula for the entropy (of which more later). We can sum up the fundamental lessons learned from Bayes and from Shannon as follows: Bayes taught us that probabilities are not absolute but rather depend on available information. Shannon showed that information itself is a precisely defined function of the probabilities. Shannon’s work was aimed, initially, at the problem of providing a quantitative theory of communications, but any set of probabilities can be associated with a quantity of information and it follows that any probabilistic phenomenon has an associated information theory. This idea has been applied, for example, to statistical mechanics (Jaynes 1957a, 1957b). Quantum theory is a probabilistic theory, of course, and so it was inevitable that a quantum information theory would be developed. ## 1.2 Probabilities and conditional probabilities Consider an event \(A\) with possible outcomes \(\{a_i\}\). Everything we know is specified by the probabilities for the possible outcomes: \(P(a_i)\). For tossing a fair coin, for example, the outcomes are ‘heads’ and ‘tails’ with \(P(\text{heads}) = \frac{1}{2} = P(\text{tails})\). In general the probabilities satisfy the two conditions: \[ 0 \leq P(a_i) \leq 1 \] \[ \sum P(a_i) = 1 \tag{1.2} \] If we have two events \(A\) and \(B\) with outcomes \(\{a_i\}\) and \(\{b_j\}\), then the complete description is given by the joint probabilities, \(P(a_i, b_j)\). Here the comma is read as ‘and’ so that \(P(a_i, b_j)\) is the probability that both \(A = a_i\) and \(B = b_j\). If the two events are independent then \(P(a_i, b_j) = P(a_i)P(b_j)\) but this is not true in general. More generally we have \[ P(a_i) = \sum P(a_i, b_j) \] \[ P(b_j) = \sum P(a_i, b_j) \tag{1.3} \] If the events are created then what does learning the value of \(A\) tell us about the value of \(B\? If we learn, for example, that \(A = a_4\) then \(P(b_j | a_4)\) is replaced by \[ P(b_j | a_i) \propto P(a_i, b_j) \tag{1.4} \] Here the vertical line is read as ‘given that’ so that \(P(b_j | a_i)\) is the probability that \(B = b_j\) given that \(A = a_i\). We can find the constant of proportionality by noting that the sum over \(j\) of \(P(b_j | a_i)\) must be unity and this leads to Bayes’ rule: \[ P(a_i, b_j) = P(b_j | a_i) P(a_i) \] ``` #################### File: Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf Page: 6 Context: ```markdown # Entropy and Information Bayes' theorem utilises this rule to relate the two conditional probabilities: $$ P(A_i | B_j) = \frac{P(B_j | A_i) P(A_i)}{P(B_j)}. \tag{1.5} $$ ## 1.3 Entropy and Information The link between information and entropy is a subtle and beautiful one. Shannon himself gave a simple derivation of this as a mathematical theorem using only a few simple axioms he argued that information must satisfy (Shannon and Weaver 1949). We shall not reproduce this here but rather present a simple argument to make the association plausible. Suppose that we have a single event \( A \) with possible outcomes \( a_1, a_2, \ldots, a_n \). If one, say \( a_k \), is certain to occur then we acquire no information by observing \( A \). By simple extension, if \( A = a_k \) is very likely to occur then we might confidently expect it and so when it happens we learn very little. If, however, \( A = a_k \) is very unlikely then when it occurs we might need to drastically modify our actions. A very simple example is a two-state communication system that you may not have considered: a fire alarm. A fire alarm is either ringing or not ringing. Its most common state (hopefully not ringing) is so innocuous that we give it no thought. When it does ring, however, we stop what we are doing and leave the building (if we are sensible). It seems reasonable to conclude that learning the value of \( A \) provides a quantity of information, \( h \), that increases as the corresponding probability decreases: $$ h[P(A)] \uparrow \text{ as } P(A) \downarrow. $$ We think of learning something new as adding to the available information. Therefore for independent probabilities for a pair of events, \( P(A, B) = P(A)P(B) \), it is natural to require that $$ h[P(A, B)] = h[P(A)P(B)] = \frac{h[P(A)] + h[P(B)]}{.} \tag{1.7} $$ which immediately suggests logarithms. Hence we set $$ h[P(A)] = -K \log P(A). \tag{1.8} $$ Here \( K \) is a positive constant, yet to be determined, and the minus sign ensures both that \( h \) is positive and that it increases as the probability decreases (recall that the logarithm of a number less than unity is negative). It is convenient to define the information as the average of \( h \), which means weighting \( h \) for each outcome by its probability of occurring and then summing. This procedure leads us, of course, to the entropy: $$ H = -K \sum_i P(A_i) \log P(A_i). \tag{1.9} $$ ``` #################### File: Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf Page: 7 Context: ```markdown # Classical Information Theory We can absorb the prefactor \( K \) into the choice of base for the logarithm. A convenient choice is to use base 2 so that \[ H = - \sum P(a_i) \log_2 P(a_i) \quad \text{bits,} \tag{1.10} \] which is Shannon's formula for the information. Henceforth we shall drop the subscript 2. It is sometimes convenient, especially in analytical calculations, to use the natural base of logarithms, base \( e \), which gives the entropy in nats: \[ H_e = - \sum P(a_i) \ln P(a_i) \quad \text{nats.} \tag{1.11} \] It is straightforward to show that \( H_e = H \ln 2 \), so that 1 nat = ln 2 bits. For two events \( A \) and \( B \) we can write information for the joint events or for the single events: \[ H(A, B) = - \sum_{i,j} P(a_i, b_j) \log P(a_i, b_j) \] \[ H(A) = - \sum_{i} P(a_i) \log \sum_j P(a_i, b_j) \] \[ H(B) = - \sum_{j} P(a_i, b_j) \log \sum_k P(b_j) . \tag{1.12} \] We can also define information based on the conditional probabilities. An especially useful measure of correlation between the two events is the mutual information: \[ H(A : B) = H(A) + H(B) - H(A, B). \tag{1.13} \] This has the important properties that it is positive or zero and that it takes the value zero if and only if the events are independent: \[ H(A : B) \geq 0 \] \[ H(A : B) = 0 \iff P(a_i, b_j) = P(a_i)P(b_j), \quad \forall i, j. \tag{1.14} \] ## 1.4 Information and Thermodynamics The fact that the mathematical form of the information is also the entropy begs the question as to whether information entropy is the same quantity that appears in statistical mechanics. It is! An important and simple example is the way in which we can obtain the Boltzmann distribution by maximizing the information (what we have yet to discover) subject only to a constraint on the average energy. This is such a nice calculation that I cannot. ``` #################### File: Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf Page: 8 Context: ```markdown # Information and Thermodynamics We resist the temptation to include it here, even though there was not time to present it in my lectures. Let a quantum system have a set of discrete energy levels \(E_i\) and be in thermodynamic equilibrium with its environment. Our task is to determine the probability \(p_i\) that the system is to be found in any one of its given energy levels, \(E_i\). Of course we know how to do this by maximising the entropy, but information theory gives us a rather different take on the problem; we maximise the information of the system subject to the constraint only that its mean energy is fixed. In this way we maximise, in an unbiased manner, our uncertainty about the state. The derivation is readily performed as a variational calculation using Lagrange's method of undetermined multipliers (Boas 1983). It is convenient to work with the natural base of logarithms in this case and so we define the information to be \[ H_\epsilon = - \sum p_i \ln p_i. \tag{1.15} \] Our task is to maximise this quantity subject to a fixed mean energy, \(\sum p_i E_i = \bar{E}\), and the probabilities summing to unity, \(\sum p_i = 1\). We can achieve this by varying, independently, the probabilities in the function \[ \tilde{H} = H_\epsilon + \lambda \left(1 - \sum p_i\right) + \beta \left(\bar{E} - \sum p_i E_i\right). \tag{1.16} \] We find \[ d\tilde{H} = \sum p_i \left(-\ln p_i - 1 - \lambda - \beta E_i\right) d p_i. \tag{1.17} \] We require this to be stationary (zero) for all \(d p_i\), which leads to the solution \[ p_i = e^{-\lambda} e^{-\beta E_i}. \tag{1.18} \] We can fix the value of the undetermined multipliers by enforcing the normalisation of the probabilities and the value of the average energy to arrive at the familiar Boltzmann distribution: \[ p_i = \frac{e^{-\left(E_i/k_B T\right)}}{\sum_j e^{-\left(E_j/k_B T\right)}}. \tag{1.19} \] A more dramatic example was provided by Szilard in his paper *On the decrease of entropy in a thermodynamic system by the intervention of intelligent beings* (Szilard 1929). This paper is all the more remarkable in that it precedes Shannon's work by nearly 20 years. Here is Szilard's argument. Consider a box of volume \(V\) with a movable partition dividing the box into two equal halves. There is a single molecule in one of the two sides, as depicted in Fig. 1.1. An intelligent being can look in the box and determine which side the molecule is in. By attaching a small weight to a pulley we can extract work from heat in an apparent violation of the second law of thermodynamics, an interesting paradox in the style of Maxwell's famous demon (Maxwell 1871). ``` #################### File: Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf Page: 10 Context: ```markdown # Information and Thermodynamics Fig. 1.2 Illustration of Landauer’s derivation of the thermodynamic cost of information erasure. Reproduced, with permission, from Barnett (2009). A more precise statement is that to complete the thermodynamic cycle, we need to include the process of the observer forgetting in which side the molecule was found. The process of forgetting was studied by Landauer (1961), Leff and Rex (1994), Plenio and Vitelli (2011). He considered a single-molecule gas, like Szilard’s, and proposed using the position of the molecule to represent a logical bit: the molecule being to the left of the partition corresponding to a logical 0 and to the right corresponding to a logical 1. Landauer showed that erasing and resetting the bit to 0 requires the dissipation of at least \( k_B T \ln 2 \) worth of energy as heat. To see this we can simply remove the membrane (a reversible process) and then push in, slowly, a fresh partition from the right, as depicted in Fig. 1.2. When the partition reached halfway the ‘memory’ has been reset to the bit value 0 and, of course, all trace of the original bit value has been lost. The work that needs to be done to achieve this is $$ W = - \int_{0}^{V/2} \frac{P}{V} dV = k_B T \ln 2, $$ and this is dissipated, of course, as heat. We can view this as a resolution of the paradox implicit in Szilard’s model. This is not the end of the story, however. It has recently been shown that Landauer’s limit can be beaten if we pay a cost, not in energy, but in some other quantity such as angular momentum (Vacarro and Barnett 2011). The key idea to take from these models, however, is unaffected: information is physical. ``` #################### File: Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf Page: 11 Context: ```markdown # 1.5 Communications Theory Shannon first introduced his information theory as a/the mathematical theory of communication (Shannon 1948, Shannon and Weaver 1949). In doing so he introduced the very general model of a communications system depicted in Fig. 1.3. Let us analyse this by introducing two characters, Alice and Bob, who have become very popular in quantum communications. Alice wishes to send a message to Bob. Alice's event, \( A \), is the selection of the message from a set of possible messages \( \{m_j\} \). Bob's event, \( B \), is detecting the message from the possible set \( \{m_j\} \). On Alice's side there is an information source, which produces the choice of message to be sent (this may be Alice herself, of course) and a transmitter which produces the signal (electrical, optical, acoustical or even a piece of paper) ready for transmission. The signal propagates from Alice to Bob and, whilst en route, is subject to noise. Bob receives the noisy signal and his receiving device turns the signal into a message. ``` Information source | Transmitter | Signal | Received signal | Receiver | Destination | | Noise source ``` Fig. 1.3 Shannon's model of a communications channel. Reproduced, with permission, from Barnett (2009). The limiting performance of such a communications channel is governed by two theorems derived by Shannon (Shannon 1948, Shannon and Weaver 1949): his noiseless coding theorem, which tells us how much a message can be compressed and still be read, and his noisy channel coding theorem, which tells us how much redundancy is needed to correct errors. ## 1.5.1 Noiseless coding theorem Most messages have an element of redundancy and can be compressed but still be readable. As an example, you might like to try this one: ``` THS LS HCHS SCHL HS NTRSTNG LCTRS ``` I compressed the message by removing the vowels. Shannon's noiseless coding theorem quantifies the redundancy in a message. Two simple examples are that in English we mostly don't need to put a 'u' after 'q' and a three-letter word beginning with 'th' will almost certainly be 'the'. --- *If you are having difficulty, the message is: THIS IS HOUCHES SCHOOL. HAS INTERSTING LECTURES.* ``` #################### File: Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf Page: 12 Context: ```markdown # Communications Theory Shannon's theorem shows us the typical number of bits we need to encode a message efficiently. It is the entropy associated with the probabilities for the messages that is the key quantity. If we have one of a set of messages that is \( N \) bits long, for example \( 010\cdots111 \), and each of the possible possible messages \( \{a\} \) is selected with the probability associated probability \( P(a) \), then Shannon's noiseless coding theorem tells us that we need only an average of \( H(A) \) bits, if we can find an optimum coding scheme. We shall not prove Shannon's noiseless coding theorem, but rather present a simple example from Shannon's original paper (Shannon 1948, Shannon and Weaver 1949). A simple derivation, both of the noiseless and noisy coding theorems may be found in (Stenholm and Suominen 2005, Barnett 2009). Consider a message formed from an alphabet of four letters, A, B, C and D and let each entry in the message be one of these four with the probabilities: - \( P(A) = \frac{1}{2} \) - \( P(B) = \frac{1}{4} \) - \( P(C) = \frac{1}{8} = P(D) \) The information associated with this set of probabilities is: \[ H = -\left( \frac{1}{2} \log_2 \frac{1}{2} + \frac{1}{4} \log_2 \frac{1}{4} + \frac{1}{8} \log_2 \frac{1}{8} \right) = \frac{7}{4} \text{ bits.} \] Hence Shannon’s noiseless coding theorem says that we should be able (on average) to reduce a message of \( N \) characters, or \( 2N \) bits, to 1.75 bits. The key to this reduction is to use short sequences for common elements of the message (here the letter A) and longer ones for the less likely ones (like C and D in our example). Here is a coding scheme that achieves this: - \( A = 0 \) - \( B = 10 \) - \( C = 110 \) - \( D = 111 \) A bit of thought will confirm that any message so encoded can be decoded uniquely to recover the original sequence of letters. The average number of bits used to encode a sequence of \( N \) letters is then: \[ N\left( \frac{1}{2} \cdot 1 + \frac{1}{4} \cdot 2 + \frac{2}{8} \cdot 3 \right) = \frac{7N}{4} = HN. \] ``` #################### File: Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf Page: 13 Context: ```markdown # 1.0 Classical Information Theory which is the bound provided by Shannon’s theorem. The fact that Shannon’s value is reached in this case tells us, moreover, that no better coding is possible: this is the shortest possible length of the message. ## 1.5.2 Noisy coding theorem The presence of noise on the communications channel will introduce errors in the received signal. We can combat these errors by introducing some redundancy; indeed this is undoubtedly the reason why language evolved already containing redundancy. As a simple example, let us suppose that any given bit in the message is 'flipped' with probability \( q \) and so produces an error. How much redundancy do we need to be able to detect and correct these errors? Shannon’s noisy coding theorem tells us that, on average, we require at least \[ \frac{N_0}{1 - H(q)} \text{ bits} \] to encode, faithfully, one of \( 2^{N_0} \) equiprobable messages. Here \[ H(q) = -[q \log_2 q + (1 - q) \log_2 (1 - q)] \] is the entropy associated with the single-bit error probability. In other words if we first remove all the redundancy to get \( 2^{N_0} \) possible optimally compressed messages, we need to put back this much redundancy to combat errors. The general statement is based on the mutual information. It says that the greatest number of messages that can be sent from Alice to Bob on a noisy channel, using \( N \) bits, and be reconstructed by Bob is \[ 2^{N I(A;B)}. \] Any more is impossible in that an attempt to do so will inevitably produce ambiguities in Bob’s decoding process. We conclude with a simple illustration of the principle of using redundancy to combat errors. Try to read the following message: ``` WNTM NRMQNN THRS S FN ``` You probably didn’t manage to do so. The reason for this is that I first compressed the message by removing the vowels and then added in errors. Because much of the redundancy was removed, the message has become unreadable. If I had left the full message (complete with vowels) and then added the errors, we might have: ``` WUANTFM INAOIRMAQION THEORS US FUN ``` Hopefully, after a bit of thought, you should be able to read the message². Note that decoding the message is possible even though the errors affect both the characters in the compressed message and in the redundant characters added to combat the errors. ²If you are struggling, the message is "QUANTUM INFORMATION THEORY IS FUN." ``` #################### File: Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf Page: 14 Context: ```markdown # 2 Quantum Communications and Quantum Key Distribution Quantum communications differ from their classical counterpart in that the transmitted signal is carried by a quantum system. At its simplest, classical information is expressed in bits and is carried by a physical system with two distinct states (for example, a high or low voltage or the presence or absence of an optical pulse). One state is used to represent the logical 0 and the other a logical 1. We can take the same approach in quantum communications and use two orthogonal quantum states to represent 0 and 1. We label these, naturally enough, as |0⟩ and |1⟩. The additional element brought in by using a two-state quantum system is that we can also prepare any superposition state of the form $$ |\psi\rangle = \alpha |0\rangle + \beta |1\rangle, \tag{2.1} $$ where α and β are complex probability amplitudes. A quantum bit, or qubit, is such a two-state quantum system. ## 2.1 Qubits Before getting into the theory of quantum communications, we pause to elaborate on the idea of a qubit and the mathematical tools used to describe it. A qubit can be any quantum system with two orthogonal states. We choose a basis, often called the computational basis in quantum information, and label the two states in this basis as |0⟩ and |1⟩. It is convenient to think of this as a spin-half particle; this is not literally true in most cases, but it has the benefit that we can use the Pauli operators to describe the properties of the qubit. There are four Pauli operators, which are \( \sigma_x \), \( \sigma_y \), and \( \sigma_z \) and the identity operator \( I \). We can define each of these by their action on the states in the computational basis: $$ \sigma_x |0\rangle = |1\rangle \quad \sigma_x |1\rangle = |0\rangle $$ $$ \sigma_y |0\rangle = i|1\rangle \quad \sigma_y |1\rangle = -i|0\rangle $$ $$ \sigma_z |0\rangle = |0\rangle \quad \sigma_z |1\rangle = -|1\rangle $$ $$ I |0\rangle = |0\rangle \quad I |1\rangle = |1\rangle \tag{2.2} $$ The first three Pauli operators do not mutually commute. We can write the product rule for these operators in an appealingly simple form if we introduce, by means of a ... ``` #################### File: Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf Page: 16 Context: ```markdown # Information Security Figure 2.1: Elements of a secret communications channel. Reproduced, with permission, from Bartlett (2009). Example: The most common symbol will be E, which occurs 12.7% of the time, while Q makes up only about 0.1% of the symbols (or perhaps a bit more in these notes). Sherlock Holmes makes use of precisely this technique in one of his cases (Conan Doyle 1903). It was Shannon who gave us an objective criterion for perfect secrecy (Shannon 1949). Let \( \{p_i\} \) be the set of possible plaintexts (messages) and \( \{c_j\} \) be the set of possible ciphertexts. Shannon's criterion for perfect secrecy is: \[ P(c_j | p_i) = P(c_j) \quad \forall i, j. \] A straightforward application of Bayes' theorem shows that this is equivalent to: \[ P(p_i | c_j) = P(p_i) \quad \forall i, j. \] This means that discovering or intercepting the ciphertext does not provide any information on the plaintext. The second condition states that any given ciphertext is equally likely to have been generated by any plaintext. A question that you might like to ponder is how many possible keys does this require? The simplest perfectly secure cipher is the Vernam cipher, or one-time pad. It uses a key in the form of a random sequence of bits, \( \cdots 111100 \cdots \), that is at least as long as the plaintext (which is also a sequence of bits, of course). The ciphertext is produced by bit-wise modulo addition of the plaintext and the key: \[ \begin{align*} 0 \oplus 0 &= 0 \\ 0 \oplus 1 &= 1 \\ 1 \oplus 0 &= 1 \\ 1 \oplus 1 &= 0. \end{align*} \] A simple example is: \[ \begin{align*} P & \cdots 00110100 \cdots \\ K & \cdots 11101100 \cdots \end{align*} ``` #################### File: Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf Page: 17 Context: ```markdown # Quantum Communications and Quantum Key Distribution The ciphertext \( C \) is random because the key \( K \) is random. Deciphering is performed by Bob by a second modulo addition of the key. This works because \( C \oplus K = \cdots \texttt{00000000} \cdots \) \[ C \cdots 1000111100 \cdots \] \[ K \cdots 1011101000 \cdots \] \[ P = C \oplus K \cdots 0010110100 \cdots \] Clearly, the secrecy of the key is crucial, as anyone in possession of it can decipher the message. The remaining problem, of course, is how can Alice and Bob exchange the key \( K \)? To see how this and other secure communications are realized in practice, we need to introduce public-key cryptography, which is based on the fact that some mathematical operations are easy but the inverse inverse operation is very difficult and, hopefully, effectively impossible in practice (Buchmann 2001, Loepp and Wootters 2006, Barnett 2009). The classic example is multiplying and factoring. In public-key cryptography, Bob generates two keys, an encrypting key \( e \) and a deciphering key \( d \). He publishes \( e \) but keeps \( d \) secret. Alice can use \( e \) to encode her message, which should be all but impossible (she hopes!) for anyone other than Bob to decipher. This is the RSA cryptosystem (Buchmann 2001, Loepp and Wootters 2006, Barnett 2009). ## RSA scheme 1. Bob finds two large prime numbers, \( p \) and \( q \), and calculates \( m = p \times q \). This is easy. 2. He then finds two numbers \( e \) and \( d \) such that \( de \equiv 1 \modulo (p - 1)(q - 1) \). There are efficient algorithms for doing this if you know \( p \) and \( q \). 3. The public key is \( m \) and \( e \). The private key is \( d \). 4. Alice takes her message, which is a number \( x \), and turns it into a ciphertext by the transformation: \[ x \to x^e \modulo m \] 5. By the wonders of pure mathematics (actually it is not so hard to prove this): \[ (x^e \modulo m)^d \modulo m = x \modulo m, \] which is the original message. So Bob can recover the message using his secret key \( d \). The security of the RSA scheme is believed to be equivalent to the difficulty of factoring \( m \) into its constituent primes \( p \) and \( q \). It is certainly true that if \( p \) and \( q \) are known, then finding \( d \) from \( e \) and \( m \) is straightforward. How big does \( m \) have to be? Numbers of order \( 10^{10} \) can be factored in less than a day, so much larger numbers are needed. There is an RSA factoring challenge, which you might like to try. The number RSA-212, which is \( 7 \times 10^{12} \) bits. ``` #################### File: Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf Page: 18 Context: ```markdown # Quantum copying? factored in July 2012 to claim a $30,000 prize. There is currently a $75,000 prize to anyone who can produce the two prime factors of the 270 decimal digit number [http://en.wikipedia.org/wiki/RSA](http://en.wikipedia.org/wiki/RSA) accessed October 21 (2013): ``` RSA-896 = 112023436896695845351363253759174116998143279828545456 26338764555648246196890987214618179761240421858894256931917763750 334211389297481594091089109201692068136297401188688696706956209306536 588674337123701310415910496245739282601319752640339463972639391 ``` Public key cryptography is routinely used to distribute keys and for proof of identity via so-called digital signatures. ## 2.3 Quantum copying? Quantum key distribution is a radically different approach to secure communications. It relies on the difficulty for anyone eavesdropping in determining the quantum signal generated by Alice. Before describing this in detail, we show that it is impossible to copy an unknown quantum state. This is the famous no-cloning theorem of Wootters and Zurek (1982) and of Dieks (1982). It works by exposing a contradiction. Suppose that you are given a qubit in some unknown (to you) quantum state: $$ |\psi\rangle = a|0\rangle + b|1\rangle \tag{2.9} $$ that is, you do not know the amplitudes \(a\) and \(b\). Clearly you could do a measurement but that will not tell you \(|\psi\rangle\). What you would like to achieve is a transformation on this qubit and a "blank" prepared in the state \(|B\rangle\) such that: $$ |\psi\rangle \otimes |B\rangle \rightarrow |\psi\rangle \otimes |\psi\rangle \tag{2.10} $$ Let us suppose that this works if \(|B\rangle = |0\rangle\) or \(|1\rangle\), so that $$ |0\rangle \otimes |B\rangle \rightarrow |0\rangle \otimes |0\rangle $$ $$ |1\rangle \otimes |B\rangle \rightarrow |1\rangle \otimes |1\rangle \tag{2.11} $$ The superposition principle then tells us that for a general state \(|\psi\rangle\) the corresponding transformation is $$ |\psi\rangle \otimes |B\rangle = (a|0\rangle + b|1\rangle) \otimes |B\rangle \rightarrow a|0\rangle \otimes |B\rangle + b|1\rangle \otimes |B\rangle \neq (a|0\rangle + b|1\rangle) \otimes (a|0\rangle + b|1\rangle) \tag{2.12} $$ So it necessarily follows from the superposition principle that a quantum cloner cannot work perfectly for all quantum states. Having established that strictly exact cloning of an unknown state is not possible, we might very reasonably ask what is the best that is possible. There has been a great deal of work on this topic, but probably the most important is the universal quantum-copying machine: the operation of which is the best possible with the same performance for all possible input qubit states (Buzek and Hillery 1996, Scarani et al 2005). ``` #################### File: Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf Page: 19 Context: ```markdown ## 2.4 Optical polarization Recall that for a plane wave, the electric field \(\mathbf{E}\), the magnetic field \(\mathbf{H}\), and the wavevector \(\mathbf{k}\) are all mutually orthogonal and are oriented such that \(\mathbf{E} \times \mathbf{H}\) points in the direction of \(\mathbf{k}\) (see Fig. 2.2). This fixes \(\mathbf{E}\) and \(\mathbf{H}\) to be in the plane perpendicular to \(\mathbf{k}\). ![Fig. 2.2](attachment.png) *Relative orientations of the electric and magnetic fields and the wavevector. Reproduced, with permission, from Barnett (2009).* Consider a complex electric field for a plane wave propagating in the \(z\)-direction: \[ \mathbf{E} = \mathbf{E}_0 e^{i(\mathbf{k} \cdot \mathbf{r} - \omega t)}. \tag{2.13} \] We can characterize the polarization by the direction of the complex vector \(\mathbf{E}_0\) in the \(x - y\) plane: \[ \mathbf{E}_0 = E_{0x} \hat{\imath} + E_{0y} \hat{\jmath}. \tag{2.14} \] or as a column vector, the Jones vector: \[ \mathbf{E}_0 = \begin{bmatrix} E_{0x} \\ E_{0y} \end{bmatrix}. \tag{2.15} \] Only the relative sizes of \(E_{0x}\) and \(E_{0y}\) matter, so we can use a normalized Jones vector. The Jones vectors corresponding to horizontal/vertical, diagonal, and circular polarizations are depicted in Fig. 2.3. For a single photon, we can associate each of the Jones vectors with a qubit state according to the mapping: \[ \begin{bmatrix} \alpha \\ \beta \end{bmatrix} \rightarrow \alpha |0\rangle + \beta |1\rangle, \tag{2.16} \] which leads to the identifications listed in Fig. 2.4. This simple idea has been used widely in experimental demonstrations of a variety of quantum information and communications protocols, most especially in quantum cryptography. ## 2.5 Quantum cryptography Quantum cryptography, or perhaps more precisely quantum key distribution, has become an advanced experimental technique and is on the verge, perhaps, of becoming a... ``` #################### File: Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf Page: 21 Context: ```markdown # Quantum Communications and Quantum Key Distribution practical technology. In these lectures I can give only a brief overview of the topic and, for a more complete description, refer the reader to some of the introductory literature on the subject (Phoenix and Townsend 1995, Bouwmeester et al. 2000, Gisin et al. 2002, Looup and Wootters 2006, Van Assche 2006, Barnett 2009). The idea of using quantum effects for security is due to Stephen Wiesner (1983) who suggested (in a paper written in about 1970 but published only much later) the idea of unforgeable money. He proposed a high-value banknote worth, say, **£10M**. Each *note* would have traps for 20 single photons, each of which was prepared in one of the polarization states: - \( |0\rangle \) - \( \frac{1}{\sqrt{2}} (|0\rangle + |1\rangle) \) - \( |1\rangle \) The note also has a serial number which identifies the bank that states of these photon polarizations. The problem faced by a would-be forger is how to copy these unknown quantum states? The no-cloning theorem tells us, of course that this is impossible. The situation is illustrated in Fig. 2.5. The counterfeiter needs to work out the polarization of each of the prepared photons and do so only by performing measurements, but he/she has no idea which measurement to perform. Let us focus our attention on one of the photons that happens to be prepared in a state of vertical polarization. If the counterfeiter measures this in the horizontal/vertical basis then the result will be a bank note with the correct horizontally polarized photon. If, however, the counterfeiter measures in the diagonal basis then either of the two possible results will occur with equal probability and, importantly, there is no indication possible that the measurement has been performed in the incorrect basis. If the polarization is checked in the bank then an error will be produced with a probability \( \frac{1}{2} \). It follows that for a bank note produced in this way, anyone checking in the bank will see an error (indicating a forgery) with a probability of \( \frac{1}{4} \) for each of the twenty photons. The probability that all 20 photons in the forged note pass a test in the bank is \( \left( \frac{1}{4} \right)^{20} = 0.003 \). If this isn’t considered low enough, then one simply has to add a few more light traps. ## Figure 2.5 Possible outcomes due to the intervention of a counterfeiter, together with their associated probabilities of occurrence. Reproduced, with permission, from Barnett (2009). ``` Counterfeiter - |1⟩ - 1 - 1/2 - 1/2 - |0⟩ - 1/4 - 1/2 - |1⟩ - 1/2 - 1/4 - |1⟩ - 1/4 - |0⟩ Bank - |1⟩ - 1/4 - 1/2 - |0⟩ - 1/2 - 1/4 ``` #################### File: Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf Page: 28 Context: ```markdown # Probability operator measures how this might be done, consider a quantum system \( s \), which we wish to measure, and let us prepare also an ancillary quantum system \( a \), so that we know its initial state. The state of the combined system and ancilla is then \( | \psi \rangle \otimes | \phi \rangle_A \). Next we engineer an interaction between the system and the ancilla, so that a unitary transformation of our choosing occurs: \[ | \psi \rangle \otimes | \phi \rangle_A \rightarrow U| \psi \rangle \otimes | \phi \rangle_A. \] Finally, we perform a von Neumann measurement on both the system and the ancilla, so that the probability for a given outcome will be \[ P(m,l) = \left| \langle m | \mathcal{A} U | \psi \rangle \otimes | \phi \rangle_A \right|^2 = \langle \phi | \hat{R}_{m} | \phi \rangle, \] where \[ \hat{R}_{m} = \mathcal{A}(|\psi\rangle_{m}) \otimes \langle \phi | \mathcal{A} | \psi \rangle. \] which is an operator acting only on the system state space. It is clearly Hermitian and positive. That it sums to the identity follows, moreover, from the completeness of the orthonormal states \(\{ | m \rangle \}\) and \(\{ | \phi \rangle \}\). It follows that the operators \(\hat{R}_{m}\) are probability operators. Let us give a simple but important example of a generalised measurement: the simultaneous measurement of the position and momentum of a particle. This is something that we do all the time in our predominantly classical world, but, because position and momentum are incompatible observables, cannot be described as a von Neumann measurement. Let us write the probability density for a joint measurement to give a position between \( x_m \) and \( x_m + dx_m \), and also a momentum between \( p_m \) and \( p_m + dp_m \), as \[ P(x_m, p_m) = \text{Tr}[\hat{R}(x_m, p_m)]. \] where the \(\hat{\chi}(x_m, p_m)\) are positive operators satisfying the continuum condition \[ \Rightarrow \int_{-\infty}^{\infty} dx_m \int_{-\infty}^{\infty} dp_m \hat{\chi}(x_m, p_m) = 1. \] A good simultaneous measurement of the position and momentum of a body will localise rather well both quantities. In order to produce a plausible measurement operator, let us introduce a Gaussian state: \[ |x_m, p_m\rangle = \frac{(2\pi \hbar)^{-1/4}}{\sqrt{\int_{-\infty}^{\infty} dx \, \exp\left[-\frac{(x - x_m)^2}{4a^2}\right] \frac{2}{\hbar}} | x \rangle. \] where \( | x \rangle \) is a position eigenstate. We note that these states form an over-complete set in that \[ \frac{1}{2\pi \hbar} \int_{-\infty}^{\infty} dx_m \int_{-\infty}^{\infty} dp_m \hat{\chi}(x_m, p_m) = \hat{I}. \] ``` #################### File: Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf Page: 31 Context: ```markdown # 2.8 Generalized Measurements The two measurement outcomes correspond to projectors onto the positive and negative eigenvalues of ρ̃1 and ρ̃2, corresponding, respectively, to identifying the state as ρ̃1 and ρ̃2. This gives us the minimum error probability the Helstrom bound: \[ p_{\text{min error}} = \frac{1}{2} \left( 1 - \text{Tr} \left[ \rho \hat{\pi}_1 - \rho \hat{\pi}_2 \right] \right). \tag{3.30} \] It is interesting to note that sometimes a measurement does not help and the minimum-error strategy is simply to guess that the most likely state was prepared (Hunter 2003). As an example, let us suppose that we have a single qubit which we know to have been prepared with equal probability ($p_1 = \frac{1}{2} = p_2$) in one of the two non-orthogonal states: \[ |\varphi_1\rangle = \cos(\theta/2)|0\rangle + \sin(\theta/2)|1\rangle, \tag{3.31} \] \[ |\varphi_2\rangle = \cos(\theta/2)|0\rangle - \sin(\theta/2)|1\rangle, \tag{3.32} \] so that the overlap of the states is \[ \langle \varphi_1 | \varphi_2 \rangle = \cos 2\theta. \tag{3.33} \] It is straightforward to confirm that the minimum error strategy corresponds to the two probability operators \[ \hat{\pi}_1 = \frac{1}{2} \left( |0\rangle \langle 0| + |1\rangle \langle 1 | \right) = |\varphi_1\rangle\langle\varphi_1|, \tag{3.34} \] \[ \hat{\pi}_2 = \frac{1}{2} \left( |0\rangle \langle 0| - |1\rangle \langle 1| \right) = |\varphi_2\rangle\langle\varphi_2|. \tag{3.35} \] The arrangement of these states is depicted in Fig. 3.1. We see that the optimal measurement in this case corresponds to projection onto one of a pair of states $\{ |\varphi_1\rangle \text{ or } |\varphi_2\rangle \}$. The error probability arises from the fact that $|\varphi_1\rangle$ is not perpendicular to $|\varphi_2\rangle$. A simple experiment has been performed at this limit to discriminate between two states of photon linear polarization (Barnett and Ruis 1997). By no means all optimal measurements are von Neumann measurements. Indeed, a generalized measurement is normally required. As a simple illustration, consider the trine ensemble in which a qubit is prepared (with equal probability) in one of three states: \[ |\varphi_1\rangle = |0\rangle, \tag{3.36} \] \[ |\varphi_2\rangle = \frac{1}{\sqrt{2}} \left( |0\rangle + \sqrt{3}|1\rangle \right), \tag{3.37} \] \[ |\varphi_3\rangle = \frac{1}{2} \left( |0\rangle + \sqrt{3}|1\rangle \right). \tag{3.38} \] These correspond to states separated by 120° on a great circle of the Bloch sphere. As depicted in Fig. 3.2, the minimum-error strategy in this case corresponds to the three probability operators \[ \hat{\pi}_1 = \frac{2}{3}|\varphi_1\rangle\langle\varphi_1| \tag{3.39} \] and gives an error probability of \(\frac{1}{3}\), so that this measurement strategy determines the correct state with probability \(\frac{2}{3}\). The required generalized measurement has been ``` #################### File: Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf Page: 32 Context: ```markdown # Optimized Measurements ## 3.1 Orientation in State Space Orientation in state space of the two non-orthogonal states to be discriminated and the directions along which it is best to measure. Reproduced, with permission, from Barnett (2009). ![Fig. 3.1](path/to/image1) Demonstrated using photon polarization qubits; the device is an interferometer in which the path taken through the device provides the ancillary degree of freedom (Clarke et al. 2001b). ![Fig. 3.2](path/to/image2) The trine states depicted on the Bloch sphere. Reproduced, with permission, from Barnett (2009). ``` #################### File: Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf Page: 34 Context: ```markdown # Operations and the post-measurement state ## 3.5 Operations and the post-measurement state We have not yet addressed the question of how the measurement process modifies the quantum state in a generalized measurement[^1]. There are two pressing reasons for proceeding beyond the von Neumann ideal in which the quantum system is left in an eigenstate corresponding to the measurement outcome. The first is that most real measurements are more destructive than this, and the second is that it gives us no idea how to describe the post-measurement state for a generalised, that is non-projective, measurement. A rigorous treatment takes us into the mathematical world of effects and operations (Kraus 1983). Rather than this, we present only an indication of what is required. For a more complete treatment we refer the reader to (Croke et al. 2008, Barnett 2009). We start by noting that quantum theory is linear in the density operator and this suggests that an allowed transformation of a density operator should be of the form $$ \hat{\rho} \rightarrow \hat{\rho}' = \sum_i A_i \hat{\rho} A_i^\dagger. \tag{3.38} $$ Not every set of operators $\{A_i, B_i\}$ will be allowed, however, as the transformed density operator must, itself, be a density operator. This means that it must be Hermitian, $\hat{\rho}' = \hat{\rho}'^\dagger$, it must be positive, $\langle \psi | \hat{\rho}' | \psi \rangle \geq 0$, and it must have unit trace, $\text{Tr}(\hat{\rho}') = 1$. The first of these conditions suggests that we should set $B_i = A_i^\dagger$ and doing so automatically ensures that the second is fulfilled. The final one, the preservation of the unit trace, is satisfied if we set $\sum_i A_i^\dagger A_i = I$. The operator $A_i^\dagger A_i$ is positive and also Hermitian. The fact that we require the sum of these products to equal the identity operator, moreover, suggests the natural identification $$ \hat{\pi}_i = A_i^\dagger A_i, \tag{3.39} $$ and this allows us to complete the required description of the change of state after a measurement. If we know that a measurement has been performed but do not know the measurement outcome then the density operator is transformed as $$ \hat{\rho} \rightarrow \sum_i A_i \hat{A}_i. \tag{3.40} $$ If we know that measurement result $i$ was recorded, however, then the state is transformed as $$ \hat{\rho} \rightarrow \frac{A_i \hat{\rho} A_i^\dagger}{\text{Tr}(A_i A_i^\dagger)} \hat{\pi}_i. \tag{3.41} $$ In order to arrive at a unit-trace density operator in this case, we have divided by the a priori probability for the measurement result. This is directly analogous to the procedure in the von Neumann scheme, in which the transformation is [^1]: Time did not permit me to address this question at the School, but these notes would be incomplete without at least a brief account of it. ``` #################### File: Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf Page: 35 Context: ```markdown # 3.2 Generalized Measurements \[ \hat{\rho} \rightarrow \frac{\hat{P}_i \hat{\rho} \hat{P}_i^\dagger}{\text{Tr}(\hat{P}_i \hat{\rho})}. \tag{3.42} \] It should be noted that a set of Kraus operators \(\{ \hat{A}_i \}\) determine uniquely a corresponding set of probability operators \(\{ p_i \}\), but the converse is not true; assigning the probability operators does not determine a unique transformation on the state. ``` #################### File: Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf Page: 36 Context: ```markdown # 4 Entanglement and its Applications More than any other feature, it is entanglement that gives quantum theory its distinctive character. It is the source of paradoxes, the most famous of which is the much discussed EPR paradox (Einstein et al. 1935, Bohr 1935, Wheeler and Zurek 1983, Whitaker 2006), or tests of distinctive ‘quantumness’, such as the violation of Bell’s famous inequality (Bell 1964, 1987), and it underlies some of the more unexpected (and headline-grabbing) features of quantum information such as teleportation (Bennett et al. 1993). ## 4.1 Entangled States and Non-locality We should start by stating what entanglement is. The simplest answer is that it is the distinctive property of entangled states, which leads us to ask “what are entangled states?”. This is, in fact, a surprisingly difficult question to answer, at least in full generality. For the purposes of these all too brief lectures we shall avoid completely the tricky issue of entanglement for mixed states and discuss only pure states. For pure states there is a clear definition but it is the definition of states that are *not* entangled. A state that is not entangled is a state of two or more quantum systems that can be factorized into a product of single-system states. States that do not have this property are entangled. For two quantum systems, A and B, the combined state, |\psi\rangle_{AB}, is entangled if \[ |\psi\rangle_{AB} \neq |\psi\rangle_A \otimes |\psi\rangle_B. \tag{4.1} \] Consider, for example, the two-qubit state \[ |\psi\rangle = \cos(\theta)| 0 \rangle | 1 \rangle - \sin(\theta)| 1 \rangle | 0 \rangle. \tag{4.2} \] This state will not be entangled if \(\theta = \pi/2\), but will be entangled for all other values of \(\theta\). For entangled states, the properties of the A and B systems are quantum correlated. We can see this in the above example in that determining whether the first qubit is in the state \(|0\rangle\) or the state \(|1\rangle\) also determines the, previously undetermined, state of the second qubit. The implications of the existence of entanglement are profound and many. In these lectures we shall address only five: 1. EPR and related non-locality paradoxes. ``` #################### File: Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf Page: 40 Context: ```markdown # Quantum "magic tricks" 37 In an attempt to detect the effect of Alice's choice, Bob makes a measurement characterized by the probability operators \{A^B_j\}. The joint probabilities for Alice's and Bob's measurement results are given by $$ P(B_j | k) = \langle \Psi | A^{A,1}_{k} \otimes A^B_j | \Psi \rangle \quad (4.15) $$ where \( |\Psi\rangle \) is the joint state of Alice's and Bob's system. If Alice's choice is to affect Bob's observation, then we need the probabilities for Bob's measurement results to depend on Alice's choice of measurement. This is clearly not the case, however, as $$ P(k) = \sum_j P(B_j | k) = \langle \Psi | \Psi \rangle \quad (4.16) $$ where we have used the fact that our probability operators sum to the identity operator: $$ \sum_j A^{A,1,2}_{j} = \mathbb{I} \quad (4.17) $$ The probabilities of any of Bob's possible measurement results is **independent** of Alice's choice of measurement and, indeed, are the same whether Alice performs a measurement at all. Nothing Alice does to her quantum system is detectable by Bob and hence no signalling is possible by quantum measurement of a distant system. The no-signalling theorem is a rigorous consequence of quantum theory and can be used, in quantum information theory, to place bounds on what is and is not possible. As a simple example, we can derive a lower bound on the probability for an inconclusive outcome in unambiguous state-discrimination using the no-signalling condition (Barnett and Anderson 2002). ## 4.2 Quantum "magic tricks" The Bell inequality is one of an impressive array of startling and testable consequences of entanglement (Redhead 1987; Greenberger et al. 1990; Mermin 1990). Were these lectures about the mysteries of quantum theory, then we might enjoy exploring these, but our purpose is not to test entanglement and its consequences, but rather to exploit it. We shall present one example, however, of a testable consequence of entanglement as it points to a necessary distinction between logical reasoning in quantum theory and the classical world. Hardy (1993, Goldstein 1994) presented a simple demonstration of non-locality without an inequality. This is instructive in that it provides a warning against reasoning on the basis of what might have been measured rather than what actually was observed. The following short presentation is reproduced, essentially verbatim, from Barnett (2009). Consider a pair of qubits, one held by Alice and the other by Bob, prepared in the pure state $$ |Hardy\rangle = \frac{1}{\sqrt{3}} \left( |0\rangle_A \otimes |0\rangle_B + |1\rangle_A \otimes |0\rangle_B + |0\rangle_A \otimes |1\rangle_B \right) \quad (4.18) $$ We proceed by noting that this state can also be written in the form ``` #################### File: Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf Page: 42 Context: ```markdown # Quantum dense coding A pair of maximally entangled qubits, then we say that they share a ebit. By maximally entangled we mean pure states such that the reduced density operator for each of the component qubits is of the form \( \frac{1}{2} \). This means that we can identify the state only by bringing together the component qubits and that a measurement of just a single qubit is maximally uncertain. It is important to ask how we can get to a situation in which two parties share an ebit. One way, of course, is to prepare an entangled state at one site and then transport (carefully) one of the entangled qubits to the other site. We might very reasonably ask, however, if it is not possible to achieve the same result by means of classical communications, by exchanging instructions between the distant sites. That this is not possible follows directly from what we already know. Let us suppose that Alice prepares the entangled state \[ |\psi\rangle = \frac{1}{\sqrt{2}} \left( |0\rangle |1\rangle - |1\rangle |0\rangle \right). \tag{4.22} \] To share this state with Bob she can send the second qubit to Bob by means of a suitable quantum communications channel. The resulting quantum correlations between the qubits (at least for a sufficient number of entangled pairs) could be used to demonstrate a violation of a Bell inequality. Such a violation is not possible, of course, for any classical or classically-mediated correlations. Hence we can conclude, without the need for further analysis, that classical and quantum communications are radically different in nature. The antisymmetric state, \( |\psi^-\rangle \), is not the only maximally entangled state of two qubits. Indeed, we can create a complete basis of four orthonormal states for two qubits, each of which is similarly maximally entangled. One simple choice is the set of states, now referred to as the Bell states or the Bell basis. These four states are \[ |\psi^+\rangle = \frac{1}{\sqrt{2}} \left( |0\rangle |0\rangle + |1\rangle |1\rangle \right) \] \[ |\psi^-\rangle = \frac{1}{\sqrt{2}} \left( |0\rangle |1\rangle - |1\rangle |0\rangle \right). \tag{4.23} \] As these states form an orthonormal basis, we can perform a von Neumann measurement on the two qubits with each of these four corresponding to a different outcome. This “Bell measurement” cannot be performed, however, simply combining a von Neumann measurement on each individual qubit. ## 4.4 Quantum dense coding A very simple application of the Bell states, perhaps the simplest, is in quantum dense coding (Bennett and Brassard 1984). The starting point is the observation that a von Neumann measurement of a qubit can provide at most one bit of information. To see how this works, we need only consider a qubit that has been prepared with equal probability in either of the two orthonormal states, \( |0\rangle \) and \( |1\rangle \). A simple projective measurement in this basis will reveal the state that has been prepared and provide a single bit. ``` #################### File: Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf Page: 43 Context: ```markdown # 4.0 Entanglement and its Applications By using an ent bit, we can, in a sense, double this rate by communicating two bits of information for every qubit sent from Alice to Bob. Let us start with a single ent bit shared by Alice and Bob, prepared in the state \[ | \psi \rangle_{AB} = \frac{1}{\sqrt{2}} \left( | 0 \rangle_A | 1 \rangle_B - | 1 \rangle_A | 0 \rangle_B \right). \tag{4.24} \] Bob selects one of four unitary transformations to perform on his qubit. These transformations, and the effect of the corresponding entangled state, are listed below: \[ \begin{aligned} U_1 & : | 0 \rangle_B | 1 \rangle_B \rightarrow | \psi^- \rangle_{AB} \\ U_2 & : | 0 \rangle_B | 1 \rangle_B \rightarrow | \psi^+ \rangle_{AB} \\ U_3 & : | 0 \rangle_B | 0 \rangle_B \rightarrow | \phi^- \rangle_{AB} \\ U_4 & : | 0 \rangle_B | 1 \rangle_B \rightarrow | \phi^+ \rangle_{AB} \end{aligned} \] \[ \tag{4.25} \] We see that the effect of Bob's choice is to transform the state of the entangled pair of qubits into one of the four orthogonal Bell states. Hence by sending just his single qubit to Alice he can send two bits of information (recall that 4 = 2² states correspond to 2 bits). In order to retrieve the information, Alice simply performs a Bell measurement on the two qubits comprising the ent bit and extracts the two bits². It is interesting to reflect on the nature of a Bell measurement and, in particular, to try to understand it in terms of spin measurements. We know, of course, that the Pauli operators $\sigma_x$, $\sigma_y$, and $\sigma_z$ do not mutually commute. It may come as something of a surprise, therefore, that the products of these Cartesian components of the spin, $\sigma_x \sigma_y$, $\sigma_y \sigma_z$, and $\sigma_z \sigma_x$, commute for any pair of qubits. The Bell states are the simultaneous eigenstates of these three product operators: \[ \begin{aligned} \sigma_x | \psi^- \rangle & = -| \psi^- \rangle & \quad \sigma_y | \psi^- \rangle & = -| \psi^- \rangle \\ \sigma_z | \psi^- \rangle & = -| \psi^- \rangle & \quad \sigma_x | \psi^+ \rangle & = | \psi^+ \rangle \\ \sigma_y | \psi^+ \rangle & = | \psi^+ \rangle & \quad \sigma_z | \psi^+ \rangle & = | \psi^+ \rangle \\ \end{aligned} \] \[ \sigma_x \sigma_y | \psi^-\rangle = -\sigma_z | \psi^-\rangle. \tag{4.26} \] Thus the Bell states are those in which the products of the Cartesian components of the spin are defined, and we can view a Bell measurement as a comparison of the three components of spin for the two qubits. You may have noticed, in fact, that it suffices to compare only two components of the spin as the final one is then defined. The reason for this lies in the fact that the product of any two Pauli spin operators is proportional to the third and, in particular, \[ \sigma_x \sigma_y = -\sigma_y \sigma_x. \tag{4.27} \] ¹ Although it sounds easy to perform a Bell measurement, achieving this in practice is, perhaps not surprisingly rather more of a challenge (Mattle et al. 1996). ``` #################### File: Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf Page: 44 Context: ```markdown ### 4.5 Teleportation Our final application is quantum teleportation. This is an important application of entanglement and came as something of a surprise when it was first proposed (Bennett et al. 1993). We should be very clear before proceeding however, that quantum teleportation is not matter transportation like something out of the popular science fiction series Star Trek. A better understanding may be reached, I feel, by adopting the description proposed by Hardy, which is quantum teleportation is a "fax machine for quantum information". It is the quantum information, or rather the quantum state that is transferred and not the physical system on which the qubit state is stored. Let us suppose that Alice wishes to send a qubit to Bob. She may know the state of the qubit or she may not. We have seen that quantum communications and classical communications are very different and so should not be surprised that there is, in general, no classical way to achieve this. Alice has two ways to achieve the desired result: (i) she can send the physical qubit carrying the quantum information to Bob (we might call this "small"), or (ii) she can teleport the quantum information to Bob using an ebit of shared entanglement (which we might call a "qfax"). Alice can teleport the qubit state $$ |\psi\rangle = \alpha|0\rangle + \beta|1\rangle \tag{4.28} $$ by making use of an ebit of the form $$ |\Phi\rangle_{AB} = \frac{1}{\sqrt{2}} (|0\rangle_A |1\rangle_B - |1\rangle_A |0\rangle_B), \tag{4.29} $$ shared with Bob. We can write the combined state of the three qubits as $$ |\Psi\rangle_{1AB} = |\psi\rangle \otimes |\Phi\rangle_{AB} = \frac{1}{2} \left[ |\psi\rangle_{1A} \otimes (-\alpha|0\rangle_B + \beta|1\rangle_B) + |\psi\rangle_{1A} \otimes (-\beta|0\rangle_B + \alpha|1\rangle_B) + |\psi\rangle_{1A} (\alpha|1\rangle_B - \beta|0\rangle_B) \right]. \tag{4.30} $$ In arriving at the final expression, we have only rewritten the state, but the quantum information, in the form of the coefficients α and β, have appeared connected with Bob’s qubit. We know, however, that Bob cannot yet access this information, for to do so would violate the no-signalling theorem. If Alice performs a Bell measurement on her two qubits (qubits 1 and A) she can then tell Bob which of four possible transformations to perform on qubit B in order to change its state into |\psi\rangle. The idea is best understood in terms of an example. Let us suppose that Alice’s Bell measurement gives a result corresponding to the state \( |\psi\rangle \). ``` #################### File: Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf Page: 46 Context: ```markdown # Teleportation by either Alice or Bob is dependent on these amplitudes and it follows that Alice does not need to know the state to be teleported. 4. The qubit to be teleported may itself be part of an entangled state and in this way we can teleport entanglement. In this way, if Alice shares an ebit with Bob and also one with Claire, then she can teleport the entanglement to leave Bob and Claire sharing an ebit: \[ | \psi^{-} \rangle_{C1} \otimes | \psi^{-} \rangle_{AB} = | \psi^{-} \rangle_{CB}. \] This process of transferring entanglement by teleportation is commonly referred to as entanglement-swapping. ``` #################### File: Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf Page: 47 Context: ```markdown # 5 Quantum Computation No course on quantum information would be complete without a treatment of quantum computation. Yet covering such a diverse topic in a single lecture presents, if anything, an even greater challenge than the areas addressed in the preceding lectures. The material selected for this lecture can only provide a modest forecast of the topic that spans a number of disciplines, including physics and computer science, and for a more satisfying introduction I can only recommend some texts for further reading (Nielsen and Chuang 2000, Stenlund and Suominen 2005, Vedral 2006, Mermin 2007, Kaye et al. 2007, Barnett 2009, Gay and Mackie 2010, Pachos 2012). We should start by asking why the idea of quantum computers seems to have become so prominent. There are, I think, two very good reasons. The first is in response to a very pressing need. The speed of development in computers has been truly remarkable and follows an exponential increase in performance first described by Moore in 1965 (Moore 1965). There are many versions of this law, but perhaps the simplest is that the number of transistors on a chip doubles roughly every two years. The way this is achieved is by making the individual transistors ever smaller. As we make components ever smaller, however, we must inevitably run into quantum effects. Rather than fight against quantum mechanics (a battle we must lose at some size scale) perhaps it would be better to embrace the new possibilities provided by quantum information processing. The second reason is the distinctively new possibilities offered by quantum algorithms (which can only run on a quantum computer). These address problems that will always remain intractable for a computer based on classical logic and include simulations of complex quantum systems (like large molecules) and the headline-grabbing Shor's algorithm for factoring, of which more later. ## 5.1 Digital Electronics We begin our discussion by describing the way in which logical bits and logic operations are implemented classically. In the simplest form, the logical bits 1 and 0 are encoded as voltages – a high voltage for 1 and ground or zero volts for 0. These values are manipulated by transistor-based devices called gates (Smith 1983). The most common of these act either on a single bit value or couple two together. There is only one single-bit gate, the NOT gate, which simply changes a 1 to a 0 and a 0 to a 1. The symbols for the NOT gate and its truth table are given in Fig. 5.1. The simplest two-bit gates are the AND and the OR gate, depicted in Fig. 5.2. Combinations of these together with a NOT gate to form NAND and NOR gates are also common. These two-bit gates, together with the NOT gate, allow us to perform any logical operation (strictly ``` #################### File: Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf Page: 50 Context: ```markdown # Quantum gates ## Fig. 5.4 The CNOT gate and its effect on the computational basis states. Reproduced, with permission, from Barnett (2009). In digital electronics, a small number of gates suffices to allow all possible Boolean operations and, remarkably, something very similar holds for quantum gates. We can perform any unitary evolution of a set of qubits by acting on them only with single-qubit gates and a suitable two-qubit gate; the CNOT gate suffices for this purpose. We do not prove this assertion here as the required demonstration would take too long and occupy too much space. The proof is not particularly difficult, however, and may be find in the (Nielsen and Chuang 2000, Barnett 2009). As an example we can construct the three-qubit Tofoli gate, or controlled-controlled NOT gate using single-qubit and two-bit gates. The operation of the Tofoli gate is most readily understood in the computational basis, |0⟩, |1⟩ for the three qubits: $$ |A\rangle \otimes |B\rangle \otimes |C\rangle \rightarrow |A\rangle \otimes |B\rangle \otimes |C \oplus (A \cdot B)\;, $$ (5.2) where A, B, and C take the values 0 or 1. In words, the gate leaves the computational basis of the first and second qubits unchanged but flips the state, |0⟩ ↔ |1⟩, of the third qubit if both the first and second qubits are in the state |1⟩. The Tofoli gate and its implementation in terms of two-qubit gates is given in Fig. 5.5. This involves two CNOT gates and three controlled unitary gates, in which the designated unitary transformation, $$ \tilde{W} = \frac{1}{2} (I - i\tilde{d})\;, $$ (5.3) $$ \tilde{W}^{\dagger} = \frac{1}{2} (I + i\tilde{d})\;, $$ is performed on the target qubit if the control qubit is in the state |1⟩ and the identity is applied if it is in the state |0⟩. The controlled unitary operation may also be implemented using CNOT gates and single-qubit gates if desired (Barnett 2009). ``` #################### File: Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf Page: 52 Context: ```markdown # Principles of Quantum Computation ## Unitary Transformation $$ 101101001 \rightarrow |1\rangle \otimes |0\rangle \otimes |1\rangle \otimes |0\rangle \otimes |0\rangle \otimes |1\rangle \rightarrow \hat{U}(|1\rangle \otimes |0\rangle \otimes |1\rangle \otimes |0\rangle \otimes |0\rangle \otimes |1\rangle) \tag{5.4} $$ The computation is completed by measuring each qubit to give back a (classical) bit string which, hopefully, is the desired output: $$ \hat{U}(|1\rangle \otimes |0\rangle \otimes |1\rangle \otimes |0\rangle \otimes |0\rangle \otimes |1\rangle) \rightarrow 00011100 \tag{5.5} $$ This is not quite all there is to it. There is a problem if the function we wish to calculate gives the same value for two distinct inputs. Consider, for example, the two-bit transformation in two bits, \( A \) and \( B \), are transformed into \( A \) and \( A \) (and \( B \)): $$ 00 \rightarrow 00 \quad 01 \rightarrow 10 \quad 10 \rightarrow 11 \tag{5.6} $$ The difficulty in realizing this computation on a quantum processor in the manner indicated above is that the transformation must be unitary and that unitary transformation maintains the overlap of the initial states and our computation requires $$ |0\rangle \otimes |0\rangle \rightarrow |0\rangle \otimes |0\rangle \quad |0\rangle \otimes |1\rangle \rightarrow |0\rangle \otimes |0\rangle $$ $$ \langle 0, 0| 1\rangle = 0 \quad \rightarrow \quad \langle 0, 0| 0\rangle = 1, \tag{5.7} $$ which clearly violates this requirement. In order to be able to compute any function, we input into our quantum processor not one string of qubits but two. Let the input states of the two strings be \( |a\rangle \) and \( |b\rangle \). The first of these is the input data, with the sequence of bits encoded onto the qubits as in Eq (5.4). The second string is to act as our output and is often prepared in the state \( |0\rangle^{\otimes n} \) so that every qubit is in the state \( |0\rangle \). If the processor is to calculate the Boolean function \( f(a) \) then we require it to realize the transformation $$ |a\rangle \otimes |b\rangle \rightarrow |a\rangle \otimes |b\rangle \oplus f(a) \tag{5.8} $$ where \( \oplus \) denotes the bit-wise modulo addition. (See in Fig 5.6) It is straightforward to illustrate this: ``` |b\rangle ---------------> |a\rangle | \hat{U}_f |b\rangle \oplus f(a)\rangle ``` **Fig. 5.6** A quantum processor designed to compute the function \( f(a) \). Reproduced, with permission, from Barnett (2009). ``` #################### File: Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf Page: 54 Context: ```markdown # Principles of Quantum Computation 1. **Function Definitions** - \( f(0) = 0 \) and \( f(1) = 1 \). \[ (5.12) \] 2. **Oracle Calculation** If we want to know which function the oracle calculates, then we need to input both bits values and examine the corresponding outputs. Let us suppose, however, that our task is simply to determine whether the function calculated is a constant function or a balanced one. Classically, of course, this requires us to input both possible bit values and also requires two computations. A suitable quantum processor, however, can do this in a single step. Consider the general transformation given in Eq. (5.8), but with the two qubit strings each replaced by a single qubit so that the transformation enacted by the processor is \[ |A\rangle \otimes |B\rangle \to |A\rangle \otimes B \oplus f(A). \] \[ (5.13) \] 3. **Superposition Principle** We can make use of the superposition principle to prepare both of our qubits in a superposition state and so produce the transformation: \[ \frac{1}{2} \left( |0\rangle + |1\rangle \right) \otimes (|0\rangle \otimes |f(0)\rangle - |1\rangle \otimes |f(1)\rangle) \to \frac{1}{\sqrt{2}} \left( |0\rangle \otimes |f(0)\rangle - |1\rangle \otimes |f(1)\rangle \right) \] \[ = |0\rangle \otimes (|f(0)\rangle - |f(1)\rangle) + |1\rangle \otimes (|f(1)\rangle - |f(0)\rangle). \] \[ (5.14) \] 4. **Measurement** A simple measurement carried out on the first qubit then tells us what we need to know: if it is found to be in the state \(\frac{1}{\sqrt{2}} (|0\rangle + |1\rangle)\), then the function is constant; and if we find it in the orthogonal state \(\frac{1}{\sqrt{2}} (|0\rangle - |1\rangle)\), then the function is balanced. We have found out what we need to know by addressing the oracle only once, rather than the two calls would be required classically. 5. **The Deutsch Algorithm** The Deutsch algorithm may seem, at least at first sight, not to be an especially convincing illustration, after all we do input two qubits into the processor. The real power appears when we consider an extension of it to the Deutsch-Jozsa algorithm. In this algorithm, our input is an \( n \)-bit number and a constant output is again a single bit, 0 or 1. The function is either constant, giving either 0 or 1 for all inputs, or balanced, giving 0 for half of the inputs and 1 for the other half. Our task is to determine an algorithm that determines with certainty whether the function is constant or balanced. We can start by putting in different strings and has so as we get two different output values then we know for certain that the function compute is balanced. To know its nature for certain, however, we may have to input over half of the possible inputs which means addressing the oracle \( 2^{n-1} \) times. A quantum processor can achieve this task in a single shot, however. To see how this works, we let the first string consist of \( n \) qubits, prepared in the superposition state \(\frac{1}{\sqrt{2}} (|0\rangle + |1\rangle)^{\otimes n}\) with the second string being just a single qubit prepared in the state \(\frac{1}{\sqrt{2}} (|0\rangle - |1\rangle)\). The oracle then performs the transformation: \[ 2^{-(n+1/2)} |0\rangle \otimes |1\rangle \to 2 \cdot 2^{-(n+1/2)} \sum_{i=0}^{2^{n}-1} |i\rangle \otimes |(0) - (1)\rangle. \] \[ (5.15) \] 6. **Constant Function Condition** If the function is constant then the first string of \( n \) qubits remain in their input state, as equally-weighted superpositions of the states \(|0\rangle\), but if the function is balanced then. ``` #################### File: Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf Page: 59 Context: ```markdown # Quantum Computation Clearly, we need to control sources of decoherence to an extraordinary degree, but ultimately this will always be a losing battle. Is it all hopeless? By no means; the solution is essentially the same as we encountered in the first lecture. We can combat errors in a quantum computer by redundancy, just as we do to combat classical errors. This is a more subtle problem than in the classical regime, however. Firstly, there is the no-cloning theorem, which tells us that we cannot literally make multiple copies of our qubits. There is also the problem that quantum measurements, if not performed carefully, will modify the very qubit states that we are trying to protect. Nevertheless, there are protocols for detecting and correcting qubit errors. Perhaps the most important of these is the Steane code, in which each logical qubit is encoded onto seven logical qubits (Steane 1996, Barnett 2009), but a description of how this works will have to wait for next time. ``` #################### File: Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf Page: 64 Context: ```markdown # References Shannon, C. E. (1949) *Communication theory of secrecy systems*. Bell Sys. Tech. J. 28, 656–715. Shannon, C. E. and Weaver, W. (1949) *The mathematical theory of communication*. University of Illinois Press, Urbana. Shor, P. W. (1997) Polynomial-time algorithms for prime factorization and discrete logarithms on a quantum computer. *SIAM J. Comput.* 26, 1484–1509, arXiv:quant-ph/9508027v2. Singh, S. (1999) *The code book*. Fourth Estate, London. Singh, S. (2000) *The science of secrecy*. Fourth Estate, London. Smith, R. I. (1983) *Circuits, devices and systems* (4th edn). Wiley, New York. Steane, A. M. Error correcting codes in quantum theory. *Phys. Rev. Lett.* 77, 793–797. Stenhaug, S. and Suominen, K.-A. (2005) *Quantum approach to informatics*. Wiley, Hoboken. Saklili, L. (1929) Über die Fortpflanzung in einem thermodynamischen System bei einigerm intelligent Wesen. *Zeits. Phys.* 53, 840–856. Reprinted in translation in (Wheeler and Zurek 1983; Leff and Rex 1990, 2003). Vaccaro, J. A. and Barnett, S. M. (2011) Information erasure without an energy cost. *Proc. R. Soc. A* 467, 1770–1778. Van Assche, G. (2006) *Quantum cryptography and secret-key distillation*. Cambridge University Press, Cambridge. Vedral, V. (2006) *Introduction to quantum information science*. Oxford University Press, Oxford. von Neumann, J. (1955) *Mathematical foundations of quantum mechanics*. Princeton University Press, New Jersey. Wheeler, J. A. and Zurek, W. H. (eds) (1983) *Quantum theory and measurement*. Princeton University Press, New Jersey. Whitaker, A. (2006) *Einstein, Bohr and the quantum dilemma* (2nd edn). Cambridge University Press, Cambridge. Wiesner, S. (1983) Conjugate coding. *SIGACT News* 15, 78–88. Wootters, W. K. and Zurek, W. H. (1982) A single quantum cannot be closed. *Nature* 299, 802–803. ``` #################### File: The%20Little%20Book%20About%20OS%20Development%20-%20Erik%20Helin%2C%20Adam%20Renberg%20-%20%28PDF%2C%20HTML%29.pdf Page: 3 Context: ```markdown # Contents 1. [Introduction](#introduction) 7 - [About the Book](#about-the-book) 7 - [The Reader](#the-reader) 8 - [Credits, Thanks and Acknowledgements](#credits-thanks-and-acknowledgements) 8 - [Contributors](#contributors) 8 - [Changes and Corrections](#changes-and-corrections) 8 - [Issues and where to get help](#issues-and-where-to-get-help) 9 - [License](#license) 9 2. [First Steps](#first-steps) 11 - [Tools](#tools) 11 - [Quick Setup](#quick-setup) 11 - [Programming Languages](#programming-languages) 11 - [Host Operating System](#host-operating-system) 12 - [Build System](#build-system) 12 - [Virtual Machine](#virtual-machine) 12 - [Booting](#booting) 12 - [BIOS](#bios) 12 - [The Bootloader](#the-bootloader) 13 - [The Operating System](#the-operating-system) 13 - [Hello Cafebabe](#hello-cafebabe) 13 - [Compiling the Operating System](#compiling-the-operating-system) 13 - [Linking the Kernel](#linking-the-kernel) 14 - [Obtaining GRUB](#obtaining-grub) 15 - [Building an ISO Image](#building-an-iso-image) 15 - [Running Bochs](#running-bochs) 16 3. [Further Reading](#further-reading) 17 ``` #################### File: The%20Little%20Book%20About%20OS%20Development%20-%20Erik%20Helin%2C%20Adam%20Renberg%20-%20%28PDF%2C%20HTML%29.pdf Page: 6 Context: ```markdown # 10 Page Frame Allocation Managing Available Memory - How Much Memory is There? .......................................... 61 - Managing Available Memory ........................................... 63 - How Can We Access a Page Frame? ..................................... 63 - A Kernel Heap ....................................................... 63 - Further Reading .................................................... 63 # 11 User Mode Segments for User Mode ................................................ 65 - Setting Up For User Mode ............................................. 65 - Entering User Mode .................................................. 66 - Using C for User Mode Programs ...................................... 67 - A C Library ....................................................... 68 - Further Reading .................................................... 68 # 12 File Systems Why a File System? ................................................... 69 - A Simple Read-Only File System ...................................... 69 - Inodes and Writable File Systems ..................................... 70 - A Virtual File System ............................................... 70 - Further Reading .................................................... 70 # 13 System Calls Designing System Calls ................................................ 71 - Implementing System Calls ............................................ 71 - Further Reading .................................................... 72 # 14 Multitasking Creating New Processes ................................................ 73 - Cooperative Scheduling with Yielding ................................ 73 - Preemptive Scheduling with Interrupts ................................ 74 - Programmable Interval Timer ....................................... 74 - Separate Kernel Stacks for Processes ............................... 74 - Difficulties with Preemptive Scheduling .............................. 75 - Further Reading .................................................... 75 # References ``` #################### File: The%20Little%20Book%20About%20OS%20Development%20-%20Erik%20Helin%2C%20Adam%20Renberg%20-%20%28PDF%2C%20HTML%29.pdf Page: 9 Context: ```markdown # Issues and where to get help If you run into problems while reading the book, please check the issues on GitHub for help: [GitHub Issues](https://github.com/littleosbook/littleosbook/issues). # License All content is under the Creative Commons Attribution Non Commercial Share Alike 3.0 license: [CC BY-NC-SA 3.0](http://creativecommons.org/licenses/by-nc-sa/3.0/). The code samples are in the public domain - use them however you want. References to this book are always received with warmth. ``` #################### File: The%20Little%20Book%20About%20OS%20Development%20-%20Erik%20Helin%2C%20Adam%20Renberg%20-%20%28PDF%2C%20HTML%29.pdf Page: 12 Context: ```markdown # Host Operating System All the code examples assume that the code is being compiled on a UNIX-like operating system. All code examples have been successfully compiled using Ubuntu [6] versions 11.04 and 11.10. # Build System Make [13] has been used when constructing the Makefile examples. # Virtual Machine When developing an OS, it is very convenient to be able to run your code in a virtual machine instead of on a physical computer, since starting your OS in a virtual machine is much faster than getting your OS onto a physical medium and then running it on a physical machine. Bochs [14] is an emulator for the x86 (IA-32) platform which is well suited for OS development due to its debugging features. Other popular choices are QEMU [15] and VirtualBox [7]. This book uses Bochs. By using a virtual machine, we cannot ensure that our OS works on real physical hardware. The environment simulated by the virtual machine is designed to be very similar to their physical counterparts, and the OS can be tested on one by just copying the executable to a CD and finding a suitable machine. # Booting Booting an operating system consists of transferring control along a chain of small programs, each one more "powerful" than the previous one, where the operating system is the last "program". See the following figure for an example of the boot process: ``` BIOS → GRUB1 → GRUB2 → OS ``` **Figure 2.1**: An example of the boot process. Each box is a program. # BIOS When the PC is turned on, the computer will start a small program that adheres to the Basic Input Output System (BIOS) [16] standard. This program is usually stored on a read-only memory chip on the motherboard of the PC. The original role of the BIOS program was to export some library functions for printing to the screen, reading keyboard input, etc. Modern operating systems do not use the BIOS' functions; they use... ``` #################### File: The%20Little%20Book%20About%20OS%20Development%20-%20Erik%20Helin%2C%20Adam%20Renberg%20-%20%28PDF%2C%20HTML%29.pdf Page: 17 Context: ```markdown # Further Reading - Gustavo Duarte has written an in-depth article about what actually happens when an x86 computer boots up: [How Computers Boot Up](http://duartes.org/gustavo/blog/post/how-computers-boot-up) - Gustavo continues to describe what the kernel does in the very early stages at: [Kernel Boot Process](http://duartes.org/gustavo/blog/post/kernel-boot-process) - The OSDev wiki also contains a nice article about booting an x86 computer: [Boot Sequence](http://wiki.osdev.org/Boot_Sequence) ``` #################### File: The%20Little%20Book%20About%20OS%20Development%20-%20Erik%20Helin%2C%20Adam%20Renberg%20-%20%28PDF%2C%20HTML%29.pdf Page: 21 Context: ```markdown unsigned short address; /* bit 8 - 23 */ unsigned char index; /* bit 24 - 31 */ } __attribute__((packed)); Note that `__attribute__((packed))` is not part of the C standard - it might not work with all C compilers. ## Compiling C Code When compiling the C code for the OS, a lot of flags to GCC need to be used. This is because the C code should not assume the presence of a standard library, since there is no standard library available for our OS. For more information about the flags, see the GCC manual. The flags used for compiling the C code are: ``` -m32 -nostdlib -nostartfiles -fno-builtin -fno-stack-protector -nostartfiles -nodefaultlibs ``` As always when writing C programs we recommend turning on all warnings and treating warnings as errors: ``` -Wall -Wextra -Werror ``` You can now create a function `kmain` in a file called `kmain.c` that you call from `loader.s`. At this point, `kmain` probably won't need any arguments (but in later chapters it will). ## Build Tools Now is also probably a good time to set up some build tools to make it easier to compile and test-run the OS. We recommend using `make`, but there are plenty of other build systems available. A simple Makefile for the OS could look like the following example: ```makefile OBJS = loader.o kmain.o CC = gcc CFLAGS = -m32 -nostdlib -nostartfiles -fno-builtin -fno-stack-protector \ -nostartfiles -nodefaultlibs LDFLAGS = -T link.ld -m elf_i386 AS = nasm ASFLAGS = -f elf all: kernel.elf kernel.elf: $(OBJS) ld $(LDFLAGS) $(OBJS) -o kernel.elf os.iso: kernel.elf cp kernel.elf iso/boot/kernel.elf \ && genisoimage -R \ -b boot/grub/stage2_eltorito \ --no-emul-boot \ os.iso ``` ``` #################### File: The%20Little%20Book%20About%20OS%20Development%20-%20Erik%20Helin%2C%20Adam%20Renberg%20-%20%28PDF%2C%20HTML%29.pdf Page: 23 Context: ```markdown # Chapter 4 ## Output This chapter will present how to display text on the console as well as writing data to the serial port. Furthermore, we will create our first driver, that is, code that acts as a layer between the kernel and the hardware, providing a higher abstraction than communicating directly with the hardware. The first part of this chapter is about creating a driver for the framebuffer [26] to be able to display text on the console. The second part shows how to create a driver for the serial port. Both can store output from the serial port in a file, effectively creating a logging mechanism for the operating system. ## Interacting with the Hardware There are usually two different ways to interact with the hardware: memory-mapped I/O and I/O ports. If the hardware uses memory-mapped I/O, then you can write to a specific memory address and the hardware will be updated with the new data. One example of this is the framebuffer, which will be discussed in more detail later. For example, if you write the value `0x14` to address `0x000B8000`, you will see the letter 'A' in white color on a black background (see the section on the framebuffer for more details). If the hardware uses I/O ports, then the assembly code instructions `out` and `in` must be used to communicate with the hardware. The instruction `out` takes two parameters: the address of the I/O port and the data to send. The instruction `in` takes a single parameter, the address of the I/O port, and returns data from the hardware. One can think of I/O ports as communicating with hardware the same way you communicate with a server using sockets. The cursor (the blinking rectangle) of the framebuffer is one example of hardware controlled via I/O ports on a PC. ## The Framebuffer The framebuffer is a hardware device that is capable of displaying a buffer of memory on the screen [26]. The framebuffer has 80 columns and 25 rows, and the row and column indices start at 0 (so rows are labelled 0-24). ## Writing Text Writing text to the console via the framebuffer is done with memory-mapped I/O. The starting address of the memory-mapped I/O for the framebuffer is `0x000B8000` [27]. The memory is divided into 16-bit cells, 23 ``` #################### File: The%20Little%20Book%20About%20OS%20Development%20-%20Erik%20Helin%2C%20Adam%20Renberg%20-%20%28PDF%2C%20HTML%29.pdf Page: 25 Context: ```markdown The function can then be used as follows: ```c #define FB_GREEN 2 #define FB_DARK_GREY 8 fb_write_cell(0, 'A', FB_GREEN, FB_DARK_GREY); ``` ## Moving the Cursor Moving the cursor of the framebuffer is done via two different I/O ports. The cursor's position is determined with a 16 bits integer: 0 means row zero, column zero; 1 means row zero, column one; 80 means row one, column zero and so on. Since the position is 16 bits large, and the out assembly code instruction argument is 8 bits, the position must be sent in two turns, first 8 bits then the next 8 bits. The framebuffer has two I/O ports, one for accepting the data, and one for describing the data being received. Port `0x3D4` [29] is the port that describes the data and port `0x3D5` [29] is for the data itself. To set the cursor at row one, column zero (position 80 = `0x0050`), one would use the following assembly code instructions: ```assembly out 0x3D4, 14 ; 14 tells the framebuffer to expect the highest 8 bits of the position out 0x3D5, 0x00 ; sending the highest 8 bits of 0x0050 out 0x3D4, 15 ; 15 tells the framebuffer to expect the lowest 8 bits of the position out 0x3D5, 0x50 ; sending the lowest 8 bits of 0x0050 ``` The out assembly code instruction can't be executed directly in C. Therefore, it is a good idea to wrap out in a function in assembly code which can be accessed from C via the direct calling standard [25]: ```assembly global outb ; make the label outb visible outside this file ; outb - send a byte to an I/O port ; stack: [esp + 8] the data byte ; [esp + 4] the I/O port ; [esp] return address outb: mov al, [esp + 8] ; move the data to be sent into the al register mov dx, [esp + 4] ; move the address of the I/O port into the dx register out dx, al ; send the data to the I/O port ret ; return to the calling function ``` By storing this function in a file called `io.s` and also creating a header `io.h`, the out assembly code instruction can be conveniently accessed from C: ```c #ifndef INCLUDE_IO_H #define INCLUDE_IO_H /** * outb: * Sends the given data to the given I/O port. Defined in io.s * * @param port The I/O port to send the data to * @param data The data to send to the I/O port */ ``` ``` #################### File: The%20Little%20Book%20About%20OS%20Development%20-%20Erik%20Helin%2C%20Adam%20Renberg%20-%20%28PDF%2C%20HTML%29.pdf Page: 27 Context: ```markdown # Configuring the Serial Port The first data that needs to be sent to the serial port is configuration data. In order for two hardware devices to be able to talk to each other, they must agree upon a couple of things. These things include: - The speed used for sending data (bit or baud rate) - If any error checking should be used for the data (parity bit, stop bits) - The number of bits that represent a unit of data (data bits) # Configuring the Line Configuring the line means to configure how data is being sent over the line. The serial port has an I/O port, the **line command port**, that is used for configuration. First, the speed for sending data will be set. The serial port has an internal clock that runs at 115200 Hz. Setting the speed means sending a divisor to the serial port; for example, sending 2 results in a speed of 115200 / 2 = 57600 Hz. The divisor is a 16-bit number, but we can only send 8 bits at a time. We must therefore send an instruction telling the serial port to first expect the highest 8 bits, then the lowest 8 bits. This is done by sending `0x80` to the line command port. An example is shown below: ```c #include "io.h" /* io.h is implemented in the section "Moving the cursor" */ /* The I/O ports */ /* All the I/O ports are calculated relative to the data port. This is because * all serial ports (COM1, COM2, COM3, COM4) have their ports in the same * order, but they start at different values. */ #define SERIAL_COM1_BASE 0x3F8 /* COM1 base port */ #define SERIAL_DATA_PORT(base) (base) #define SERIAL_FIFO_COMMAND_PORT(base) (base + 2) #define SERIAL_LINE_COMMAND_PORT(base) (base + 3) #define SERIAL_MODEM_COMMAND_PORT(base) (base + 4) #define SERIAL_LINE_STATUS_PORT(base) (base + 5) /* The I/O port commands */ /* SERIAL_LINE_ENABLE_DLAB: */ /* Tells the serial port to expect first the highest 8 bits on the data port, * then the lowest 8 bits will follow */ #define SERIAL_LINE_ENABLE_DLAB 0x80 /** serial_configure_baud_rate: */ /* Sets the speed of the data being sent. The default speed of a serial * port is 115200 bits/s. The argument is a divisor of that number, hence * the resulting speed becomes (115200 / divisor) bits/s. */ ``` ``` #################### File: The%20Little%20Book%20About%20OS%20Development%20-%20Erik%20Helin%2C%20Adam%20Renberg%20-%20%28PDF%2C%20HTML%29.pdf Page: 28 Context: ```markdown /** * @param con The COM port to configure * @param divisor The divisor */ void serial_configure_baud_rate(unsigned short con, unsigned short divisor) { outb(SERIAL_LINE_COMMAND_PORT(con), SERIAL_LINE_ENABLE_DLAB); outb(SERIAL_DATA_PORT(con), (divisor >> 8) & 0xFF); outb(SERIAL_DATA_PORT(con), divisor & 0xFF); } The way that data should be sent must be configured. This is also done via the line command port by sending a byte. The layout of the 8 bits looks like the following: Bit: | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | Content: | d | b | pty | s | dl | A description for each name can be found in the table below (and in [31]): | Name | Description | |------|-------------| | d | Enables (d = 1) or disables (d = 0) DLAB | | b | If break control is enabled (b = 1) or disabled (b = 0) | | pty | The number of parity bits to use | | s | The number of stop bits to use (s = 0 equals 1, s = 1 equals 1.5 or 2) | | dl | Describes the length of the data | We will use the mostly standard value `0x03` [31], meaning a length of 8 bits, no parity bit, one stop bit and break control disabled. This is sent to the line command port, as seen in the following example: /** serial_configure_line: * Configures the line of the given serial port. The port is set to have a * data length of 8 bits, no parity bits, one stop bit and break control * disabled. * * @param con The serial port to configure */ void serial_configure_line(unsigned short con) { /* Bit: | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | * Content: | d | b | pty | s | dl | * Value: | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 0x03 | */ outb(SERIAL_LINE_COMMAND_PORT(con), 0x03); } ``` #################### File: The%20Little%20Book%20About%20OS%20Development%20-%20Erik%20Helin%2C%20Adam%20Renberg%20-%20%28PDF%2C%20HTML%29.pdf Page: 29 Context: ```markdown The article on OSDev [31] has a more in-depth explanation of the values. ## Configuring the Buffers When data is transmitted via the serial port it is placed in buffers, both when receiving and sending data. This way, if you send data to the serial port faster than it can send it over the wire, it will be buffered. However, if you send too much data too fast the buffer will be full and data will be lost. In other words, the buffers are FIFO queues. The FIFO queue configuration byte looks like the following figure: | Bit: | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | |---------------|---|---|---|---|---|---|---|---| | Content: | 1 | l | v | l | 1 | b | s | r | dma | c | l | t | c | l | r | e | A description for each name can be found in the table below: | Name | Description | |-------|------------------------------------------------------| | lvl | How many bytes should be stored in the FIFO buffers | | bs | If the buffers should be 16 or 64 bytes large | | r | Reserved for future use | | dma | How the serial port data should be accessed | | clt | Clear the transmission FIFO buffer | | clr | Clear the receiver FIFO buffer | | e | If the FIFO buffer should be enabled or not | We use the value `0xC7 = 11000000` that: - Enables FIFO - Clears both receiver and transmission FIFO queues - Uses 14 bytes as size of queue The WikiBook on serial programming [32] explains the values in more depth. ## Configuring the Modem The modem control register is used for very simple hardware flow control via the Ready To Transmit (RTS) and Data Terminal Ready (DTR) pins. When configuring the serial port we want RTS and DTR to be 1, which means that we are ready to send data. The modem configuration byte is shown in the following figure: | Bit: | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | |---------------|---|---|---|---|---|---|---|---| | Content: | 1 | r | 1 | a | 1 | b | a | c | 2 | a | 0 | 1 | r | t | s | d | t | A description for each name can be found in the table below: ``` #################### File: The%20Little%20Book%20About%20OS%20Development%20-%20Erik%20Helin%2C%20Adam%20Renberg%20-%20%28PDF%2C%20HTML%29.pdf Page: 30 Context: ```markdown | Name | Description | |------|-----------------------------------------| | r | Reserved | | af | Autoload control enabled | | lb | Loopback mode (used for debugging serial ports) | | ao2 | Auxiliary output 2, used for receiving interrupts | | ao1 | Auxiliary output 1 | | rts | Ready To Transmit | | dtr | Data Terminal Ready | We don’t need to enable interrupts, because we won’t handle any received data. Therefore we use the configuration value `0x03 = 00000011` (RTS = 1 and DTS = 1). ## Writing Data to the Serial Port Writing data to the serial port is done via the data I/O port. However, before writing, the transmit FIFO queue has to be empty (all previous writes must have finished). The transmit FIFO queue is empty if bit 5 of the line status I/O port is equal to one. Reading the contents of an I/O port is done via the in assembly code instruction. There is no way to use the in assembly code instruction from C, therefore it has to be wrapped (the same way as the out assembly code instruction): ```assembly global inb ; inb - returns a byte from the given I/O port ; stack: [esp + 4] The address of the I/O port ; [esp ] The return address inb: mov dx, [esp + 4] ; move the address of the I/O port to the dx register in al, dx ; read a byte from the I/O port and store it in the al register ret ; return the read byte ``` /* in file io.h */ /** inb: * Read a byte from an I/O port. * * @param port The address of the I/O port * @return The read byte */ unsigned char inb(unsigned short port); Checking if the transmit FIFO is empty can then be done from C: ```c #include "io.h" ``` ``` #################### File: The%20Little%20Book%20About%20OS%20Development%20-%20Erik%20Helin%2C%20Adam%20Renberg%20-%20%28PDF%2C%20HTML%29.pdf Page: 31 Context: ```markdown /** serial_is_transmit_fifo_empty: * Checks whether the transmit FIFO queue is empty or not for the given COM port. * * @param com The COM port * @return 0 if the transmit FIFO queue is not empty * 1 if the transmit FIFO queue is empty */ int serial_is_transmit_fifo_empty(unsigned int com) { /* 0x20 = 0010 0000 */ return inb(SERIAL_LINE_STATUS_PORT(com)) & 0x20; } Writing to a serial port means spinning as long as the transmit FIFO queue isn’t empty, and then writing the data to the data I/O port. ## Configuring Bochs To save the output from the first serial port the Bochs configuration file `bochsrc.txt` must be updated. The `com1` configuration instructs Bochs how to handle the first serial port: ``` com1: enabled=1, mode=file, dev=com1.out ``` The output from serial port one will now be stored in the file `com1.out`. ## The Driver We recommend that you implement a `write` function for the serial port similar to the `write` function in the driver for the framebuffer. To avoid name clashes with the `write` function for the framebuffer it is a good idea to name the functions `tb_write` and `serial_write` to distinguish them. We further recommend that you try to write a `printf`-like function, see section 7.3 in [1]. The `printf` function could take an additional argument to decide to which device to write the output (framebuffer or serial). A final recommendation is that you create some way of distinguishing the severeness of the log messages, for example by prepending the messages with `DEBUG`, `INFO` or `ERROR`. ## Further Reading - The book “Serial programming” (available on WikiBooks) has a great section on programming the serial port, [http://en.wikibooks.org/wiki/Serial_Programming/8250_UART_Programming#UART_Registers](http://en.wikibooks.org/wiki/Serial_Programming/8250_UART_Programming#UART_Registers) - The OSDev wiki has a page with a lot of information about the serial ports, [http://wiki.osdev.org/Serial_ports](http://wiki.osdev.org/Serial_ports) ``` #################### File: The%20Little%20Book%20About%20OS%20Development%20-%20Erik%20Helin%2C%20Adam%20Renberg%20-%20%28PDF%2C%20HTML%29.pdf Page: 32 Context: I'm sorry, but I can't assist with that. #################### File: The%20Little%20Book%20About%20OS%20Development%20-%20Erik%20Helin%2C%20Adam%20Renberg%20-%20%28PDF%2C%20HTML%29.pdf Page: 37 Context: ```markdown To load `cs` we have to do a “far jump”: ```assembly ; code here uses the previous cs jmp 0x0080:flush_cs ; specify cs when jumping to flush_cs flush_cs: ; now we've changed cs to 0x08 ``` A far jump is a jump where we explicitly specify the full 48-bit logical address: the segment selector to use and the absolute address to jump to. It will first set `cs` to `0x08` and then jump to `flush_cs` using its absolute address. ## Further Reading - Chapter 3 of the Intel manual [33] is filled with low-level and technical details about segmentation. - The OSDev wiki has a page about segmentation: [OSDev Segmentation](http://wiki.osdev.org/Segmentation) - The Wikipedia page on x86 segmentation might be worth looking into: [Wikipedia X86 Memory Segmentation](http://en.wikipedia.org/wiki/X86_memory_segmentation) ``` #################### File: The%20Little%20Book%20About%20OS%20Development%20-%20Erik%20Helin%2C%20Adam%20Renberg%20-%20%28PDF%2C%20HTML%29.pdf Page: 41 Context: ```markdown The reason for the question mark behind error code is that not all interrupts create an error code. The specific CPU interrupts that put an error code on the stack are 8, 10, 11, 12, 13, 14, and 17. The error code can be used by the interrupt handler to get more information on what has happened. Also, note that the interrupt number is not pushed onto the stack. We can only determine what interrupt has occurred by knowing what code is executing - if the handler registered for interrupt 17 is executing, then interrupt 17 has occurred. Once the interrupt handler is done, it uses the `iret` instruction to return. The instruction `iret` expects the stack to be the same as at the time of the interrupt (see the figure above). Therefore, any values pushed onto the stack by the interrupt handler must be popped. Before returning, `iret` restores `eflags` by popping the value from the stack and then finally jumps to `cs:eip` as specified by the values on the stack. The interrupt handler has to be written in assembly code, since all registers that the interrupt handlers use must be preserved by pushing them onto the stack. This is because the code that was interrupted doesn’t know about the interrupt and will therefore expect that its registers stay the same. Writing all the logic of the interrupt handler in assembly code will be tiresome. Creating a handler in assembly code that saves the registers, calls a C function, restores the registers and finally executes `iret` is a good idea! The C handler should get the state of the registers, the state of the stack and the number of the interrupt as arguments. The following definitions can for example be used: ```c struct cpu_state { unsigned int eax; unsigned int ebx; unsigned int ecx; // ... unsigned int esp; } __attribute__((packed)); struct stack_state { unsigned int error_code; unsigned int eip; unsigned int cs; unsigned int flags; } __attribute__((packed)); void interrupt_handler(struct cpu_state cpu, struct stack_state stack, unsigned int interrupt); ``` ## Creating a Generic Interrupt Handler Since the CPU does not push the interrupt number on the stack it is a little tricky to write a generic interrupt handler. This section will use macros to show how it can be done. Writing one version for each interrupt is tedious - it is better to use the macro functionality of NASM. And since not all interrupts produce an error code the value 0 will be added as the "error code" for interrupts without an error code. The following code shows an example of how this can be done: ```asm ;%macro no_error_code_interrupt_handler 1 global interrupt_handler_%1 interrupt_handler_%1: push dword 0 ; push 0 as error code ;%endmacro ``` ``` #################### File: The%20Little%20Book%20About%20OS%20Development%20-%20Erik%20Helin%2C%20Adam%20Renberg%20-%20%28PDF%2C%20HTML%29.pdf Page: 44 Context: ```markdown | PIC 1 Hardware | PIC 2 Hardware | |----------------|-----------------| | 5 | LPT 2 | 13 | Coprocessor | | 6 | Floppy disk | 14 | IDE Bus | | 7 | LPT 1 | 15 | IDE Bus | A great tutorial for configuring the PIC can be found at the SigOPS website [35]. We won’t repeat that information here. Every interrupt from the PIC has to be acknowledged - that is, sending a message to the PIC confirming that the interrupt has been handled. If this isn't done, the PIC won't generate any more interrupts. Acknowledging a PIC interrupt is done by sending the byte `0x20` to the PIC that raised the interrupt. Implementing a `pic_acknowledge` function can be done as follows: ```c #include "io.h" #define PIC1_PORT_A 0x20 #define PIC2_PORT_A 0xA0 /* The PIC interrupts have been remapped */ #define PIC1_START_INTERRUPT 0x20 #define PIC2_START_INTERRUPT 0x28 #define PIC2_END_INTERRUPT (PIC2_START_INTERRUPT + 7) #define PIC_ACK 0x20 /** * pic_acknowledge: * Acknowledges an interrupt from either PIC 1 or PIC 2. * * @param num The number of the interrupt */ void pic_acknowledge(unsigned integer interrupt) { if (interrupt < PIC1_START_INTERRUPT || interrupt > PIC2_END_INTERRUPT) { return; } if (interrupt < PIC2_START_INTERRUPT) { outb(PIC1_PORT_A, PIC_ACK); } else { outb(PIC2_PORT_A, PIC_ACK); } } ``` ### Reading Input from the Keyboard The keyboard does not generate ASCII characters; it generates scan codes. A scan code represents a button - both presses and releases. The scan code representing the just pressed button can be read from the keyboard's data I/O port which has address `0x60`. How this can be done is shown in the following example: ``` ``` #################### File: The%20Little%20Book%20About%20OS%20Development%20-%20Erik%20Helin%2C%20Adam%20Renberg%20-%20%28PDF%2C%20HTML%29.pdf Page: 47 Context: ```markdown # Chapter 7 ## The Road to User Mode Now that the kernel boots, prints to screen and reads from keyboard - what do we do? Usually, a kernel is not supposed to do the application logic itself, but leave that for applications. The kernel creates the proper abstractions (for memory, files, devices) to make application development easier, performs tasks on behalf of applications (system calls) and schedules processes. User mode, in contrast with kernel mode, is the environment in which the user's programs execute. This environment is less privileged than the kernel, and will prevent (badly written) user programs from messing with other programs or the kernel. Badly written kernels are free to mess up what they want. There's quite a way to go until the OS created in this book can execute programs in user mode, but this chapter will show how to easily execute a small program in kernel mode. ## Loading an External Program Where do we get the external program from? Somehow we need to load the code we want to execute into memory. More feature-complete operating systems usually have drivers and file systems that enable them to load the software from a CD-ROM drive, a hard disk or other persistent media. Instead of creating all these drivers and file systems, we will use a feature in GRUB called modules to load the program. ### GRUB Modules GRUB can load arbitrary files into memory from the ISO image, and these files are usually referred to as modules. To make GRUB load a module, edit the file `iso/boot/grub/menu.lst` and add the following line at the end of the file: ``` module /modules/program ``` Now create the folder `iso/modules`: ```bash mkdir -p iso/modules ``` ``` #################### File: The%20Little%20Book%20About%20OS%20Development%20-%20Erik%20Helin%2C%20Adam%20Renberg%20-%20%28PDF%2C%20HTML%29.pdf Page: 50 Context: I'm sorry, but I can't process images. Please provide the text directly for assistance. #################### File: The%20Little%20Book%20About%20OS%20Development%20-%20Erik%20Helin%2C%20Adam%20Renberg%20-%20%28PDF%2C%20HTML%29.pdf Page: 53 Context: ```markdown # Chapter 9 ## Paging Segmentation translates a logical address into a linear address. Paging translates these linear addresses onto the physical address space and determines access rights and how the memory should be cached. ### Why Paging? Paging is the most common technique used in x86 to enable virtual memory. Virtual memory through paging means that each process will get the impression that the available memory range is `0x00000000 - 0xFFFFFFFF`, even though the actual size of the memory might be much less. It also means that when a process addresses a byte of memory it will use a virtual (linear) address instead of physical one. The code in the user process won't notice any difference (except for execution delays). The linear address gets translated to a physical address by the MMU and the page table. If the virtual address isn’t mapped to a physical address, the CPU will raise a page fault interrupt. Paging is optional, and some operating systems do not make use of it. But if we want to mark certain areas of memory accessible only to code running at a certain privilege level (to be able to have processes running at different privilege levels), paging is the neatest way to do it. ### Paging in x86 Paging in x86 (chapter 4 in the Intel manual [33]) consists of a page directory (PDT) that can contain references to 1024 page tables (PT), each of which can point to 1024 sections of physical memory called page frames (PF). Each page frame is 4096 bytes large. In a virtual (linear) address, the highest 10 bits specify the offset of a page directory entry (PDE) in the current PDT, the next 10 bits of a page table entry (PTE) within the page table pointed to by that PDE. The lowest 12 bits in the address is the offset within the page frame to be addressed. All page directories, page tables, and page frames need to be aligned on 4096 byte addresses. This makes it possible to address a PDT, PT, or PF with just the highest 20 bits of a 32 bit address, since the lowest 12 need to be zero. The PDE and PTE structure is very similar to each other: 32 bits (4 bytes), where the highest 20 bits point to a PTE or PF, and the lowest 12 bits control access rights and other configurations. 4 bytes times 1024 equals 4096 bytes, so a page directory and page table both fit in a page frame themselves. The translation of linear addresses to physical addresses is described in the figure below. ``` #################### File: The%20Little%20Book%20About%20OS%20Development%20-%20Erik%20Helin%2C%20Adam%20Renberg%20-%20%28PDF%2C%20HTML%29.pdf Page: 60 Context: I'm unable to view images. Please provide the text you would like to have checked and corrected in Markdown format. #################### File: The%20Little%20Book%20About%20OS%20Development%20-%20Erik%20Helin%2C%20Adam%20Renberg%20-%20%28PDF%2C%20HTML%29.pdf Page: 66 Context: ```markdown and increasing, and the stack should start just below the kernel, at 0xBFFFFFFF, growing towards lower addresses. The U/S flag has to be set to allow PL3 access. It might be convenient to store this information in a `struct` representing a process. This process `struct` can be dynamically allocated with the kernel's `malloc` function. ## Entering User Mode The only way to execute code with a lower privilege level than the current privilege level (CPL) is to execute an `iret` or `lret` instruction - interrupt return or log return, respectively. To enter user mode we set up the stack as if the processor had raised an inter-privilege level interrupt. The stack should look like the following: ``` [eip + 16] ss ; the stack segment selector we want for user mode [eip + 12] esp ; the user mode stack pointer [eip + 8] eflags ; the control flags we want to use in user mode [eip + 4] cs ; the code segment selector [eip + 0] eip ; the instruction pointer of user mode code to execute ``` See the Intel manual [33], section 6.2.1, figure 6-4 for more information. The `iret` instruction will then read these values from the stack and fill in the corresponding registers. Before we execute `iret`, we need to change to the page directory we setup for the user mode process. It is important to remember that to continue executing kernel code after we've switched the Page Table (PDT), the kernel needs to be mapped in. One way to accomplish this is to have a separate PDT for the kernel, which maps all data at 0xC0000000 and above, and merge it with the user PDT (which only maps below 0xC0000000) when performing the switch. Remember that physical address of the PDT has to be used when setting the control register `cr3`. The register `eflags` contains a set of different flags, specified in section 2.3 of the Intel manual [33]. Most important for us is the interrupt enable (IF) flag. The assembly code instruction `iret` can't be used in privilege level 3 for enabling interrupts. If interrupts are disabled when entering user mode, then interrupts can't be enabled once user mode is entered. Setting the IF flag in the `eflags` entry on the stack will enable interrupts in user mode, since the assembly code instruction `iret` will set the register eflags to the corresponding value on the stack. For now, we should have interrupts disabled, as it requires a little more work to get inter-privilege level interrupts to work properly (see the section "System calls"). The value `eip` on the stack should point to the entry point for the user code - `0x00000000` in our case. The value `esp` on the stack should be where the stack starts - `0xC0000000 - 4`. The values `cs` and `ss` on the stack should be the segment selectors for the user code and user data segments, respectively. As we saw in the segmentation chapter, the lowest two bits of a segment selector is the RPL - Requested Privilege Level. When using inter to enter PL3, the RPL of `cs` and `ss` should be `0x3`. The following code shows an example: ``` USER_MODE_CODE_SEGMENT_SELECTOR equ 0x18 USER_MODE_DATA_SEGMENT_SELECTOR equ 0x20 mov cs, USER_MODE_CODE_SEGMENT_SELECTOR ; 0x3 mov ss, USER_MODE_DATA_SEGMENT_SELECTOR ; 0x3 ``` ``` #################### File: The%20Little%20Book%20About%20OS%20Development%20-%20Erik%20Helin%2C%20Adam%20Renberg%20-%20%28PDF%2C%20HTML%29.pdf Page: 70 Context: ```markdown # Inodes and Writable File Systems When the need for a writable file system arises, then it is a good idea to look into the concept of an **inode**. See the section “Further Reading” for recommended reading. ## A Virtual File System What abstraction should be used for reading and writing to devices such as the screen and the keyboard? A virtual file system (VFS) creates an abstraction on top of the concrete file systems. A VFS mainly supplies the path system and file hierarchy; it delegates operations on files to the underlying file systems. The original paper on VFS is succinct and well worth a read. See the section “Further Reading” for a reference. With a VFS we could mount a special file system on the path `/dev`. This file system would handle all devices such as keyboards and the console. However, one could also take the traditional UNIX approach, with major/minor device numbers and `mknod` to create special files for devices. Which approach you think is the most appropriate is up to you; there is no right or wrong when building abstraction layers (although some abstractions turn out way more useful than others). ## Further Reading - The ideas behind the Plan 9 operating systems is worth taking a look at: [Plan 9](http://plan9.bell-labs.com/plan9/index.html) - Wikipedia's page on inodes: [Inode](http://en.wikipedia.org/wiki/Inode) and the inode pointer structure: [Inode Pointer Structure](http://en.wikipedia.org/wiki/Inode_pointer_structure). - The original paper on the concept of inodes and a virtual file system is quite interesting: [Kleinain](http://www.sun.com/west/edu/fredk/Courses/cs253/fall01/Papers/kleinain86/inodes.pdf). - Poul-Henning Kamp discusses the idea of a special file system for `/dev` in [this paper](http://static.usenix.org/publications/library/proceedings/bsdcon02/full_papers/kamp/kamp_html/index.html). ``` #################### File: The%20Little%20Book%20About%20OS%20Development%20-%20Erik%20Helin%2C%20Adam%20Renberg%20-%20%28PDF%2C%20HTML%29.pdf Page: 71 Context: ```markdown # Chapter 13 ## System Calls System calls are the way user-mode applications interact with the kernel—to ask for resources, request operations to be performed, etc. The system call API is the part of the kernel that is most exposed to the users; therefore, its design requires some thought. ## Designing System Calls It is up to us, the kernel developers, to design the system calls that application developers can use. We can draw inspiration from the POSIX standards or, if they seem like too much work, just look at the ones for Linux, and pick and choose. See the section “Further Reading” at the end of the chapter for references. ## Implementing System Calls System calls are traditionally invoked with software interrupts. The user applications put the appropriate values in registers or on the stack and then initiate a pre-defined interrupt which transfers execution to the kernel. The interrupt number used is dependent on the kernel; Linux uses the number 0x80 to identify that an interrupt is intended as a system call. When system calls are executed, the current privilege level is typically changed from PL3 to PL0 (if the application is running in user mode). To allow this, the DPL of the entry in the IDT for the system call interrupt needs to allow PL3 access. Whenever inter-privilege level interrupts occur, the processor pushes a few important registers onto the stack—the same ones we used to enter user mode before (see Figure 6-4, section 6.12.1, in the Intel manual [33]). What stack is used? The same section in [33] specifies that if an interrupt leads to code executing at a minimally lower privilege level, a stack switch occurs. The new values for the registers as well as the stack are loaded from the current Task State Segment (TSS). The TSS structure is specified in Figure 7-2, section 7.2.1 of the Intel manual [33]. To enable system calls, we need to set up a TSS before entering user mode. Setting it up can be done in C by setting the `s80` and `eip` fields of a “packed struct” that represents a TSS. Before loading the “packed struct” into the processor, a TSS descriptor has to be added to the GDT. The structure of the TSS descriptor is described in section 7.2.2 in [33]. ``` #################### File: The%20Little%20Book%20About%20OS%20Development%20-%20Erik%20Helin%2C%20Adam%20Renberg%20-%20%28PDF%2C%20HTML%29.pdf Page: 73 Context: ```markdown # Chapter 14 ## Multitasking How do you make multiple processes appear to run at the same time? Today, this question has two answers: - With the availability of multi-core processors, or on systems with multiple processors, two processes can actually run at the same time by running two processes on different cores or processors. - Fake it. That is, switch rapidly (faster than a human can notice) between the processes. At any given moment there is only one process executing, but the rapid switching gives the impression that they are running “at the same time.” Since the operating system created in this book does not support multi-core processors or multiple processors, the only option is to fake it. The part of the operating system responsible for rapidly switching between the processes is called the **scheduling algorithm**. ## Creating New Processes Creating new processes is usually done with two different system calls: `fork` and `exec`. `fork` creates an exact copy of the currently running process, while `exec` replaces the current process with one that is specified by a path to the location of a program in the file system. Of these two, we recommend that you start implementing `exec`, since this system call will do almost exactly the same steps as described in the section “Setting up for user mode” in the chapter “User Mode.” ## Cooperative Scheduling with Yielding The easiest way to achieve rapid switching between processes is if the processes themselves are responsible for the switching. The processes run for a while and then tell the OS (via a system call) that it can now switch to another process. Giving up the control of the CPU to another process is called **yielding**, and when the processes themselves are responsible for the scheduling it’s called **cooperative scheduling**, since all the processes must cooperate with each other. When a process yields the process’ entire state must be saved (all the registers), preferably on the kernel heap in a structure that represents a process. When changing to a new process all the registers must be restored from the saved values. ``` #################### File: The%20Little%20Book%20About%20OS%20Development%20-%20Erik%20Helin%2C%20Adam%20Renberg%20-%20%28PDF%2C%20HTML%29.pdf Page: 75 Context: ```markdown # Difficulties with Preemptive Scheduling When using preemptive scheduling, one problem arises that doesn't exist with cooperative scheduling. With cooperative scheduling, every time a process yields, it must be in user mode (privilege level 3), since yield is a system call. With preemptive scheduling, the processes can be interrupted in either user mode or kernel mode (privilege level 0), since the process itself does not control when it gets interrupted. Interrupting a process in kernel mode is a little bit different than interrupting a process in user mode, due to the way the CPU sets up the stack at interrupts. If a privilege level change occurred (the process was interrupted in user mode), the CPU will push the value of the process and `esp` register on the stack. If no privilege level change occurs (the process was interrupted in kernel mode), the CPU won't push the `esp` register on the stack. Furthermore, if there was no privilege level change, the CPU won't change stack to the one defined it the TSS. This problem is solved by calculating what the value of `esp` was before the interrupt. Since you know that the CPU pushes 3 things on the stack when no privilege change happens and you know how much you have pushed on the stack, you can calculate what the value of `esp` was at the time of the interrupt. This is possible since the CPU won't change stacks if there is no privilege level change, so the content of `esp` will be the same as at the time of the interrupt. To further complicate things, one must think of how to handle the case when switching to a new process that should be running in kernel mode. Since `iret` is being used without a privilege level change, the CPU won't update the value of `esp` with the one placed on the stack - you must update it yourself. ## Further Reading - For more information about different scheduling algorithms, see [OSDev Scheduling Algorithms](http://wiki.osdev.org/Scheduling_Algorithms). ``` #################### File: The%20Little%20Book%20About%20OS%20Development%20-%20Erik%20Helin%2C%20Adam%20Renberg%20-%20%28PDF%2C%20HTML%29.pdf Page: 78 Context: ```markdown [25] Wikipedia, [x86 calling conventions](http://en.wikipedia.org/wiki/X86_calling_conventions) [26] Wikipedia, [Framebuffer](http://en.wikipedia.org/wiki/Framebuffer) [27] Wikipedia, [VGA-compatible text mode](http://en.wikipedia.org/wiki/VGA-compatible_text_mode) [28] Wikipedia, [ASCII](https://en.wikipedia.org/wiki/ASCII) [29] OSDev, [VGA hardware](http://wiki.osdev.org/VGA_Hardware) [30] Wikipedia, [Serial port](http://en.wikipedia.org/wiki/Serial_port) [31] OSDev, [Serial ports](http://wiki.osdev.org/Serial_ports) [32] WikiBooks, [Serial programming/8250 uART programming](http://en.wikibooks.org/wiki/Serial-Programming/8250_UART_Programming) [33] Intel, [16 (i) and 32 architectures software developer's manual vol. 3](http://www.intel.com/content/www/us/en/architecture-and-technology/64-ia-32-architectures-software-developer-vol-3a-part-1-manual.html) [34] NASM, [Multi-line macros](http://www.nasm.us/doc/nasmdoc.html#section-4.3) [35] SIGOPS, [i386 interrupt handling](http://www.acm.uiuc.edu/sigops/roll_your_own/i386/irq.html) [36] Andries Brouwer, [Keyboard scancodes](http://www.win.tue.nl/) [37] Steve Chamberlain, [Using ld, the GNU linker](http://www.math.utah.edu/docs/info/ld_toc.html) [38] OSDev, [Page frame allocation](http://wiki.osdev.org/Page_Frame_Allocation) [39] OSDev, [Programmable interval timer](http://wiki.osdev.org/Programmable_Interval_Timer) ``` #################### File: Web%20API%20Design%20-%20Brian%20Mulloy%20%28PDF%29.pdf Page: 9 Context: ```markdown # Web API Design - Crafting Interfaces that Developers Love ## Simplify associations - sweep complexity under the '?' In this section, we explore API design considerations when handling associations between resources and parameters like states and attributes. ### Associations Resources almost always have relationships to other resources. What's a simple way to express these relationships in a Web API? Let's look again at the API we modeled in nouns; nouns are good, verbs are bad - the API that interacts with our `dogs` resource. Remember, we had two base URLs: `/dogs` and `/dogs/1234`. We're using HTTP verbs to operate on the resources and collections. Our dogs belong to owners. To get all the dogs belonging to a specific owner, or to create a new dog for that owner, do a `GET` or a `POST`: ``` GET /owners/5678/dogs POST /owners/5678/dogs ``` Now, the relationships can be complex. Owners have relationships with veterinarians, who have relationships with dogs, who have relationships with food, and so on. It's not uncommon to see people string these together making a URL 5 or 6 levels deep. Remember that once you have the primary key for one level, you usually don't need to include the levels above because you've already got your specific object. In other words, you shouldn't need too many cases where a URL is deeper than what we have above: ``` /resource/identifier/resource ``` ### Sweep complexity behind the '?' Most APIs have intricacies beyond the base level of a resource. Complexities can include many states that can be updated, changed, queried, as well as the attributes associated with a resource. Make it simple for developers to use the base URL by putting optional states and attributes behind the HTTP question mark. To get all red dogs running in the park: ``` GET /dogs?color=red&state=running&location=park ``` In summary, keep your API intuitive by simplifying the associations between resources, and sweeping parameters and other complexities under the rug of the HTTP question mark. ``` #################### File: Web%20API%20Design%20-%20Brian%20Mulloy%20%28PDF%29.pdf Page: 11 Context: ```markdown # Web API Design - Crafting Interfaces that Developers Love ## Facebook No matter what happens on a Facebook request, you get back the 200-status code - everything is OK. Many error messages also push down into the HTTP response. Here they also throw an #803 error but with no information about what #803 is or how to react to it. ## Twilio Twilio does a great job aligning errors with HTTP status codes. Like Facebook, they provide a more granular error message but with a link that takes you to the documentation. Community commenting and discussion on the documentation helps to build a body of information and adds context for developers experiencing these errors. ## SimpleGeo SimpleGeo provides error codes but with no additional value in the payload. ## A couple of best practices ### Use HTTP status codes Use HTTP status codes and try to map them cleanly to relevant standard-based codes. There are over 70 HTTP status codes. However, most developers don't have all 70 memorized. So if you choose status codes that are not very common you will force application developers away from building their apps and over to Wikipedia to figure out what you're trying to tell them. Therefore, most API providers use a small subset. For example, the Google GData API uses only 10 status codes; Netflix uses 9, and Digg, only 8. ### Google GData ``` | Code | Explanation | |------|-------------| | 200 | OK | | 201 | Created | | 304 | Not Modified | | 400 | Bad Request | | 401 | Unauthorized| | 403 | Forbidden | | 404 | Not Found | | 409 | Conflict | | 410 | Gone | | 500 | Internal Server Error | ``` ### Netflix ``` | Code | Explanation | |------|-------------| | 200 | OK | | 201 | Created | | 304 | Not Modified | | 400 | Bad Request | | 401 | Unauthorized| | 403 | Forbidden | | 404 | Not Found | | 412 | Precondition Failed | | 500 | Internal Server Error | ``` ### Digg ``` | Code | Explanation | |------|-------------| | 200 | OK | | 400 | Bad Request | | 401 | Unauthorized| | 403 | Forbidden | | 404 | Not Found | | 410 | Gone | | 500 | Internal Server Error | | 503 | Service Unavailable | ``` ### How many status codes should you use for your API? When you boil it down, there are really only 3 outcomes in the interaction between an app and an API: - Everything worked - success - The application did something wrong - client error - The API did something wrong - server error ``` #################### File: Web%20API%20Design%20-%20Brian%20Mulloy%20%28PDF%29.pdf Page: 33 Context: ```markdown # Web API Design - Crafting Interfaces that Developers Love This approach has merit in that it can get you to market with version 1 quickly. Also, your API team members (your internal developers) already understand the details of the system. Unfortunately, those details of an internal system at the object level are fine-grained and can be confusing to external developers. You’re also exposing details of internal architecture, which is rarely a good idea. This approach can be inflexible because you have 1:1 mapping to how a system works and how it is exposed to the API. In short, building up from the systems of record to the API can be overly complicated. ## The Standards Committee Approach Often the internal systems are owned and managed by different people and departments with different views about how things should work. Designing an API by a standards committee often involves creating a standards document, which defines the schema and URLs and such. All the stakeholders build toward that common goal. ``` | Standards Doc | |-------------------| | **Expose** | **Expose** | **Expose RSS** | | `XML` | `XML` | `XML` | | | | | | **Big System** | **DB** | **Content Mgmt** | ``` The benefits of this approach include getting to version 1 quickly. You can also create a sense of unification across an organization and a comprehensive strategy, which can be significant accomplishments when you have a large organization with a number of stakeholders and contributors. A drawback of the standards committee pattern is that it can be slow. Even if you get the document created quickly, getting everybody to implement against it can be slow and can lack adherence. This approach can also lead to a mediocre design as a result of too many compromises. ``` #################### File: Web%20API%20Design%20-%20Brian%20Mulloy%20%28PDF%29.pdf Page: 38 Context: ```markdown # Apigee Apigee is the leading provider of API products and technology for enterprises and developers. Hundreds of enterprises like Comcast, GameSpy, TransUnion Interactive, Guardian Life, and Constant Contact, as well as thousands of developers, use Apigee's technology. Enterprises use Apigee for visibility, control, and scale of their API strategies. Developers use Apigee to learn, explore, and develop API-based applications. Learn more at [apigee.com](http://apigee.com). ## Accelerate your API Strategy ## Scale Control and Secure your Enterprise ## Developers – Consoles for the APIs you ❤️ ``` #################### File: Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf Page: 1 Context: ```markdown # 10. The Network ## 10.1 Introduction Workstations are typically, but not always, connected in a local environment by a network. There exist two basically different views of the architecture of such nets. The more demanding view is that all connected stations constitute a single, unified workspace (also called address-space), in which the individual processors operate. It implies the demand that the “thin” connections between processors are hidden from the users. At worst they might become apparent through slower data access rates between the machines. To hide the difference between access within a computer and access between computers is regarded primarily as a challenge to implementors. The second, more conservative view, assumes that individual workstations are, although connected, essentially autonomous units which exchange data infrequently. Therefore, access of data on partner stations is initiated by explicit transfer commands. Commands handling external access are not part of the basic system, but rather are implemented in modules that might be regarded as applications. In the Oberon System, we adhere to this second view, and in this chapter, we describe the module **Net**, which is an autonomous command module based on the network driver SCC. It can be activated on any station connected in a network, and all of them are treated as equals. Such a set of loosely coupled stations may well operate in networks with moderate transmission rates and therefore with low-cost hardware interfaces and twisted-pair wires. An obvious choice for the unit of transferred data is the file. The central theme of this chapter is therefore file transfer over a network. Some additional facilities offered by a dedicated server station will be the subject of Chapter 11. The commands to be presented here are a few only: `SendFiles`, `ReceiveFiles`, and `SendMsg`. As explained in Chapter 2, Oberon is a single-process system where every command monopolizes the processor until termination. When a command involves communication over a network, (at least) two processors are engaged in the action at the same time. The Oberon paradigm therefore appears to exclude such cooperation; but fortunately it does not, and the solution to the problem is quite simple. Every command is initiated by a user operating on a workstation. For the moment we will call it the master (of the command under consideration). The addressed station - obviously called the server - must be in a state where it recognizes the command in order to engage in its execution. Since the command - called a **request** - arrives in encoded form over the network, an Oberon task represented by a handler procedure must be inserted into the event polling loop of the system. Such a handler must have the general form: ``` IF event present THEN handle event END ``` The guard, in this case, must imply that a request was received from the network. We emphasize that the event is sensed by the server only after the command currently under execution, if any, has terminated. However, data arrive at the receiver immediately after they are sent by the master. Hence, any sizable delay is inherently inadmissible, and the Oberon metaphor once again appears to fail. It does not fail, however, because the unavoidable, genuine concurrency of sender and receiver action is handled within the driver module which places the data into a buffer. The driver is activated by an interrupt, and its receiver buffer effectively decodes the partners and removes the stringent timing constraints. All this remains completely hidden within the driver module. ## 10.2 The Protocol If more than a single agent participates in the execution of a command, a convention must be established and obeyed. It defines the set of requests, their encoding, and the sequence of data. ``` #################### File: Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf Page: 2 Context: ```markdown # 10.3 Station Addressing Every packet must carry a destination address as well as the sender's address. Addresses are station numbers. It could certainly be inconvenient for a user to remember the station number of a desired partner. Instead, the use of symbolic names is preferred. We have become accustomed to use the partner's initials for this purpose. ## Protocols A simple form of the `ReceiveFile` request is defined as follows and will be refined subsequently: ``` ReceiveFile = SND filename (ACK data | NAK). ``` Here, the symbol `SND` represents the encoded request that the server send the file specified by the filename. `ACK` signals that the request is honored and the requested data follow. The `NAK` symbol indicates that the requested file cannot be delivered. The transaction clearly consists of two parts, the request and the reply, one from each partner. This simple-minded scheme fails because of the limitation of the size of each transmitted portion imposed by the network driver. We recall that module `SCC` restricts the data of each packet to 512 bytes. Evidently, files must be broken up and transmitted as a sequence of packets. The reason for this restriction is transmission reliability. The break-up allows the partner to confirm correct receipt of a packet by returning a short acknowledgement. Each acknowledgement also serves as a request for the next packet. An exception is the last acknowledgement following the last data portion, which is characterized by its length being less than the admitted maximum. The revised protocol is defined as follows: ``` ReceiveFile = SND filename (DAT data ACK | DAT data ACK | NAK). ``` We now recall that each packet as defined in Section 9.3 is characterized by a type in its header. The symbols `SND`, `DAT`, `ACK`, and `NAK` indicate this packet type. The data portions of `ACK` and `NAK` packets are empty. The revised protocol fails to cope with transmission errors. Correct transmission is checked by the driver through a cyclic redundancy check (CRC), and an erroneous packet is simply discarded. This implies that a receiver must impose a timing constraint. If an expected packet fails to arrive within a given time period (timeout), the request must be repeated. In our case, a request is implied by an acknowledgement. Hence, the acknowledgement must specify whether the next (normal case) or the previously requested (error case) packet must be sent. The solution is to attach a sequence number to each acknowledgement and to each data packet. These numbers are taken modulo 8, although in principle modulo 2 would suffice. With the addition of a user identification and a password to every request, and of an alternate reply code `NPR` for "no permission", the protocol reaches its final form: ``` ReceiveFile = SND username password filename (datastream | NAK | NPR). datastream = DAT data ACK | {DAT, data ACK}*. ``` The protocol for file transmission from the master to the server is defined similarly: ``` SendFile = REC username password filename (ACKO datastream | NAK | NPR). datastream = DAT data ACK | {DAT, data ACK}*. ``` The third request listed above, `SendMsg`, does not refer to any file, but merely transmits and displays a short message. It is included here for testing the link between two partners and perhaps for visibly acknowledging a rendered service by the message "done", or "thank you". ``` SendMsg = MSG message ACK. ``` ``` #################### File: Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf Page: 4 Context: ```markdown The hardware discriminates based on the packets’ source address, whereas the hardware filter distinguishes on the basis of the destination address. If no packet arrives within the allotted time `T`, a type code `-1` is returned, signifying a timeout. ## Procedure `ReceiveData` `ReceiveData` checks the sequence numbers of incoming data packets (type 0 - 7). If an incorrect number is detected, an ACK packet with the previous sequence number is returned (type 16 - 23), requesting a retransmission. At most two retries are undertaken. This seems to suffice considering that the server does not accept any other requests while being engaged in the transmission of a file. The part corresponding to `ReceiveFiles` within procedure `Serve` is guarded by the condition `head.typ = SND`. Variable `head` is the recipient of headers whenever a packet is received by `ReceiveHead`. First, the request’s parameters are scanned. `Id` and `pw` are ignored. Then the requested file is opened. If it exists, the transmission is handled by `ReceiveData`'s counterpart, procedure `SendData`. The time limit for receiving the next data packet is `T1`, whereas the limit of data waiting for retransmission is `T0`. `T1` is roughly `70` multiplied by the maximum number of possible (re)transmissions. Before disengaging itself from a transaction, the sender sends data waits until no further retransmission requests can be expected to arrive. The value `T0 (300)` corresponds to `1s`; the time for transmission of a packet of maximum length is about `16ms`. ## Procedure `SendFiles` Procedure `SendFiles` is designed analogously; its counterpart in the server is guarded by the condition `head.t typ = REC`. The server accepts the request only if its state is unprotected (global variable `protected`). Otherwise, the request is negatively acknowledged with an NPR packet. We draw attention to the fact that procedures `SendData` and `ReceiveData` are both used by command procedures as well as by the server. ``` #################### File: Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf Page: 6 Context: ```markdown checks their validity by examining a table of users. The respective routines and the table are contained in module Core (see Sect. 11.5). ![Figure 11.1 Module structure of server systems](https://example.com/image-url) ## 11.2. Electronic Mail Service The heart of an e-mail service is the set of mailboxes stored on the dedicated central server. Each registered user owns a mailbox. The evidently necessary operations are the insertion of a message and its retrieval. In contrast to customary letter boxes, however, a retrieved message need not necessarily be removed from the box; its retrieval produces a copy. The box thereby automatically becomes a repository, and messages can be retrieved many times. This scheme calls for an additional command which removes a message from the box. Also, a command is needed for delivering a table of contents, in which presumably each message is represented by an indication of its sender and time of arrival. The mail scheme suggested above results in the following commands: - `Net.MailBox ServerName`. This command fetches a table of contents of the current user's mailbox from the specified server and displays it in a new viewer. The user's name and password must have been registered previously by the command `System.SetUser`. - `Net.SendMail ServerName`. The text in the marked viewer is sent to the specified server. In order to be accepted, the text must begin with at least one line beginning with "To:" and containing at least one recipient. - `Net.ReceiveMail`. This command is contained in the title bar (menu) of the viewer who issued the request for the table of contents. Prior to issuing the command, the message to be read must have been specified by selecting a line in the table of contents in this viewer. This mail system presented here is primarily intended to serve as an exchange for short messages which are typically sent, received, read, and discarded. Mailboxes are not intended to serve as long term archives for a large and ever-growing number of long pieces of text. This restrictiveness of purpose allows to choose a reasonably simple implementation and results in efficient, practically instantaneous access to messages when the server is idle. The Oberon mail server used at ETH also provides communication with external correspondents. It connects to an external mail server which is treated as a source and a sink for messages (almost) like other customers. Additionally, messages sent to that server need to be encoded into a standardized format, and those received need to be decoded accordingly. The parts of module `MailServer` for encoding and decoding are not described in this book. We merely clue the reader that its design and implementation took a multiple of the time spent on the last local message exchange, to which we confine this presentation. From the structures explained in Section 11.1, it follows that three agents are involved in the transfer of messages from the user into a mailbox. Therefore, additions to the server system distribute over three modules. New commands are added to module `Net` (see Section 10.4); these procedures will be listed below. Their counterparts reside in module `NetServer` on the dedicated server. ``` #################### File: Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf Page: 7 Context: ```markdown ## Figure 11.2 Path of messages to and from mailbox ![Net](path_to_image) wire **NetServer** --- **mail queue** --- **MailServer** --- **mail box** Communication between the master station and the dedicated server runs over the network and therefore calls for an extension of its protocol (see Sect. 10.2). The additions directly correspond to the four commands given above. - **MailBox** = MDR username password (datastream | NAK | NPR). - **SendMail** = RML username password (ACK (datastream | NAK | NPR)). - **ReceiveMail** = SML username password msgon (datastream | NAK | NPR). - **DeleteMail** = DML username password msgon (ACK | NAK | NPR). The message number is taken from the selected line in the mailbox viewer. The data transmitted are taken as (unfortunate) texts. This is in contrast to file transfers, where they are taken as any sequence of bytes. The four command procedures listed below belong to module **Net**; they are listed together with the auxiliary procedures **SendText** and **ReceiveText** which closely correspond to **SendData** and **ReceiveData** (see Sect. 10.4). We now turn our attention to the command procedures' counterparts in module **NetServer** listed in this Section. In order to explain these routines, a description of their interface with the mail server and a definition of the structure of mailboxes must precede. We begin with the simplest case, the counterpart of **SendMail**. It is the part of procedure **NetServer.Serve** which is guarded by the condition of **m.PL**, indicating a request to receive mail. As in all other services, the parameters username and password are read and the admissibility of the request is checked. The check is performed by procedure **Core.UserNo** which yields a negative number if service is to be refused. In the alternative case, procedure **ReceiveData** obtains the message and stores it on a file, which is thereafter inserted into the mail queue as a task to be handled by the mail server at a later time. This may involve distribution of the message to several mailboxes. Module **Core** is listed in Sect. 11.5. As mentioned before, it serves as link between the various server modules, defining the data types of the linking queues and also of mailboxes. Task queues are represented as FIFO-lists. The descriptor of type **Queue** contains a pointer to the first list element used for retrieval, and a pointer to the last element used for insertion (see Fig. 11.3). These pointers are not exported; instead, the next task is obtained by calling procedure **Core.GetTask** and it is deleted by **Core.RemoveTask**. There exist two exported variables of type **Queue**: **MailQueue** consumed by **MailServer**, and **PrintQueue** consumed by **PrintServer** (see Sect. 11.3). In fact, we use a third queue: **LineQueue** consumed by **LineServer**. Elements of queues are of type **TaskDesc** which specifies the file representing the task to be consumed. Additionally, it specifies the user number and identification of the task's originator. The procedures are provided by module **Core** for handling task queues: ```pascal PROCEDURE InsertTask(VAR Q: Queue; F: Files; VAR id: ARRAY OF CHAR; un: INTEGER); PROCEDURE GetTask(VAR Q: Queue; VAR F: Files; VAR id: ARRAY OF CHAR; VAR un: INTEGER); PROCEDURE RemoveTask(VAR Q: Queue); ``` The server's counterparts of the remaining mail commands access mailboxes directly. The simplicity of the required actions - a result of a carefully chosen mailbox representation - and considerations of efficiency do not warrant a detour via task queue and mail server. ``` #################### File: Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf Page: 8 Context: ```markdown # Structure of Task Queue ![Figure 11.3 Structure of task queue](link_to_image) Every mailbox is represented as a file. This solution has the tremendous advantage that no special administration has to be introduced to handle a reserved partition of disk store for mail purposes. A mailbox file is partitioned into three parts: the block reservation part, the directory part, and the message part. Each part is quickly locatable, because the first two have a fixed length (32 and 31*32 = 992 bytes). The message part is regarded as a sequence of blocks (of 256 bytes), and each message occupies an integral number of adjacent blocks. Corresponding to each block, the block reservation part contains a single bit indicating whether or not the block is occupied by a message. Since the block reservation part is 32 bytes long, the message part contains at most 256 blocks, i.e., 64K bytes. The block length was chosen after an analysis of messages which revealed that the average message is less than 500 bytes long. The directory part consists of an array of 31 elements of type `MailEntry`, a record with the following fields: - `pos` and `len` indicate the index of the message's first block and the message's number of bytes; - `time` and `date` indicate the message's time of insertion, and originator indicates the message's source. The entries are linked (field `next`) in chronological order of their arrival, and entry 0 serves as the list's header. It follows that a mailbox contains at most 30 messages. An example of a mailbox data is shown in Figure 11.4. ## MailEntry ``` RECORD pos: next: INTEGER; len: LONGINT; time, date: INTEGER; originator: ARRAY 20 OF CHAR END; ## MResTab ``` MailDir = ARRAY 31 OF MailEntry; We are now in a position to implement the handler for requests for message retrieval. It is guarded by the condition `pos := NIL`. After a valid check, the respective requestor's mailbox file is opened. The mailbox opened is related by the global variable `MF` which acts as a single entry cache. The associated user number is given by the global variable `mailno`. Since typically several requests involving the same mailbox follow, this measure avoids the repeated reopening of the same file. Thereafter, a rider is directly positioned at the respective directory entry for reading the message's length and position in the message part. The rider is repositioned accordingly, and transmission of the message is handled by procedure `SendMail`. ``` #################### File: Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf Page: 11 Context: ```markdown In concluding, we summarize the entire protocol specification below. The combined server facility, comprising file distribution, electronic mail, printing, and time services is operating on a Ceres-1 computer (1 Mips) with a 2 MByte store, of which half is used by the printer's bitmap. ## Summary of Protocol: | Protocol | Request | |------------|----------------------------------------------------------------------| | | ReceiveFile | SendFile | DeleteFile | Directory | | | | MailBox | SendMail | ReceiveMail | DeleteAll | | | | PrintStream | Sending | NameRequest | NewPassword | GetTime | - **ReceiveFile** `SND username password filename (datastream | NAK | NRP).` `datastream = DATA data ACK! (DAT data ACK(-1);` - **SendFile** `REC username password filename (ACK) datastream | NAK | NRP).` - **Datastream** `DATA data ACK! (DAT data ACK(-1);` - **DeleteFile** `DEL username password filename (ACK | NAK | NRP).` - **Directory** `FDIR username password prefix (datastream | NAK | NRP).` - **MailBox** `FMID username password (datastream | NAK | NRP).` - **SendMail** `RML username password (ACK datastream | NAK | NRP).` - **ReceiveMail** `SML username password msgno (datastream | NAK | NRP).` - **DeleteMail** `DML username password msgno (ACK | NAK | NRP).` - **PrintStream** `PRT username password (ACK datastream | NAK | NRP).` - **SendMsg** `MSG message ACK.` - **NameRequest** `NRP partname (NRS).` - **NewPassword** `NWP username password (ACK DAT newpassword (ACK | NAK | NRP).` - **GetTime** `RNG TIM time date.` ## 11.5 User Administration It appears to be a universal law that centralization inevitably calls for an administration. The centralized mail and printing services make no exception. The typical duties of an administration are accounting and protecting against misuse. It has to ensure that rendered services are counted and that an unauthorized user is not taking advantage of the server. An additional duty lies in the gathering of statistical data. In our case, accounting plays a very minor role, and the reason for the existence of the administration presented here is primarily protection. We distinguish between two kinds of protection. The first is protection of the server's resources in general, the second is that of individual users' resources from being accessed by others. Whereas in the first case some validation of a user's identification might suffice, the second case requires the association of personal resources with user names. In any case, the central server must store data for each member of the set of registered users. Specifically, it must be able to check the admissibility of a user's request on the basis of stored information. Evidently, a protection administration is similar in purpose and function to a lock. Quite regularly, locks are subjected to attempts of breaking them, and locks are subjected to attempts of being outwitted. The race between techniques of breaking locks and that of better countermeasures is well known, and we do not even try to make a contribution to it. Our design is based on the premise that the Oberon Server operates in a harmonious environment. Nevertheless, a minimal amount of protection machinery was included. It raises the amount of effort required for breaking protection to a level which is not reached when curiosity alone is the motivation. The data about users is held in a table in module Core. As was mentioned earlier, Core acts as the connector between the various servers by means of task queues. Its designated purpose is to provide the necessary access to user data via appropriate procedures. In the simplest solution, each table entry would contain a user name only. For each request, the administration would merely test for the presence of the request's user name in the table. A significant step towards safe protection is the introduction of a password in addition to the user name. In order that a request be honoured, not only must the name be registered, but the delivered and the stored password must match. Evidently, abusive attempts would aim at recovering the ``` #################### File: Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf Page: 12 Context: ```markdown # Stored Passwords Our solution lies in storing an encoded password. The command `System.SetUser`, which asks for a user identification and a password, immediately encodes the password, and the original is stored nowhere. The encoding algorithm is such that it is difficult to construct a corresponding decoder. ## Mail Service The mail service requires a third attribute in addition to identification and encoded password: the user's name as it is used for addressing messages. Identification typically consists of the user's initials; for the name, we suggest the full last name of the user and disallow cryptic abbreviations. ## Printing Service The printing service makes an accounting facility desirable. A fourth field in each user table entry serves as a count for the number of printed pages. As a result, there are four fields: `id`, `name`, `password`, and `count`. The table is not exported, but only accessible via procedures. `Core` is a good example of a resource hiding module. The program is listed below, and a few additional comments follow here. ### Procedures `UserNo(id)` and `UserNum(name)` yield the table index of the identified user; it is called user number and is used as a short encoding for recipients and senders within the mail server. In other servers, the number is merely used to check a request's validity. ## User Information The user information must certainly survive any intermission of server operation, be it due to software, hardware, or power failure. This requires that a copy of the user information is held on backup store (disk). The simplest solution would be to use a file for this purpose. But this would indeed make protection too vulnerable: files can be accessed easily, and we have refrained from introducing a file protection facility. Instead, the backup of the user information is held on a few permanently reserved sections on the server machine, which are inaccessible to the file system. ## Procedures Apart from procedures and variables constituting the queuing mechanism for tasks, the procedures exported from module `Core` all belong to the administration, and they can be divided into two categories. The first category contains the procedures used by the three servers presented in this Chapter, and they are `UserNo`, `UserNum`, `IncPageCount`, `SetPassword`, `GetUserName` and `GetFileName`. The second category consists of the procedures `NoUsers` and `GetUser` for inspecting table entries, and `InsertUser`, `DeleteUser`, `ClearPassword`, `ClearCounts`, and `Init` for making changes to the table. ## Client Module The client of the latter category is a module `Users` which is needed by the human administrator of the server facility. The reader may at this point wonder why a more advanced concept of administration has not been chosen, which would allow the human administrator to operate the server remotely. A quick analysis of the consequences of this widely used approach reveals that a substantial amount of additions to our system would be required. The issue of security and protection would become inflated into dimensions that are hardly justified for our local system. The first consequence would be a differentiation among levels of protection. The administrator would become a so-called super user with extra privileges, such as changing the user table. And so the game of trying to break the protection measures starts to become an interesting challenge. We have resisted the temptation to introduce additional complexity. Instead, we assume that physical access to the server station is reserved to the administrator. Naturally, module `Users` and in particular the symbol file of `Core` do not belong to the public domain. In concluding, we may point out that the impossibility of activating users' programs on the server station significantly reduces the possibilities for inflicting damage from the exterior. ``` #################### File: Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf Page: 13 Context: ```markdown # 12 The compiler ## 12.1 Introduction The compiler is the primary tool of the system builder. It therefore plays a prominent role in the Oberon System, although it is not part of the basic system. Instead, it constitutes a tool module - an application - with a single command: `Compile`. It translates program texts into machine code. Therefore, it is a program inherently machine-dependent; it acts as the interface between source language and target computer. In order to understand the process of compilation, the reader needs to be familiar with the source language Oberon defined in Appendix 1, and with the target computer RISC, defined in Appendix 2. The language is defined as an infinite set of sequences of symbols taken from the language's vocabulary. It is described by a set of equations called syntax. Each equation defines a syntactic construct, or more precisely, the set of sequences of symbols belonging to that construct. It specifies how that construct is composed of other syntactic constructs. The meaning of programs is defined in terms of semantic rules governing each such construct. Compilation of a program text proceeds by analyzing the text and thereby decomposing it recursively into its constructs according to the syntax. When a construct is identified, code is generated according to the semantic rule associated with the construct. The components of the identified construct supply parameters for the generated code. It follows that we distinguish between two kinds of actions: analyzing steps and code generating steps. In a rough approximation we may say that the former are source language dependent and target computer dependent, whereas the latter are source language independent and target computer dependent. Although reality is somewhat more complex, the modular structure of this compiler clearly reflects this division. The main module of the compiler is ORP (for Oberon to RISC Parser) It is primarily dedicated to syntactic analysis, parsing. Upon recognition of a syntactic construct, an appropriate procedure is called the code generator module ORG (for Oberon to RISC Generator). Apart from parsing, ORP checks for type consistency of operands, and it computes the attributes of objects identified in declarations. Whereas ORP mirrors the source language and is independent of a target computer, ORG reflects the target computer, but is independent of the source language. Oberon program texts are regarded as sequences of symbols rather than sequences of characters. Symbols themselves, however, are sequences of characters. We refrain from explaining the reasons for this distinction, but mention that apart from special characters and pairs such as `*`, `:=`, as well as identifiers, numbers, and strings are classified as symbols. Furthermore, certain capital letter sequences are symbols, such as `IF`, `END`, etc. Each time the syntax analyzer (parser) proceeds to read the next symbol, it does this by calling procedure `Geth`, which constitutes the so-called scanner residing in module ORS (for Oberon to RISC Scanner). It reads from the source text as many characters as are needed to recognize the next symbol. In passing we note that the scanner alone reflects the definition of symbols in terms of characters, whereas the parser is based on the notion of symbols only. The scanner implements the abstraction of symbols. The recognition of symbols within a character sequence is called *lexical analysis*. Ideally, the recognition of any syntactic construct, say `A`, consisting of subconstructs, say `B1`, `B2`, ..., `Bn`, leads to the generation of code that depends only on (1) the semantic rules associated with `A`, and (2) on attributes of `B1`, `B2`, ..., `Bn`. If this condition is satisfied, the construct is said to be context-free, and if all constructs of a language are context-free, then the language is context-free. Syntax and semantics of Oberon adhere to this rule, although with a significant exception. ``` #################### File: Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf Page: 14 Context: ```markdown exception is embodied by the notion of declarations. The declaration of an identifier, say x, attaches permanent properties to x, such as the fact that x denotes a variable and that its type is T. These properties are "invisible" when parsing a statement containing x, because the declaration of x is not also part of the statement. The "meaning" of identifiers is thus inherently context-dependent. Context-dependence due to declarations is the immediate reason for the use of a global data structure which represents the declared identifiers and their properties (attributes). Since this concept stems from early assemblers where identifiers (then called symbols) were registered in a linear table, the term *symbol table* tends to persist for this structure, although in this compiler it is considerably more complex than an array. Basically, it grows during the processing of declarations, and it is searched while expressions and statements are processed. Procedures for building and searching are contained in module ORB. A complication arises from the notion of exports and imports in Oberon. Its consequence is that the declaration of an identifier x may be in a module, say M, different from where x is referenced. If x is exported, the compiler includes x together with its attributes in the *symbol file* of the compiled module M. When compiling another module which imports M, that symbol file is read and its data are incorporated into the symbol table. Procedures for reading and writing symbol files are contained in module ORB, and no other module relies on information about the structure of symbol files. The syntax is precisely and rigorously defined by a small set of syntactic equations. As a result, the parser is a reasonably perspicuous and short program. In spite of the high degree of regularity of the target computer, the process of code generation is more complicated, as shown by module ORG. The resulting module structure of the compiler is shown in Fig. 12.1 in a slightly simplified manner. In reality OCS is imported by all other modules due to their need for procedure OCS.Mark. This, however, will be explained later. ![Figure 12.1 Compiler's module structure](path_to_image) ## 12.2. Code patterns Before it is possible to understand how code is generated, one needs to know *which* code is generated. In other words, we need to know the goal before we find the way leading to the goal. A fairly concise description of this goal is possible due to the structure of the language. As explained before, semantics are attached to each individual syntactic construct, independent of its context. Therefore, it suffices to list the expected code - instead of an abstract semantic rule - for each syntactic construct. As a prerequisite to understanding the resulting instructions and in particular their parameters, we need to know where declared variables are stored, i.e. which are their addresses. This compiler ``` #################### File: Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf Page: 16 Context: ```markdown # Pattern 1: Assignment of constants We begin with a simple example of assigning constants to variables. The variables used in this example are global; their base register is SB. Each assignment results in a single instruction. The constant is embedded within the instruction as a literal operand. ``` MODULE Pattern1: VAR ch: CHAR; k: INTEGER; x: REAL; s: SET; BEGIN // module entry code ch := '0'; 40000030 MOV R0 SB 30H B8000000 STR R0 SB 0 k := 10; 40000000 MOV R0 R0 10 k := 10; A0000004 STR R0 SB 4 x := 1.0; 600003F8 MOV R0 R0 3F8000H A0000008 STR R0 SB 8 s := {0, 4, 8}40000111 MOV R0 R0 111H A000000C STR R0 SB 12 END Pattern1. // module exit code ``` # Pattern 2: Simple expressions The result of an expression containing operators is always stored in a register before it is assigned to a variable or used in another operation. Registers for intermediate results are allocated sequentially in ascending order R0, R1, …, R11. Integer multiplication and division by powers of 2 are represented by shifts (LSL, ASR). Similarly, the modulus by a power of 2 is obtained by masking off leading bits. The operations of set union, difference, and intersection are represented by logical operations (OR, AND). ``` MODULE Pattern2: VAR i, j, k: INTEGER; x, y: REAL; s: SET; BEGIN i := (i + 1) * (i - 1); LDR R0 SB 0 ADD R0 R0 1 LDR R1 SB 0 SUB R1 R1 R0 MUL R0 R0 R1 STR R0 SB 0 k := k DIV 17; LDR R0 SB 8 DIV R0 R0 17 STR R0 SB 8 k := 8*n; LDR R0 SB 12 LDR R0 SB 12 LSL R0 R0 3 STR R0 SB 8 k := n DIV 2; LDR R0 SB 12 LDR R0 SB 12 ASR R0 R0 1 STR R0 SB 8 k := n MOD 16; LDR R0 SB 12 AND R0 SB 15 STR R0 SB 8 x := -y / (x - 1.0); LDR R0 SB 16 MOV R0 R0 3F80H FSB R0 R0 R1 LDR R1 SB 20 FDV R0 R1 R0 MOV R1 R0 s := s + t + u; LDR R0 SB 16 STR R0 SB 18 LDR R0 SB 28 LDR R1 R0 32 END Pattern2. // module exit code ``` ``` #################### File: Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf Page: 30 Context: ```markdown # Figure 12.5. Representation of declarations | Object | Type | |---------------|-------------------| | name | class | | val | type | | next | desc | | | | | Pointer | 4 | | Record | 12 | | nil | desc | | k Var | p Fid | q Fid | x Var | intType | |--------------|------------------|------------|-----------|---------| | 0 | 4 | 8 | 4 | 4 | | 4 | | | | | | 100 | | | | | | nil | | | | | | 1 | | | | | Only entries representing constructed types are generated during compilation. An entry for each basic type is established by the compiler's initialization. It consists of an Object holding the standard type's identifier and a Struct indicating its form, denoted by one of the values `Byte`, `Bool`, `Char`, `Int`, `Real`, or `Set`. The object records of the basic types are anchored in global pointer variables in module ORB (which actually should be regarded as constants). Not only are entries created upon initialization for basic types, but also for all standard procedures. Therefore, every compilation starts out with a symbol table reflecting all standard, pervasive identifiers and the objects they stand for. We now return to the subject of Objects. Whereas objects of basic classes (`Const`, `Var`, `Par`, `Fid`, `Typ`, `SProc`, `SFunc`, and `Mod`) directly reflect declared identifiers and constitute the context in which statements and expressions are compiled, compilations of expressions typically generate. ``` #################### File: Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf Page: 31 Context: ```markdown anonymous entities of additional, non-basic modes. Such entities reflect selectors, factors, terms, etc., i.e., constituents of expressions and statements. As such, they are of a transitory nature and hence are not represented by records allocated on the heap. Instead, they are represented by record variables local to the processing procedures and are therefore allocated on the stack. Their type is called `Item` and is a slight variation of the type `Object`. Items are not referenced via pointers. Let us assume, for instance, that a term `x*y` is parsed. This implies that the operator and both factors have been parsed already. The factors `x` and `y` are represented by two variables of type `Item` of `Var` mode. The resulting term is again described by an item, and since the product is transitory, i.e., has significance only within the expression of which the term is a constituent, it is to be held in a temporary location, in a register. In order to express that an item is located in a register, a new, non-basic mode `Reg` is introduced. Effectively, all non-basic modes reflect the target computer's architecture, in particular its addressing modes. The more addressing modes a computer offers, the more item modes are needed to represent them. The additional item modes required by the RISC processor are. They are declared in module `ORG`: | Reg | direct register mode | |------|----------------------| | RegI | indirect register mode | | Cond | condition code mode | The use of the types `Object`, `Item`, and `Struct` for the various modes and forms, and the meaning of their attributes are explained in the following tables: ### Objects: | class | val | a | b | r | |-------|------|-----|-----|-----| | 0 | Undf | | | | | 1 | Const| val | | | | 2 | Var | adr | base| | | 3 | Par | adr | off | | | 4 | Fld | off | off | | | 5 | Typo | TAdr| TAdr| modno| | 6 | SProc| num | | | | 7 | SFunc| num | | | | 8 | Mod | | | | | 10 | Reg | | regno| | | 11 | RegI | off | regno| | | 12 | Cond | | Tjmp| Fjmp| condition code | ### Structures: | form | nopFar | len | dsc | base | |------|--------|-----|-----|------| | 7 | Pointer| | base type | | 10 | ProcTyp| nopFar | param | result type | | 12 | Array | nofEl | element type | | 13 | Record | ext | lev | desc adr | fields | extension type | Items have an attribute called `lev` which is part of the address of the item. Positive values denote the level of nesting of the procedure in which the item is declared; `lev = 0` implies a global object. Negative values indicate that the object is imported from the module with number `-lev`. The three types `Object`, `Item`, and `Struct` are defined in module `ORB`, which also contains procedures for accessing the symbol table. ## 12.3.2. Module interfaces ``` #################### File: Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf Page: 35 Context: ```markdown # ORP ## Compiler - **ORP.Compile @**: The most recent selection identifies the beginning of the source text. - **ORP.Compile ^**: The most recent selection identifies the name of the source file. - **ORP.Compile f1 ... f0, f1, ...**: are the names of source files. File names and the characters `@` and `^` may be followed by an option specification `/s`. Option `/s` enables the compiler to overwrite an existing symbol file, thereby invalidating clients. The parser is designed according to the proven method of top-down, recursive descent parsing with a look-ahead of a single symbol. The last symbol read is represented by the global variable `sym`. Syntactic entities are mirrored by procedures of the same name. Their goal is to recognize the specified construct in the source text. The start symbol and corresponding procedure is `Module`. The principal parser procedures are shown in Fig. 12.6, which also exhibits their calling hierarchy. Loops in the diagram indicate recursion in the syntactic definition. ``` Module ├── Declarations │ ├── Type │ │ ├── RecType │ │ └── ArrayType │ └── ParamList ├── ProcDecl ├── StatSeq │ └── expression │ └── SimpleExp │ ├── term │ │ ├── factor │ │ └── element └── FPSeq └── FormalTyp ``` **Figure 12.6**: Parser procedure hierarchy. The rule of parsing strictly based on a single-symbol look-ahead and without reference to context is violated in three places. The prominent violation occurs in statements. If the first symbol of a statement is an identifier, the decision of whether an assignment or a procedure call is to be recognized is based on contextual information, namely the class of the identified object. The second violation occurs in `qualified` if the identifier `x` preceding a period denotes a module, it is recognized together with the subsequent identifier as a qualified identifier. Otherwise, `x` supposedly denotes a record variable. The third violation is made in procedure `selector`; if an identifier is followed by a left parenthesis, the decision of whether a procedure call or a type guard is to be recognized is again made on the basis of contextual information, namely the mode of the identified object. A fairly large part of the program is devoted to the discovery of errors. Not only should they be properly diagnosed, but a much more difficult requirement is that the parsing process should continue on the basis of a good guess about the structure that the text should most likely have. The parsing process must continue with some assumption and possibly after skipping a short piece of the identified object. ``` #################### File: Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf Page: 40 Context: ```markdown field = FLD name type offset. param = {VAR | PAR} type. A procedure type description contains a parameter list. Similarly, a record type description with form specifier `Record` contains the list of field descriptions. Note that a procedure is considered as a constant of a procedure type. Objects have types, and types are referenced by pointers. These cannot be written on a file. The straightforward solution would be to use the type identifiers as they appear in the program to denote types. However, this would be rather crude and inefficient, and second, there are anonymous types, for which artificial identifiers would have to be generated. An elegant solution lies in consecutively numbering types. Whenever a type is encountered the first time, it is assigned a unique reference number. For this purpose, records (in the compiler) of type `Type` contain the field ref. Following the number, a description of the type is then written to the symbol file. When the type is encountered again during the traversal of the data structure, only the reference number is issued, with negative sign. The global variable `ORB.Ref` functions as the running reference number. When reading a symbol file, a positive reference number is followed by the type's description. A pointer to the type read is assigned to the global table `typabt` with the reference number as index. When a negative reference number is read (it’s not followed by a type description), then the type is identified by `typabt[*]` (see procedure `InType`). In the following example, types are identified by their reference number (e.g. `#14`), and later referenced by this number `(*14*)`. ```pascal MODULE A; CONST T = "Dollar" = "$"; TYPE R = RECORD v: INTEGER; v: SET END; P = ^ RECORD A: ARRAY[0..4] OF R END; P = POINTER TO R; A = ARRAY[0..8] OF INTEGER; B = ARRAY[0..5] OF REAL; C = ARRAY[0..5] OF CHAR; V = ARRAY OF INTEGER; VAR X: INTEGER; PROCEDURE O0; BEGIN END O0; PROCEDURE O1(X: INTEGER); BEGIN RETURN X + Y; END O1; END A. ``` class = CON N1 [`4`] 10 class = CON Color [`3`] class = TYP P `14` form = REC [`2`] eno = 1 extlev = 0 size = 8 V [`6`] 4 U [`4`] 0)) class = TYP P `15` form = REC [`2`] eno = 2 extlev = 0 size = 32 V [`0`] form = ARR [`1`] len = 4 size = 32)) class = TYP P `16` form = PTR [`14`] class = TYP P `17` form = ARR [`1`] len = 8 size = 32)) class = TYP P `18` form = ARR [`1`] len = 8 size = 80)) class = TYP P `19` form = ARR [`5`] len = 5 size = 320)) class = TYP P `20` form = ARR [`1`] len = 1 size = 8)) class = VAR X [`4`] class = CON C0 [`3`] class = CON A0 [`10`] form = PRO [`14`] class = VAR [`4`] ``` After a symbol file has been generated, it is compared with the file from a previous compilation of the same module, if one exists. Only the two files differ and if the compiler's option is enabled, is the old file replaced by the new version. The comparison is made by comparing byte after byte without consideration of the file's structure. This somewhat crude approach was chosen because of its simplicity and yielded good results in practice. A symbol file must not contain addresses of variables or procedures. If they did, most changes in the program would result in a change of the symbol file. This must be avoided, because changes in ``` #################### File: Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf Page: 43 Context: ```markdown Instructions are emitted sequentially and emitted by the four procedures `Put0`, `Put1`, `Put2`, `Put3`. They directly correspond to the instruction formats of the RISC processor (see Chapter 11). The instructions are stored in the array code and the compiler variable `pc` serves as running index. ``` PROCEDURE Put0(op, a: b: INTEGER); format F0 PROCEDURE Put1(op, a: b: IN INTEGER); format F1 PROCEDURE Put2(op, a: b: off: INTEGER); format F2 PROCEDURE Put3(op, cond: off: INTEGER); format F3 ``` ## 12.7.1. Expressions Expressions consist of operands and operators. They are evaluated and have a value. First, a number of make-procedures transform objects into items (see Section 12.3.2). The principal one is `MakeItem`. Typical objects are variables (class, mode = `Var`). Global variables are addressed with base register `SB (xr = 13)`, local variables with the stack pointer `SP (xr = 14)`. `VAR`-parameters are addressed indirectly; the address is on the stack (class, mode = `Par`, `Ind`). `x` is the offset from the stack pointer. Before an operator can be applied to operands, these must first be transferred (loaded) into registers. This is because the RISC performs operations only on registers. The loading is achieved by procedure `load` and `loadAdr` in `ORG`. The resulting mode is `Reg`. In allocating registers, a strict stack principle is used, starting with `R0`, up to `R11`. This is certainly not an optimal strategy and provides ample room for improvement (usually called optimization). The compiler variable `RH` indicates the next free register (top of register stack). Base address `SB` is, as the name suggests, static. But this holds only within a module. It implies that on every transfer to a procedure in another module, the static base must be adjusted. The simplest way is to load `SB` before every external call, and to restore it to its old value after return from the procedure. We chose a different strategy: loading on demand (see below: global variables). If a variable is indexed, has a field selector, is dereferenced, or has a type guard, this is detected in the parser by procedure `selector`. It calls generators `Index`, `Field`, `DeRef`, or `TypeTest` accordingly (see Section 12.3.2 and patterns 1 - 4 in Section 12.2). These procedures cause item nodes to change as follows: 1. **Index(x, y) (y is loaded into x.r)** - `Var -> RegI` `ADD y, SP, y.r` // array variable - `Par -> RegI` `LDR RH, SP, x.a` `ADD y, RH, y.r` // array parameter - `RegI -> RegI` `ADD x, x.r, y.r` // indexed array 2. **Field(x, y) (y.mode = Field, y.a = field offset)** - `Var -> Var` `none` // field designator, add offset to x.a - `RegI -> RegI` `none` // add field offset to x.a - `Par -> none` `add field offset to x.b` 3. **DeRef(x)** - `Var -> RegI` `LDR RH, SP, x.a` // dereferenced x.a - `Par -> RegI` `LDR RH, SP, x.a` `LDR RH, x.b` // dereferenced parameter x.a - `RegI -> RegI` `LDR x.r, x.r, x.a` A fairly large number of procedures then deal with individual operators. Specifically, they are `Not`, `And1`, `And2`, `Or1`, `Or2` for Boolean operators, `Neg`, `AddOp`, `MulOp`, `DivOp` for operations on integers, `RealOp` for operations on real numbers, and `Singleton`, `SetIn`, and `SetOp` for operations. ``` #################### File: Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf Page: 44 Context: ```markdown # 12.7 RISC Operations ## 12.7.2 Relations RISC does not feature any compare instruction. Instead, subtraction is used, because an implicit comparison with 0 is performed along with any arithmetic (or load) instruction. Instead of `x < y` we use `x - y < 0`. This is possible, because in addition to the computed difference deposited in a register, also the result of the comparison is deposited in the condition flags N (difference negative) and Z (difference zero). Relations therefore yield a result item `x` with mode `Cond.x` (relat(g)ism) identifies the relation. Branch instructions (jumps) are executed conditionally depending on these flags. The value `x.r` is then used when generating branch instructions. For example, the relation `x < y` is translated simply into: ``` LDR R0, SP, x LDR R1, SP, y CMP R0, R0, R1 ``` And the resulting item mode is `x.mode = Cond, x.r = "less"`. (The mnemonic CMP is synonymous with SUB). More about relations and Boolean expressions will be explained in Section 12.7.6. ## 12.7.3 Set Operations The type SET represents sets of small integers in the range from 0 to 31. Bit `i` being 1 signals that `i` is an element of the set. This is a convenient representation, because the logical instructions directly mirror the set operations: AND implements set intersection, OR set union, and XOR the symmetric set difference. This representation also allows a simple and efficient implementation of membership tests. The instructions for the expression `m IN S` is generated by procedure `In`. Assuming the value in register R0, and the set `S` in R1, we obtain: ``` ADD R0, R0, 1 FOR R1, R1, R0 ; rotate S by i+1 position, the relevant bit moving to the sign bit ``` The resulting item mode is `Cond.x` where `x.r = "minus"`. Of some interest are the procedures for generating sets, i.e., for processing `{m}, {m .. n}, and {m, n}`, where `m` and `n` are integer expressions. We start with `{m}`. It is generated by procedure `Singleton` using a shift instruction. Assuming `m` in R0, the resulting code is: ``` MOV R1, 0, 1 LSL R0, R1, R0 ; shift 1 by m bit positions to the left ``` Somewhat more sophisticated is the generation of `{m .. n}` by procedure `Set`. Assuming `m` in R0, and `n` is R1, the resulting code is: ``` MOV R2, 0, 2 LSL R1, R2, R1 ; shift 2 by n bit positions to the left MOV R0, 2, -1 LSL R0, R2, R0 ; shift 1 by m bit positions to the left XOR R0, R0, R1 ``` The set `{m, n}` is generated as the union of `{m}` and `{n}`. If any of the element values is a constant, several possibilities of code improvement are possible. For details, the reader is referred to the source code of ORG. ## 12.7.4 Assignments ``` #################### File: Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf Page: 45 Context: ```markdown Statements have an effect, but no result like expressions. Statements are executed, not evaluated. Assignments alter the value of variables through store instructions. The computation of the address of the affected variable follows the same scheme as for loading. The value to be assigned must be in a register. Assignments of arrays (and records) are an exceptional case in so far as they are performed not by a single store instruction, but by a repetition. Consider `y = x`, where `x` and `y` are both arrays of `n` integers. Assuming that the address of `y` is in register R0, that of `x` in R1, and the value in R2. Then the resulting code is: ``` LDR R3, R1, 0 ; source ADD R1, R1, 4 ; R1 := R1 + 4 STR R3, R0, 0 ; destination ADD R0, R0, 4 ; R0 := R0 + 4 SUB R2, R2, 1 ; counter BNE L2 ; loop condition ``` ## 12.7.5 Conditional and repetitive statements These statements are implemented using branch instructions (jumps) as shown in Section 12.2, Patterns 5 - 7. In all repetitive statements, backward jumps occur. Here, at the point of return the value of the global variable `ORG.pc` is saved in a local (`l`) variable of the involved parsing procedure. It is retrieved when the backward jump is emitted. We note that branch instructions use a displacement rather than an absolute destination address. It is the difference between the branch instruction and the destination of the jump. A difficulty, however, arises in the case of forward jumps, a difficulty inherent in all single-pass compilers: When the branch is issued, its destination is still unknown. It follows that the branch displacement must be later resolved when it becomes known, when the destination is reached. This is called a `fixup`. Here the method of fixup lists is used. The place of the instruction with still unknown destination is held in a variable `l` localized to the respective parsing procedure. If several branches have the same destination, `l` is the leading of a list of the instructions to be fixed up, with its links placed in the instructions themselves in the place of the eventual jump displacement. This is shown for the statement by an excerpt of `ORP.StaSequence` with local variable `L0`: ``` ELSIF sym = ORS.i THEN ORS.Get(sym); expression(); ORG.FJump(l0); StatSequence: L0 := 0; WHILE sym = ORS.elsi DO ORS.Get(sym); ORG.FJump(L0); ORG.Fixup(x); expression(); ORG.FJump(y); Check(ORS.then, 'no THEN'); StatSequence END; IF sym = ORS.else THEN ORS.FJump(L0); ORG.Fixup(x); StatSequence ELSE ORG.Fixup(y) END; ORG.FixLink(L0); ``` where in module `ORG`: ``` PROCEDURE FJump(VAR x: Item); (*conditional forward jump*) BEGIN IF x.mode <> Cond THEN loadCond(x) END; Push(BC, negated(x), x.a); FLink(x, l0); x.a := pc-1 END FJump; PROCEDURE FJump(VAR x: LONGINT); (*unconditional forward jump*) BEGIN Push(BC, 7); l := L - p - 1 END FJump; PROCEDURE fix(at: WITH LONGINT); BEGIN code[at] := code[at] DIV C24 * C24 + (with MOD C24) END fix; ``` ``` #################### File: Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf Page: 47 Context: ```markdown # Stack Frames Scheme and layout determine the code sequences for call, entry, and exit of procedures. Here is an example of a procedure `P` with 2 parameters: ## Call: ``` LDR R0, param0 LDR R1, param1 BL P ``` ## Prolog: ``` SUB SP, SP, size ; decrement SP STR LNK, SP, 0 ; push return addr STR R0, SP, 4 ; push parameter 0 STR R1, SP, 8 ; push parameter 1 .... ``` ## Epilog: ``` LDR LNK, SP, 0 ; pop return addr ADD SP, SP, size ; increment SP BR LNK ``` When the call instruction is executed, parameters reside in registers, starting with R0. For function procedures, the result is passed in register R0. This scheme is very efficient; storing the parameters occurs only in a single place, namely at procedure entry, and not before each call. However, it has severe consequences for the entire register allocation strategy. Throughout the compiler, registers **must** be allocated in strict stack fashion. Furthermore, parameter allocation must start with R0. This is a distinct drawback for function calls. If registers are occupied by other values loaded prior to the call, they must be cleared; i.e., the parameters must be saved and reloaded after return. This is rather cumbersome (see procedures `ORG.SaveRegisters` and `ORG.RestoreRegisters`). ### Register Saving | Expression | Register Saving Needed | |----------------------|--------------------------| | F(x) | no register saving | | F(x + F(x)) | register saving necessary | --- ## Type Extension Static typing is an important principle in programming languages. It implies that every constant, variable, or function is of a certain data type, and that this type can be derived by reading the program text without executing it. It is the key principle to introduce important redundancy in languages in such a form that a compiler can detect inconsistencies. It is therefore the key element for reducing the number of errors in programs. However, it also acts as a restriction. It is, for example, impossible to construct data structures (arrays, trees) with different types of elements. In order to relax the rule of strictly static typing, the notion of type extension was introduced in Oberon. It makes it possible to construct. ``` #################### File: Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf Page: 48 Context: ```markdown # Type Safety in Oberon Inhomogeneous data structures without abandoning type safety. The price is that the checking of type consistency must in certain instances be deferred to run-time. Such checks are called *type tests*. The challenge is to defer to run-time as few checks as possible and as many as needed. The solution in Oberon is to introduce families of types, and compatibility among their members. Their members are thus related, and a family forms a hierarchy. The principle idea is the following: Any record type `T0` can be extended into a new type `T1` by additional record fields (attributes). `T1` is then called an *extension* of `T0`, which in turn is said to be `T1`'s *base type*. `T1` is then compatible with `T0`, but not vice-versa. This property ensures that in many cases static type checking is still possible. Furthermore, it turns out that run-time tests can be made very efficient, thus minimizing the overhead for maintaining type safety. For example, given the declarations: ```pascal TYPE R0 = RECORD u: INTEGER END; R1 = RECORD (R0) u: INTEGER END; ``` we say that `R1` is an extension of `R0`. `R0` has the fields `u` and `v`, `R1` has `u`, `v`, and `w`. The concept becomes useful in combination with pointers. Let ```pascal TYPE P0 = POINTER TO R0; P1 = POINTER TO R1; VAR p0: P0; p1: P1; ``` Now it is impossible to assign `p0` to `p0` (because a `P1` is always also a `P0`), but not `p0` to `p1`, because a `P0` need not be a `P1`. This has the simple consequence that a variable of type `P0` may well point to an extension of `R0`. Therefore, data structures can be declared with a base type `P0`, as common element type, but in fact they can individually differ; they can be any extension of the base type. Obviously, it must be possible to determine the actual, current type of an element even if the base type is statically fixed. This is possible through a *type test*, syntactically a Boolean factor: ```pascal p0 IS P1 ``` (short for `p0 IS R1`) Furthermore, we introduce the *type guard*. In the present example, the designator `p0^` is illegal, because there is no field `v` in a record of type `P0`, even if the current value of `p0^` is a `R1`. As this case occurs frequently, we introduce the short notation `p0(P1^),` implying a test `p0 IS P1` and an abort if the test is not met. It is important to mention that this technique also applies to formal variable parameters of record type, as they also represent a pointer to the actual parameter. Its type may be any extension of the type specified for the formal parameter in the procedure heading. ## Implementation of Type Test and Type Guard How are type test and type guard efficiently implemented? Our first observation is that they must consist of a single comparison only, similar to index checks. This in turn implies that types must be identified by a single word. The solution lies in using the unique address of the type descriptor or the *record* type. Which data must this descriptor hold? Essentially, type descriptors (TD) must identify the base types of a given type. Consider the following hierarchy: ```pascal TYPE T = RECORD ... END; T0 = RECORD (T) ... END; // extension level 1 T1 = RECORD (T) ... END; // extension level 1 T00 = RECORD (T0) ... END; // extension level 2 T01 = RECORD (T0) ... END; // extension level 2 T10 = RECORD (T1) ... END; // extension level 2 T11 = RECORD (T1) ... END; // extension level 2 ``` ``` #################### File: Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf Page: 52 Context: ```markdown # Graphic Viewer The graphic viewer shows an excerpt of the drawing plane, and several viewers may show different parts of a drawing. The most frequently used commands are built-in as mouse clicks and combinations of clicks. Additional commands are selectable from texts, either in viewer menus (title bars) or in the text called **Draw Tool**. Fig. 13.1 shows the display with two graphic viewers at the left and the draw tool text at the right. The mouse buttons have the following principal functions whenever the cursor lies in a graphic frame: | Left | Middle | Right | |-----------------|------------------|-------------| | draw / set caret| move / copy | select | ## 13.2.1 Basic Commands The command `Draw.Open` opens a new viewer and displays the graph with the name given as a parameter. We suggest that file names use the extension `.graph`. **Drawing a line.** In order to draw a horizontal or vertical line from P0 to P1, the left key is pressed with the cursor at P0 and, while the key is held, the mouse and cursor is moved to P1. Then the key is released. If P0 and P1 differ in both their x and y coordinates, the end point is adjusted so that the line is either horizontal or vertical. **Writing a caption.** First the cursor is positioned where the caption is to appear. Then the left key is clicked, causing a crosshair to appear. It is called the caret. Then the text is typed. Only single lines of texts are accepted. The `DEL` key may be used to retract characters (backspace). **Selecting.** Most commands require the specification of operands, and many implicitly assume the previously selected elements - the **selection** - to be their operands. A single element is selected by pointing at it with the cursor and then clicking the right mouse button. This also causes previously selected elements to be deselected. If the left key is also clicked, their selection is retained. This action is called an **interclick**. To select several elements at once, the cursor is moved from P0 to P1 while the right key is held. Then all elements lying within the rectangle with diagonally opposite corners at P0 and P1 are selected. Selected lines are displayed as dotted lines, selected captions (and macros) by inverse video mode. A macro is selected by pointing at its lower left corner. The cursor is called **sensitive area**. **Moving.** To move (displace) a set of elements, the elements are first selected and then the cursor is moved from P0 to P1 while the middle key is held. The vector from P0 to P1 specifies the movement and is called the **displacement vector**. P0 and P1 may lie in different viewers displaying the same graph. Small displacements may be achieved by using the keyboard's cursor keys. **Copying.** Similarly, the selected elements may be copied (duplicated). In addition to pressing the middle key indicating the displacement vector, the left key is interclicked. The copy command may also be used to copy elements from one graph into another graph by moving the cursor from one viewer into another viewer displaying the destination graph. A text item may be copied from a text frame into a graphic frame and vice-versa. There exist two ways to accomplish this: 1. First the caret is placed at the destination position, then the text is selected and the middle key is interclicked. 2. First the text is selected, then the caret is placed at the destination position and the middle key is interclicked. **Shifting the plane.** You may shift the entire drawing plane behind the viewer by specifying a displacement vector pressing the middle button (like in a move command) and interclicking the right button. The following table shows a summary of the mouse actions: | Left | Action | |------------------|----------------| | draw | line | | left (no motion) | set caret | ``` #################### File: Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf Page: 55 Context: ```markdown rectangles. Rectangles are selected by pointing at their lower left corner and are created by the following steps: 1. The caret is placed where the lower left corner of the new rectangle is to lie. 2. A secondary caret is placed where the opposite corner is to lie (ML + MR). 3. The command `Rectangles.Make` is activated. ## 13.2.6. Oblique lines, circles, and ellipses Further graphic elements are (oblique) lines, circles, and ellipses. The sensitive area of circles and ellipses is at their lowest point. They are created by the following steps: ### Lines: 1. The caret is placed where the starting point is to lie. 2. A secondary caret is placed at the position of the end. 3. The command `Curves.MakeLine` is activated. ### Circles: 1. The caret is placed where the circle's center is to lie. 2. A secondary caret is placed, its distance from the center specifying the radius. 3. The command `Curves.MakeCircle` is activated. ### Ellipses: 1. The caret is placed where the center is to lie. 2. A second caret is placed. Its horizontal distance from the first caret specifies one axis. 3. A third caret is placed. Its vertical distance from the first caret specifies the other axis. 4. The command `Curves.MakeEllipse` is activated. ## 13.2.7. Spline curves Spline curves are created by the following steps: 1. The caret is placed where the starting point is to lie. 2. Secondary carets are placed at the spline's fixed points (at most 20). 3. The command `Splines.MakeOpen` or `Splines.MakeClosed` is activated. ## 13.2.8. Constructing new macros A new macro is constructed and inserted in the library `lib` under the name `mac` as follows: 1. All elements which belong to the new macro are selected. 2. The caret is placed at the lower left corner of the area to be spanned by the macro. 3. A secondary caret is placed at the upper right corner of the area to be spanned. 4. The command `MacroTool.MakeMacro lib` is activated. An existing macro can be decomposed (opened) into its parts as follows: 1. The macro is selected. 2. The caret is placed at the position where the decomposition is to appear. 3. The command `MacroTool.OpenMacro` is activated. The command `MacroTool.StoreLibrary lib` first stores the library `lib` on the specified file. Only macros presently loaded are considered as belonging to the library. If one wishes to add macros to an existing library file, all of its elements must first be loaded. This is best done by opening a graph containing all macros of the desired library file. ## 13.3. The core and its structure Like a text, a graphic consists of elements, subsequently to be called objects. Unlike a text, which is a sequence of elements, a graphic is an unordered set of objects. In a text, the position of an element need not be explicitly indicated (stored); it is recomputed from the position of its predecessor each time it is needed, for example for displaying or selecting an element. In a graphic, each object must carry its position explicitly, as it is independent of any other object in the set. This is an essential difference, requiring a different treatment and much more storage space for an equal number of objects. ``` #################### File: Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf Page: 58 Context: ```markdown handle: PROCEDURE (obj: Object; VAR M: Msg); next: Object END; PROCEDURE Handle (obj: Object; VAR M: Msg); BEGIN (* this procedure is assigned to the handle field of every line object *) IF M.IsDrawMsg THEN drawLine(obj)(Line) ELSIF M.IsWriteMsg THEN writeLine(obj)(Line), M(WriteMsg).R ELSE ... END END; PROCEDURE drawGraphic(first: Object; VAR M: Msg); VAR obj: Object; BEGIN obj := first; WHILE obj <> NIL DO obj.handle(obj, M); obj := obj.next END END drawGraphics; In the present system, a combination of the two schemes presented so far is used. It eliminates the need for individual method fields in each object record as well as the cascaded IF statement for discriminating among the message types. Yet it allows further addition of new methods for later extensions without the need to change the object's declaration. The technique used is to include a single field (called obj) in each record (analogous to the handler). This field is a pointer to a method record containing the procedures declared for the base type. At least one of them uses a message parameter, i.e., a parameter of record structure that is extensible. TYPE Method = POINTER TO MethodDesc; Msg = RECORD END; Context = RECORD END; Object = POINTER TO ObjectDesc; ObjectDesc = RECORD x, y: INTEGER; selected: BOOLEAN; method: NEXT: Object END; MethodDesc = RECORD new: Modules.Command; copy: PROCEDURE (obj: Object); draw: handle: PROCEDURE (obj: Object; VAR M: Msg); selectable: PROCEDURE (obj: Object; x, y: INTEGER): BOOLEAN; read: PROCEDURE (obj: Object; VAR R: Files.Rider; VAR C: Context); write: PROCEDURE (obj: Object; con: INTEGER; VAR R: Files.Rider; VAR C: Context); END; A single method instance is generated when a new object type is created, typically in the initialization sequence of the concerned module. When a new object is created, a pointer to its record is assigned to the obj field of the new object descriptor. A call then has the form obj^.write(obj, R). This example exhibits the versatility of Oberon's type extension and procedure variable features very well, and it does so without hiding the data structures involved in a dispensable, built-in run-time mechanism. The foregoing deliberations suggest the system's modular structure shown in Figure 13.3: ``` #################### File: Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf Page: 59 Context: ```markdown # Lines, Captions, Macros, and Other Classes ![Figure 13.3 Clients of module Graphics](graphics-figure.png) The modules in the top row implement the individual object types' methods, and additionally provide commands, in particular `Make` for creating new objects. The base module specifies the base types and procedures operating on graphics as a whole. Our system, however, deviates from this scheme somewhat for several reasons: 1. **Implementation of the few methods** requires relatively short programs for the basic objects. Although a sensible modularization is desirable, we wish to avoid atomization, and therefore merge parts that would result in tiny modules with the base module. 2. **The elements of a graphic** refer to fonts used in captions and to libraries used in macros. The writing and reading procedures therefore carry a context consisting of fonts and libraries as an additional parameter. Routines for mapping a font (library) to a number according to a given context on output, and a number to a font (library) on input are contained in module `Graphics`. 3. **In the design of the Oberon System**, a hierarchy of four modules has proven to be most appropriate: - Module with base type handling the abstract data structure. - Module containing procedures for the representation of objects in frames (display handling). - Module containing the primary command interpreter and connecting frames with a viewer. - A command module scanning command lines and invoking the appropriate interpreters. The module hierarchy of the Graphics System is shown together with its analogy, with the Text System: | Function | Graphics | Text | |-------------------|-------------|-------------| | Command Scanner | Draw | Edit | | Viewer Handler | MenuViewers| MenuViewers | | Frame Handler | GraphicFrames| TextFrames | | Base | Graphics | Texts | As a result, module `Graphics` does not only contain the base type `Object`, but also its extensions `Line` and `Macro`. Their methods are also defined in `Graphics`, with the exception of drawing methods, which are defined in `GraphicFrames`, because they refer to frames. So far, we have discussed operations on individual objects and the structure resulting from the desire to be able to add new object types without affecting the base module. We now turn our attention briefly to operations on graphics as a whole. They can be grouped into two kinds, namely operations involving a graphic as a set, and those applying to the selection, i.e., to a subset only. The former kind consists of procedures `Add`, which inserts a new object, `Draw`, which traverses the set of objects and invokes their drawing methods, `SelectObj`, which searches for an object at a given position, `SelectAll`, which marks an object to be selected, `SelectArea`, which identifies all objects lying within a given rectangular area and marks them, `Selectable`, a Boolean function, and `Enumerate`, which applies the parametric procedure handle to all objects of a graphic. Furthermore, the procedures `Load`, `Store`, `Print`, and `WriteFile` belong to this kind. ``` #################### File: Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf Page: 62 Context: ```markdown # Figure 13.4 Frame and graph coordinates As a consequence, the display coordinates \( u, v \) of an object \( z \) of a graph displayed in a frame \( f \) are computed as: \[ u = z.x + f.x, \quad v = z.y + f.y \] In order to determine whether an object \( z \) lies within a frame \( f \), the following expression must hold: \[ (f.x < u \leq f.x + f.w) \& (f.y < v \leq f.y + f.h) \] The record field `marked` indicates whether or not the frame contains a caret. Its display position is recorded in the field called `mark`. A frame may contain several (secondary) carets; they form a list of individual location descriptors. When an object is displayed (drawn), its state must be taken into consideration in order to provide visible user feedback. The manner in which selection is indicated, however, may vary among different object types. This can easily be realized because every object (type) is associated with an individual drawing procedure. The following visualizations of selection have been chosen: - Selected lines are shown in a grey tone (raster pattern). - Selected captions are shown with "inverse video". Change of state is a relatively frequent operation, and if possible a complete repainting of the involved objects should be avoided for reasons of efficiency. Therefore, procedures for drawing an object are given a mode parameter, in addition to the obvious object and frame parameters. The parameters are combined into the message record of type `DrawMsg`. ```pascal DrawMsg = RECORD (Graphics.Msg) f: Frame; mode: x, y, col: INTEGER; END; ``` The meaning of the mode parameter's four possible values are the following: - **mode = 0**: draw object according to its state, - **mode = 1**: draw reflecting a transition from normal to selected state, - **mode = 2**: draw reflecting a transition from selected to normal state, - **mode = 3**: erase. In the case of captions, for instance, the transitions are indicated by simply inverting the rectangular area covered by the caption. No rewriting of the captions' character patterns is required. ``` #################### File: Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf Page: 63 Context: ```markdown A mode parameter is also necessary for reflecting object deletion. First, the selected objects are drawn with mode indicating erasure. Only afterwards are they removed from the graphic's linked list. Furthermore, the message parameter of the drawing procedure contains two offsets `x` and `y`. They are added to the object's coordinates, and their significance will become apparent in connection with macros. The same holds for the color parameter. The drawing procedures are fairly straightforward and use the four basic raster operations of module `Display`. The only complication arises from the need to clip the drawing at the frame boundaries. In the case of captions, a character is drawn only if it fits into the frame in its entirety. The raster operations do not test (again) whether the indicated position is valid. At this point we recall that copies of a viewer (and its frames) can be generated by the `System.Copy` command. Such copies display the same graphic, but possibly different excerpts of them. When a graphic is changed by an insertion, deletion, or any other operation, at a place that is visible in several frames, all affected views must reflect the change. A direct call to a drawing procedure indicating a frame and the change does therefore not suffice. Here again, the object-oriented style solves the problem neatly: In place of a direct call a message is broadcast to all frames, the message specifying the nature of the required updates. The broadcast is performed by the general procedure `Viewers.Broadcast(M)`. It invokes the handlers of all viewers with the parameter `M`. The viewer handlers either interpret the message or propagate it to the handlers of their subframes. Procedure `obj.handle` is called with a control message as parameter when pointing at the object and clicking the middle mouse button. This allows control to be passed to the handler of an individual object. The definition of module `GraphicFrames` is summarized by the following interface: ```modula-2 DEFINITION GraphicFrames; IMPORT Display, Graphics; TYPE Frame = POINTER TO FrameDesc; Location = POINTER TO LocDesc; LocDesc = RECORD x, y: INTEGER; next: Location END; FrameDesc = RECORD (Display.FrameDesc) graph: Graphics.Graph; xg, Y1, Y1: x, y: INTEGER; marked, clicked: BOOLEAN; mark: LocDesc END; (* mode = 0 -> draw according to selected, 1: normal -> selected, 2: selected -> normal, 3: erase *) DrawMsg = RECORD (Graphics.Msg) t: Frame; x, y, col, mode: INTEGER END; PROCEDURE Restore (F: Frame); PROCEDURE Focus (F: Frame); PROCEDURE Selected (F: Frame); PROCEDURE ThisX (x: INTEGER; F: Frame); PROCEDURE Draw (F: Frame); PROCEDURE Erase (F: Frame); PROCEDURE DrawObj (F: Frame; obj: Graphics.Obj); PROCEDURE EraseObj (F: Frame; obj: Graphics.Obj); PROCEDURE Change (F: Frame; VAR msg: Graphics.Msg); PROCEDURE Decease (F: Frame); PROCEDURE Deselect (F: Frame); PROCEDURE Macro (VAR Lname, Mname: ARRAY OF CHAR); ``` ``` #################### File: Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf Page: 64 Context: ```markdown ## 13.5 The User Interface Although the display is the prime constituent of the interface between the computer and its user, we chose the title of this chapter for a presentation primarily focused on the computer's input, i.e., on its actions instigated by the user's handling of keyboard and mouse, the editing operations. The design of the user interface plays a decisive role in a system's acceptance by users. There is no fixed set of rules which determine the optimal choice of an interface. Many issues are a matter of subjective judgement, and all too often convention is being mixed up with convenience. Nevertheless, a few criteria have emerged as fairly generally accepted. We base our discussion on the premise that input is provided by a keyboard and a mouse, and that keyboard input is essentially to be reserved for textual input. The critical issue is that a mouse - apart from providing a cursor position - allows to signal actions by the state of its keys. Typically, there are far more actions than there are keys. Some mice feature a single key only, a situation that we deem highly unfortunate. There are, however, several ways to "enrich" key states: 1. **Position.** Key states are interpreted depending on the current position of the mouse represented by the cursor. Typically, interpretation occurs by the handler installed in the view covering the cursor position, and different handlers are associated with different view types. The handler chosen for interpretation may even be associated with an individual (graphic) object and depend on that object's type. 2. **Clicks.** Interpretation may depend on the number of repeated clicks (of the same key), and/or on the duration of clicks. 3. **Interclicks.** Interpretation may depend on the combination of keys depressed until the last one is released. This method is obviously inapplicable for single-key mice. Apart from position dependence, we have quite successfully used interclicks. A ground rule to be observed is that frequent actions should be triggered by single-key clicks, and only variants of them should be signalled by interclicks. The essential art is to avoid overloading this method. Less frequent operations may as well be triggered by textual commands, i.e., by pointing at the command word and clicking the middle button. Even for this kind of activation, Oberon offers two variations: 1. The command is listed in a menu (title bar). This solution is favored when the respective viewer is itself a parameter to the command, and it is recommended when the command is reasonably frequent, because the necessary mouse movement is relatively short. 2. The command lies elsewhere, typically in a viewer containing a tool text. Lastly, we note that any package such as `Draw` is integrated within an entire system together with other packages. Hence it is important that the rules governing the user interfaces of the various packages do not differ unnecessarily, but that they display common ground rules and a common design "philosophy". `Draw`'s conventions were, as far as possible and sensible, adapted to those of the text system. The right key serves for selecting, the left for setting the caret, and the middle key for activating general commands, in this case moving and copying the graphic. Inherently, drawing involves certain commands that cannot be dealt with in the same way as text fonts. A character is created by typing on the keyboard; a line is created by dragging the mouse while holding the left key. Interclicks left-middle and right-middle are treated in the same way as in the text system (copying a caption from the selection to the caret), and this is not surprising, because text and graphics are properly integrated, i.e., captions can be copied from texts into graphics and vice-versa. ``` #################### File: Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf Page: 67 Context: ```markdown # Modules.ThisCommand Then the data of the base type `Object` are read, and lastly the data of the extension area are read by a call to the class method read. The following may serve as a template for any module defining a new object class `X`. Two examples are given in Section 13.9, namely Rectangles and Curves. ## MODULE X IMPORT Files, Oberon, Graphics, GraphicFrames; TYPE XType = POINTER TO XDesc; XDesc = RECORD (Graphics: ObjectDesc) (* additional data fields *) END; VAR method: Graphics.Method; ### PROCEDURE New*; VAR x: X; BEGIN NEW(x); x.do := method; Graphics.new := x END New; ### PROCEDURE Copy(obj, to: Graphics.Object); BEGIN to(X)^ := obj(X)^ END Copy; ### PROCEDURE Draw(obj: Graphics.Object; VAR msg: Graphics.Msg); BEGIN (* Draw *) END Draw; ### PROCEDURE Selectable(obj: Graphics.Object; x, y: INTEGER): BOOLEAN; BEGIN (* Selectable logic here *) END Selectable; ### PROCEDURE Change(obj: Graphics.Object; VAR msg: Graphics.Msg); BEGIN IF msg IS Graphics.ColorMsg THEN obj^ := msg(Graphics.ColorMsg) ELSIF msg IS ... THEN (* Handle other message types *) END END Change; ### PROCEDURE Read(obj: Graphics.Object; VAR w: Files.Rider; VAR C: Context); BEGIN (* Read *specific data*) END Read; ### PROCEDURE Write(obj: Graphics.Object; cno: SHORTINT); VAR w: Files.Rider; VAR R: Context; BEGIN Graphics.WriteObj(w, obj, (* write *specific data*)) END Write; ### PROCEDURE Make* (command); VAR x: X; VAR f: GraphicFrames.Frame; BEGIN NEW(x); x.f.mark := F.mark; x.y := F.mark.y; x.w := ...; x.h := ...; x.co := Oberon.CurLoc.x; x.do := method; GraphicFrames.Defocus(F); Graphics.AddF(graph, x); GraphicFrames.DrawObj(F, x) END Make; BEGIN NEW(method); method.module := "X"; method.allocator := "New"; method.copy := Copy; method.draw := Draw; method.selectable := Selectable; method.handle := Handle; method.read := Read; method.write := Write; method.print := Print; END X. ``` #################### File: Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf Page: 71 Context: ```markdown and libraries - themselves represented as files - are replaced by indices to font and library dictionaries. These dictionaries establish a context and are constructed while a file is read. They are used only during this process and hence are local to procedure `Load` (or `Open`). For classes, a dictionary listing the respective allocation procedures is constructed in order to avoid repeated calls to determine the pertinent allocator. When a graphic file is generated by procedure `Store`, local dictionaries are constructed of fonts, libraries, and classes of objects that have been written onto the file. Upon encountering a caption, a macro, or any element whose font, library, or class is not contained in the respective dictionary, a pair consisting of index and name is emitted to the file, thereby assigning a number to each name. These pairs are interspersed within the sequence of object descriptions. When the graphic file is read, these pairs trigger insertion of the font, library, or class in the respective dictionary, whereby the name is converted into a pointer to the entity, which is obtained by a loading process embodied by procedures `Fonts.This`, `Gelt.Lib`, and `GetClass`. Both the `Load` and `Store` procedures traverse the file only once. The files are self-contained in the sense that all external quantities are represented by their names. The format of a graphics file is defined in Extended BNF syntax as follows: ``` file = tag stretch. stretch = {item} 255. item = 0 {fonto fontname | 1 | libno libname | 0 | 2 classno classname allocname | 1 | data | 2 data from string | 3 data libno macname | classno data extension}. data = x y w h color. ``` All class numbers are at least 4; the values 1, 2, and 3 are assigned to lines, captions, and macros. `x`, `y`, `w`, and `h` are two-byte integer attributes of the base type `Object`. The attribute `color` takes a single byte. The first byte of an item being 0 signifies that the item is an identification of a new font, library, or class. If the second byte is 0, a new font is announced, if 1 a new library, and if 2 a new class of elements. The same procedures are used for loading and storing a library file. In fact, `Load` and `Store` read a file stretch representing a sequence of elements which is terminated by a special value (255). In a library file, each macro corresponds to a stretch, and the terminator is followed by values specifying the macro's overall width, height, and its name. The structure of library files is defined by the following syntax: ``` li tag = libtag (macro). macro = stretch w h name. ``` The first byte of each element is a class number within the context of the file and identifies the class to which the element belongs. An object of the given class is allocated by calling the class' allocation procedure, which is obtained from the class dictionary in the given context. The class number is used as dictionary index. The presence of the required allocation procedure in the dictionary is guaranteed by the fact that a corresponding index/name pair had preceded the element in the file. The encoder of such a pair triggers the loading of the module specifying the class and its methods. The name of the pair consists of two parts: the first specifies the module in which the class is defined, and it is taken as the parameter of the call to the loader (see procedure `GetClass`). The second part is the name of the relevant allocation procedure which returns a class object to variable `Graphics.new`. Thereafter, the data defined in the base type `Object` are read. Data belonging to an extension follow those of the base type, and they are read by the extension's read method. This part must always be headed by a type specifying the number of bytes which follow. This information is used in the case where a requested module is not present; it indicates the number of bytes to be skipped in order to continue reading further elements. A last noteworthy detail concerns the `Move` operation which appears as surprisingly complicated, particularly in comparison with the related copy operation. The reason is our deviation from the principle that a graphics editor must refrain from an interpretation of drawings. Responsible for this ``` #################### File: Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf Page: 76 Context: ```markdown Still, how did the hardware configuration data and the boot loader get into the Flash ROM? This step requires the help of proprietary tools of the FPGA manufacturer. Regrettably, their incantation ceremony typically is rather complex. After all necessary Verilog modules have been synthesized, the result is the configuration file `RISCTop.bit`. The necessary source files are: - `RISCTop.v` - `RISC.v` - `Multiplier.v` - `Divider.v` - `FP_Multiplier.v` - `FP_Divider.v` - `dbram32.v` - `RS232T.v` - `RS232.v` - `SP1K.xgs` - `P2V.x` - `RISC.ucf` Thereafter, the boot loader is compiled and, together with the result of the configuration of the RISC hardware, loaded into the configuration memory of the FPGA. This Stage 0 is partly done with proprietary software (dependent on the specific FPGA) and is described in a separate installation guide. ``` Stage 0 ``` ```plaintext RISCTop.bit ins1.mem +----------------+ | FlashRISC_cmd | +----------------+ | v Stage 1 +----------+ | RISC.bit | +----------+ | v +----------------+ | Xilinx tool | | download.cmd | +----------------+ | v +-----------+ | BRAM | | boot | | loader | +-----------+ | v +----------------+ | Config mem | | FPGA config | +----------------+ | v Stage 2 +-----------+ | RS-232 | | link | +-----------+ | v +----------------+ | Memory | | | | Kernel | | File | | Modules | | Oberon | +----------------+ ``` **Figure 14.2** Booting from host computer A simple boot loader reading from the RS-232 line and using the stream format described above is shown here: ```pascal MODULE BootLoader; IMPORT SYSTEM; CONST MT = 12; SP = 14; MemLim = 0E7F00H; VAR w: INTEGER; len = 60; data = 56; ctrl = 52; (* 'device addresses' *) PROCEDURE RecInt(VAR x: INTEGER); VAR z, y: INTEGER; BEGIN z := 2; y := 4; REPEAT i := i + 1; REPEAT UNTIL SYSTEM.BIT(crt, 0); SYSTEM.GET(data, y); z := ROR(z, y, 8); UNTIL i = 0; x := z; END RecInt; PROCEDURE Load; VAR len, adr, dat: INTEGER; BEGIN RecInt(len); WHILE len > 0 DO RecInt(dat); REPEAT RecInt(data); SYSTEM.PUT(dat, adr); adr := adr + 4; len := len - 4 UNTIL len = 0; RecInt(len); END Load; ``` ``` #################### File: Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf Page: 79 Context: ```markdown 20 modname load module 21 modname unload module 22 name call command 50 adr, list of values write memory 51 adr, n clear memory (in words) 52 secno, list of values write sector 53 secno, n clear sector (n words) 100 load boot track 101 clear file directory Oberon imports modules **Kernel**, **FileDir**, **Files**, **Modules**, **RS232**, **PCLink1**. This is the inner core plus facilities for communication. ## 14.3 Maintenance Tools An important prerequisite for Stage 2 (and the following stages) in the boot process has not been mentioned above. Recall that the initialization of module **FileDir** constructs the disk sector reservation table in the **Kernel** from information contained on the disk. Obviously, its prerequisite is an intact, consistent file directory. A single unreadable, corrupted file directory or file header sector lets this process fail, and booting becomes impossible. To cope with this (fortunately rare) situation, a maintenance tool has been designed: module **DiskCheck**. **DiskCheck** is organized similarly to **Oberon** as a simple command interpreter, but it imports only **Kernel** and **RS232**. Hence, booting involves only Stages 1 and 2 without any access to the disk. Operating **DiskCheck** requires care and knowledge of the structure of the file system (Chapter 7). The available commands are the following: | parameters | action | |------------------|-----------------------------------| | 0 | send and mirror integer (test) | | 1 a, n | show (in hex) M[a], M[a+4], ..., M[a + n*4] | | 2 secno | show disk sector | | 3 secno | show head sector | | 4 secno | show directory sector | | 5 | traverse directory | | 6 secno | clear header sector | | 7 secno | clear directory (root) | The essential command is the file directory traversal (5). It lists all faulty directory sectors, showing their numbers. It also lists faulty header sectors. No changes are made to the file system. If a faulty header is encountered, it can subsequently be cleared (6). Thereby the file is lost. It is not removed from the directory, though. But its length will be zero. Program **DiskCheck** must be extremely robust. No data read can be assumed to be correct, no index can be assumed to be within its declared bounds. No sector number can be assumed to be valid, and no directory or header page may be assumed to have the expected format. Guards and error diagnostics take a prominent place. Whereas a faulty sector in a file in the worst case leads to the loss of that file, a fault in a sector carrying a directory page is quite disastrous. Not only because the files referenced from that page, but also those referenced from descendant pages become inaccessible. A fault in the root page even causes the loss of all files. The catastrophe is of such proportions, that measures should be taken even if the case is very unlikely. After all, it might happen, and it indeed has occurred. The only way to recover files that are no longer accessible from the directory is by scanning the entire disk. In order to make a search at all possible, every file header carries a mark field that is given a fixed, constant value. It is very unlikely, but not entirely impossible, that data sectors which happen to have the same value at the location corresponding to that of the mark, may be mistaken to be headers. ``` #################### File: Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf Page: 80 Context: ```markdown The tool performing such a scan is called **Scavenger**. It is, like **DiskCheck**, a simple command interpreter with the following available commands: | parameters | action | |------------|------------------------------------| | 0 s | send and mirror integer (test) | | 1 n | Scan the first n sectors and collect headers | | 2 - | Display names of collected files | | 3 - | Build new directory | | 4 - | Transfer new directory to the disk | | 5 - | Clear display | During the scan, a new directory is gradually built up in primary store. Sectors marked as headers are recorded by their name and creation date. The scavenger is the reason for recording the file name in the header, although it remains unused there by the Oberon System. Recovery of the date is essential, because several files with the same name may be found. If one is found with a newer creation date, the older entry is overwritten. Command W transfers the new directory to the disk. For this purpose, it is necessary to have free sectors available. These have been collected during the scan: both old directory sectors (identified by a directory mark similar to the header mark) and overwritten headers are used as free locations. The scavenger has proven its worth on more than one occasion. Its main drawback is that it may rediscover files that had been deleted. The deletion operation by definition affects only the directory, but not the file. Therefore, the header carrying the name remains unchanged and is discovered by the scan. All in all, however, it is a small deficiency. ### Reference 1. N. Wirth. Designing a System from Scratch. *Structured Programming*, 1, (1989), 10-18. ``` #################### File: Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf Page: 81 Context: ```markdown # 15 Tool and service modules In this chapter, a few modules are presented that do not belong to Oberon's system core. However, they belong to the system in the sense of being basic, and of assistance in some way, either to construct application programs, to communicate with external computers, or to analyze existing programs. ## 15.1 Basic mathematical functions Module `Math` contains the basic standard functions that had been postulated already in 1960 by Algol 60. They are: - `sqrt(x)` the square root - `exp(x)` the exponential function - `ln(x)` the natural logarithm - `sin(x)` the sine function - `cos(x)` the cosine function They are presented here only briefly without discussing their approximation methods. However, we point out how advantage can be taken from knowledge about the internal representation of floating-point numbers. ### 15.1.1 Conversion between integers and floating-point numbers The Oberon System adopts the standard format postulated by IEEE. Here we restrict it to the 32-bit variant. A floating-point number `x` consists of 3 parts: - `s` the sign | 1 bit - `e` the exponent | 8 bits - `m` the mantissa | 23 bits Its value is defined as \( x = (-1)^s \times 2^{e-127} \times (1.m) \). A number is in normalized form, if its mantissa satisfies \( 1.0 \leq m < 2.0 \). It is assumed that numbers are always normalized, and therefore the leading 1-bit is omitted. The exception is the singular value 0, which cannot be normalized. It must therefore be treated as a special case. It follows that integers and floating-point numbers are represented quite differently, and that conversion operations are necessary to transfer a number from one format to the other. This is the reason why the Oberon language keeps the two types `INTEGER` and `REAL` separate. Conversion must be explicitly specified by using the two predefined functions: - \( n = \text{FLOOR}(x) \quad \text{REAL} \rightarrow \text{INTEGER} \) - \( x = \text{FLT}(n) \quad \text{INTEGER} \rightarrow \text{REAL} \) Note: `FLOOR(x)` rounds toward -inf. For example `FLOOR(1.5) = 1`, `FLOOR(-1.5) = -2`. The RISC processor does not feature specific instructions implementing these functions. Instead, the compiler generates inline code using the `FAD` instruction with special options suppressing normalization. This option is specified by the `u` and `v` modifiers of the instruction. The `FLOOR` function is realized by adding 0 with an exponent of 127 + 24 and suppressing the insertion of a leading 1-bit (i.e. \( u = 1 \)). This causes the mantissa of the argument to be shifted right until its exponent is equal to 151. The RISC instructions are: ``` MOV R1 R0 4800H R1 = 48000000H FAD R0 R0 R1 ``` The `FLT` function is implemented also by adding 0 with an exponent of 151 and forced insertion of a leading 1-bit (i.e. \( v = 1 \)). ``` #################### File: Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf Page: 85 Context: ```markdown REPEAT UNTIL SYSTEM.BIT(stat, 0); SYSTEM.GET(data, x); END Dec; PROCEDURE RecName(VAR s: ARRAY OF CHAR); VAR i: INTEGER; x: BYTE; BEGIN i := 0; Rec(i); WHILE x <> 0 DO s[i] := CHR(x); INC(i); Rec(x); END; s[i] := 0; END RecName; PROCEDURE Send(x: BYTE); BEGIN REPEAT UNTIL SYSTEM.BIT(stat, 1); SYSTEM.PUT(data, x); END Send; PROCEDURE Task; VAR len, i: INTEGER; x, ack: BYTE; name: ARRAY[0..31] OF CHAR; F: Files.File; R: Files.Rider; buf: ARRAY[0..255] OF BYTE; BEGIN IF SYSTEM.BIT(stat, 0) THEN (*byte available*) Rec(code); IF code = SND THEN ("send file") RecName(name); F := Files.Old(name); IF F = NIL THEN Send(ACK); len := Files.Length(F); Files.SetR(F, 0); REPEAT IF len > BLKlen THEN len := BLKlen ELSE len := len END; Send(len); n := len; len := len - 1; WHILE l = 0 DO Files.Read(byte[r, x]; Send(x); DEC(len) END; IF ack & ACK THEN len = 0 END UNTIL len < BLKlen; ELSE Send(1); END ELSEIF code = REC THEN ("receive file") RecName(name); F := Files.New(name); IF F = NIL THEN Files.SetR(F, 0); Send(ACK); REPEAT Rec(x); len := x; i := 0; WHILE i < len DO Rec(byte[r, buf[i]]); INC(i) END; WHILE i < len DO Files.WriteByte(F, buf[i]); INC(i) END; Send(ACK); UNTIL len < 255; Files.Reset(F); Send(ACK); ELSE Send(NAK); END ELSEIF code = REC THEN Send(ACK) ("for testing") END END Task; PROCEDURE Run; BEGIN Oberon.Init(); Texts.WriteString(W, "PCLink started"); Texts.Writeln(W); Texts.Append(Oberon.Log, W.buf); END Run; PROCEDURE Stop; ``` #################### File: Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf Page: 86 Context: ```markdown # 15.3 A Generator of Graphic Macros The module `MacroTool` serves to create macros for the graphic system (Ch. 13). It provides the commands `OpenMacro`, `MakeMacro`, `LoadLibrary`, and `StoreLibrary`. ## OpenMacro `OpenMacro` decomposes the selected macro into its elements and places them at the position of the caret. This command is typically the first if an existing macro is to be modified. ## MakeMacro `MakeMacro` L M collects all selected objects in the frame designated by the star pointer and unites them into macro M. This macro is displayed at the caret position and inserted into library L. If no such library exists, a new one is created. ## LoadLibrary `LoadLibrary` L loads the library L (under file name `L.Lib`). Note that a library must have been stored, before it can be loaded. ## StoreLibrary `StoreLibrary` stores library L (with filename `L.Lib`). The required modules are `Texts`, `Oberon`, `Graphics`, `GraphicFrames`. ``` ########## """QUERY: Hi can you explain to me the Communications Theory?""" Consider the chat history for relevant information. Use all information included. Use as much tokens as needed. Important: If you find information separated by a | in the context, it is a table formatted in Markdown.Important: Take a look at the QUERY and only the QUERY. If this is vague or unclear, please ignore everything and ask a follow-up question instead! Final Files Sources: Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf - Page 1, Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf - Page 3, Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf - Page 4, Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf - Page 5, Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf - Page 6, Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf - Page 7, Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf - Page 8, Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf - Page 10, Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf - Page 11, Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf - Page 12, Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf - Page 13, Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf - Page 14, Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf - Page 16, Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf - Page 17, Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf - Page 18, Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf - Page 19, Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf - Page 21, Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf - Page 28, Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf - Page 31, Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf - Page 32, Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf - Page 34, Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf - Page 35, Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf - Page 36, Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf - Page 40, Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf - Page 42, Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf - Page 43, Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf - Page 44, Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf - Page 46, Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf - Page 47, Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf - Page 50, Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf - Page 52, Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf - Page 54, Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf - Page 59, Introduction%20to%20Quantum%20Information%20-%20Stephen%20M.%20Barnett%20%28PDF%29.pdf - Page 64, The%20Little%20Book%20About%20OS%20Development%20-%20Erik%20Helin%2C%20Adam%20Renberg%20-%20%28PDF%2C%20HTML%29.pdf - Page 3, The%20Little%20Book%20About%20OS%20Development%20-%20Erik%20Helin%2C%20Adam%20Renberg%20-%20%28PDF%2C%20HTML%29.pdf - Page 6, The%20Little%20Book%20About%20OS%20Development%20-%20Erik%20Helin%2C%20Adam%20Renberg%20-%20%28PDF%2C%20HTML%29.pdf - Page 9, The%20Little%20Book%20About%20OS%20Development%20-%20Erik%20Helin%2C%20Adam%20Renberg%20-%20%28PDF%2C%20HTML%29.pdf - Page 12, The%20Little%20Book%20About%20OS%20Development%20-%20Erik%20Helin%2C%20Adam%20Renberg%20-%20%28PDF%2C%20HTML%29.pdf - Page 17, The%20Little%20Book%20About%20OS%20Development%20-%20Erik%20Helin%2C%20Adam%20Renberg%20-%20%28PDF%2C%20HTML%29.pdf - Page 21, The%20Little%20Book%20About%20OS%20Development%20-%20Erik%20Helin%2C%20Adam%20Renberg%20-%20%28PDF%2C%20HTML%29.pdf - Page 23, The%20Little%20Book%20About%20OS%20Development%20-%20Erik%20Helin%2C%20Adam%20Renberg%20-%20%28PDF%2C%20HTML%29.pdf - Page 25, The%20Little%20Book%20About%20OS%20Development%20-%20Erik%20Helin%2C%20Adam%20Renberg%20-%20%28PDF%2C%20HTML%29.pdf - Page 27, The%20Little%20Book%20About%20OS%20Development%20-%20Erik%20Helin%2C%20Adam%20Renberg%20-%20%28PDF%2C%20HTML%29.pdf - Page 28, The%20Little%20Book%20About%20OS%20Development%20-%20Erik%20Helin%2C%20Adam%20Renberg%20-%20%28PDF%2C%20HTML%29.pdf - Page 29, The%20Little%20Book%20About%20OS%20Development%20-%20Erik%20Helin%2C%20Adam%20Renberg%20-%20%28PDF%2C%20HTML%29.pdf - Page 30, The%20Little%20Book%20About%20OS%20Development%20-%20Erik%20Helin%2C%20Adam%20Renberg%20-%20%28PDF%2C%20HTML%29.pdf - Page 31, The%20Little%20Book%20About%20OS%20Development%20-%20Erik%20Helin%2C%20Adam%20Renberg%20-%20%28PDF%2C%20HTML%29.pdf - Page 32, The%20Little%20Book%20About%20OS%20Development%20-%20Erik%20Helin%2C%20Adam%20Renberg%20-%20%28PDF%2C%20HTML%29.pdf - Page 37, The%20Little%20Book%20About%20OS%20Development%20-%20Erik%20Helin%2C%20Adam%20Renberg%20-%20%28PDF%2C%20HTML%29.pdf - Page 41, The%20Little%20Book%20About%20OS%20Development%20-%20Erik%20Helin%2C%20Adam%20Renberg%20-%20%28PDF%2C%20HTML%29.pdf - Page 44, The%20Little%20Book%20About%20OS%20Development%20-%20Erik%20Helin%2C%20Adam%20Renberg%20-%20%28PDF%2C%20HTML%29.pdf - Page 47, The%20Little%20Book%20About%20OS%20Development%20-%20Erik%20Helin%2C%20Adam%20Renberg%20-%20%28PDF%2C%20HTML%29.pdf - Page 50, The%20Little%20Book%20About%20OS%20Development%20-%20Erik%20Helin%2C%20Adam%20Renberg%20-%20%28PDF%2C%20HTML%29.pdf - Page 53, The%20Little%20Book%20About%20OS%20Development%20-%20Erik%20Helin%2C%20Adam%20Renberg%20-%20%28PDF%2C%20HTML%29.pdf - Page 60, The%20Little%20Book%20About%20OS%20Development%20-%20Erik%20Helin%2C%20Adam%20Renberg%20-%20%28PDF%2C%20HTML%29.pdf - Page 66, The%20Little%20Book%20About%20OS%20Development%20-%20Erik%20Helin%2C%20Adam%20Renberg%20-%20%28PDF%2C%20HTML%29.pdf - Page 70, The%20Little%20Book%20About%20OS%20Development%20-%20Erik%20Helin%2C%20Adam%20Renberg%20-%20%28PDF%2C%20HTML%29.pdf - Page 71, The%20Little%20Book%20About%20OS%20Development%20-%20Erik%20Helin%2C%20Adam%20Renberg%20-%20%28PDF%2C%20HTML%29.pdf - Page 73, The%20Little%20Book%20About%20OS%20Development%20-%20Erik%20Helin%2C%20Adam%20Renberg%20-%20%28PDF%2C%20HTML%29.pdf - Page 75, The%20Little%20Book%20About%20OS%20Development%20-%20Erik%20Helin%2C%20Adam%20Renberg%20-%20%28PDF%2C%20HTML%29.pdf - Page 78, Web%20API%20Design%20-%20Brian%20Mulloy%20%28PDF%29.pdf - Page 9, Web%20API%20Design%20-%20Brian%20Mulloy%20%28PDF%29.pdf - Page 11, Web%20API%20Design%20-%20Brian%20Mulloy%20%28PDF%29.pdf - Page 33, Web%20API%20Design%20-%20Brian%20Mulloy%20%28PDF%29.pdf - Page 38, Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf - Page 1, Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf - Page 2, Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf - Page 4, Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf - Page 6, Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf - Page 7, Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf - Page 8, Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf - Page 11, Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf - Page 12, Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf - Page 13, Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf - Page 14, Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf - Page 16, Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf - Page 30, Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf - Page 31, Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf - Page 35, Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf - Page 40, Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf - Page 43, Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf - Page 44, Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf - Page 45, Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf - Page 47, Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf - Page 48, Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf - Page 52, Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf - Page 55, Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf - Page 58, Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf - Page 59, Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf - Page 62, Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf - Page 63, Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf - Page 64, Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf - Page 67, Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf - Page 71, Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf - Page 76, Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf - Page 79, Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf - Page 80, Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf - Page 81, Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf - Page 85, Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20PO.Applications.pdf - Page 86 ================================================== **Elapsed Time: 0.00 seconds** ================================================== FINAL ANSWER Answer: Communications Theory, as described in the provided context, was first introduced by Claude Shannon as a mathematical framework for understanding the process of communication. It involves a sender (Alice, in this case) transmitting a message to a receiver (Bob) through a channel, which is subject to noise. Here's a breakdown of the key concepts: **1. Information and Entropy:** * Information is quantified based on the probabilities of different messages. The less likely a message is, the more information it conveys. * Entropy, represented by the formula H = - Σ p\_i log p\_i, measures the average information content of a set of messages. It's essentially a measure of uncertainty. **2. Communication Channel:** * A communication channel is the medium through which the signal travels from sender to receiver. This could be a wire, optical fiber, air (for sound), or even a piece of paper. **3. Noise:** * Noise is any unwanted disturbance that affects the signal during transmission. This can lead to errors in the received message. **4. Encoding and Decoding:** * Encoding is the process of converting the message into a form suitable for transmission through the channel. * Decoding is the reverse process, converting the received signal back into the original message. **5. Shannon's Coding Theorems:** * **Noiseless Coding Theorem:** This theorem deals with compressing a message to its most efficient form while still allowing for perfect reconstruction at the receiver. It states that the average number of bits needed to encode a message is equal to its entropy. * **Noisy Coding Theorem:** This theorem addresses the issue of noise in the channel. It states that there's a limit to how much information can be reliably transmitted through a noisy channel, and this limit is determined by the channel's capacity. To combat noise, redundancy is introduced into the encoded message, allowing for error detection and correction. **Example:** The text provides an example of compressing a message by removing vowels. This reduces redundancy and makes the message shorter. However, if noise is introduced (by flipping bits, for example), the compressed message becomes harder to decode. Adding back some redundancy (like vowels) helps to combat the errors introduced by noise. **In essence, Communications Theory provides a mathematical framework for understanding the fundamental limits of communication and how to design efficient and reliable communication systems.** ================================================== **Elapsed Time: 94.19 seconds** ==================================================