<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>Julram's 개발 낙서장</title>
    <link>https://julrams.tistory.com/</link>
    <description>개발 관련 사항 정리 및 기억하기 위한 낙서장입니다.
저의 조그마한 지식이 도움 되시길.</description>
    <language>ko</language>
    <pubDate>Sat, 23 May 2026 03:06:22 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>줄람이</managingEditor>
    <item>
      <title>[Linux] SD / eMMC (mmc) 설정 확인 커맨드</title>
      <link>https://julrams.tistory.com/49</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;1. interrupts 체크&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;#&amp;nbsp;cat&amp;nbsp;/proc/interrupts&amp;nbsp;|&amp;nbsp;grep&amp;nbsp;mmc &lt;br /&gt;&amp;nbsp;45:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;160&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;GIC-0&amp;nbsp;161&amp;nbsp;Level&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;mmc0 &lt;br /&gt;&amp;nbsp;46:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;GIC-0&amp;nbsp;159&amp;nbsp;Level&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;mmc1 &lt;br /&gt;&amp;nbsp;47:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;1223&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;GIC-0&amp;nbsp;157&amp;nbsp;Level&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;mmc2&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;2. debugfs 활용 (mount -t debugfs none /sys/kernel/debug)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;#&amp;nbsp;cat&amp;nbsp;/sys/kernel/debug/mmc0/ios&amp;nbsp; &lt;br /&gt;clock:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;50000000&amp;nbsp;Hz &lt;br /&gt;vdd:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;21&amp;nbsp;(3.3&amp;nbsp;~&amp;nbsp;3.4&amp;nbsp;V) &lt;br /&gt;bus&amp;nbsp;mode:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;2&amp;nbsp;(push-pull) &lt;br /&gt;chip&amp;nbsp;select:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;0&amp;nbsp;(don't&amp;nbsp;care) &lt;br /&gt;power&amp;nbsp;mode:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;2&amp;nbsp;(on) &lt;br /&gt;bus&amp;nbsp;width:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;2&amp;nbsp;(4&amp;nbsp;bits) &lt;br /&gt;timing&amp;nbsp;spec:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;7&amp;nbsp;(sd&amp;nbsp;uhs&amp;nbsp;DDR50) &lt;br /&gt;signal&amp;nbsp;voltage:&amp;nbsp;1&amp;nbsp;(1.80&amp;nbsp;V) &lt;br /&gt;driver&amp;nbsp;type:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;0&amp;nbsp;(driver&amp;nbsp;type&amp;nbsp;B)&lt;br /&gt;&lt;br /&gt;#&amp;nbsp;cat&amp;nbsp;/sys/kernel/debug/mmc2/ios&amp;nbsp; &lt;br /&gt;clock:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;100000000&amp;nbsp;Hz &lt;br /&gt;vdd:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;7&amp;nbsp;(1.65&amp;nbsp;-&amp;nbsp;1.95&amp;nbsp;V) &lt;br /&gt;bus&amp;nbsp;mode:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;2&amp;nbsp;(push-pull) &lt;br /&gt;chip&amp;nbsp;select:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;0&amp;nbsp;(don't&amp;nbsp;care) &lt;br /&gt;power&amp;nbsp;mode:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;2&amp;nbsp;(on) &lt;br /&gt;bus&amp;nbsp;width:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;3&amp;nbsp;(8&amp;nbsp;bits) &lt;br /&gt;timing&amp;nbsp;spec:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;9&amp;nbsp;(mmc&amp;nbsp;HS200) &lt;br /&gt;signal&amp;nbsp;voltage:&amp;nbsp;1&amp;nbsp;(1.80&amp;nbsp;V) &lt;br /&gt;driver&amp;nbsp;type:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;0&amp;nbsp;(driver&amp;nbsp;type&amp;nbsp;B)&lt;/p&gt;</description>
      <category>System Programming/Tips</category>
      <category>mmc</category>
      <category>sd</category>
      <author>줄람이</author>
      <guid isPermaLink="true">https://julrams.tistory.com/49</guid>
      <comments>https://julrams.tistory.com/49#entry49comment</comments>
      <pubDate>Wed, 1 Apr 2026 16:41:24 +0900</pubDate>
    </item>
    <item>
      <title>Chapter 2. ARMv8-A Architecture and Processors</title>
      <link>https://julrams.tistory.com/48</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;2.1 ARMv8-A&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;ARMv8-A 아키텍처는 애플리케이션 프로파일을 대상으로 하는 최신 세대의 ARM 아키텍처입니다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;ARMv8이라는 이름은 이제 32비트 실행과 64비트 실행을 모두 포함하는 전체 아키텍처를 설명하는 데 사용됩니다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;기존 ARMv7 소프트웨어와의 하위 호환성을 유지하면서 64비트 와이드 레지스터로 실행할 수 있는 기능을 도입했습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1153&quot; data-origin-height=&quot;810&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cZ9PRN/dJMcacCv25v/kar34KOIn2tYCRGjWII141/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cZ9PRN/dJMcacCv25v/kar34KOIn2tYCRGjWII141/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cZ9PRN/dJMcacCv25v/kar34KOIn2tYCRGjWII141/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcZ9PRN%2FdJMcacCv25v%2Fkar34KOIn2tYCRGjWII141%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1153&quot; height=&quot;810&quot; data-origin-width=&quot;1153&quot; data-origin-height=&quot;810&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;ARMv8-A 아키텍처는 여러 가지 변경 사항을 도입하여 훨씬 더 높은 성능의 프로세서 구현을 설계할 수 있게 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Large physical address&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 프로세서가 4GB 이상으로 접근이 가능하도록 합니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;64-bit virtual addressing&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span&gt; 4GB 제한을 초과하는 가상메모리를 사용할 수 있습니다. memory mapped file I/O 또는 sparse addressing&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt; (희소 주소 지정)을 사용하는 최신 데스크톱 및 서버 소프트웨어에 중요합니다.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;Automatic event signaling&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span&gt; 전력 효율이 높고 고성능의 spinlock을 구현할 수 있습니다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Larger register files&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt; 31개의&amp;nbsp;64비트&amp;nbsp;범용&amp;nbsp;레지스터는&amp;nbsp;성능을&amp;nbsp;향상시키고&amp;nbsp;스택&amp;nbsp;사용량을&amp;nbsp;줄입니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Efficient 64-bit immediate generation&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt; 리터럴풀 사용을 줄일 수 있습니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Large PC-relative addressing range&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt; 공유&amp;nbsp;라이브러리&amp;nbsp;및&amp;nbsp;위치&amp;nbsp;독립&amp;nbsp;실행&amp;nbsp;파일&amp;nbsp;내에서&amp;nbsp;효율적인&amp;nbsp;데이터&amp;nbsp;주소&amp;nbsp;지정을&amp;nbsp;위한&amp;nbsp;+/-4GB&amp;nbsp;주소&amp;nbsp;범위.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Additional 16KB and 64KB translation granules&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt; 번역&amp;nbsp;조회&amp;nbsp;버퍼(TLB)&amp;nbsp;누락률과&amp;nbsp;페이지&amp;nbsp;탐색&amp;nbsp;깊이가&amp;nbsp;줄어듭니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;New exception model&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt; 이를&amp;nbsp;통해&amp;nbsp;운영체제&amp;nbsp;및&amp;nbsp;하이퍼바이저&amp;nbsp;소프트웨어의&amp;nbsp;복잡성이&amp;nbsp;줄어듭니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Eifficient cache management&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt; 사용자&amp;nbsp;공간&amp;nbsp;캐시&amp;nbsp;작업은&amp;nbsp;동적&amp;nbsp;코드&amp;nbsp;생성&amp;nbsp;효율성을&amp;nbsp;향상시킵니다.&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt; 데이터 캐시 제로 명령어를 사용한 빠른 데이터 캐시 클리어 기능도 제공합니다.&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;Hadware-accelerated cryptography&lt;/h4&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt; 3배에서&amp;nbsp;10배&amp;nbsp;향상된&amp;nbsp;소프트웨어&amp;nbsp;암호화&amp;nbsp;성능을&amp;nbsp;제공합니다.&amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt; 이는&amp;nbsp;HTTPS와&amp;nbsp;같이&amp;nbsp;하드웨어&amp;nbsp;가속기로&amp;nbsp;효율적으로&amp;nbsp;오프로드하기에는&amp;nbsp;너무&amp;nbsp;작은&amp;nbsp;단위의&amp;nbsp;암호화&amp;nbsp;및&amp;nbsp;복호화에&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt; 유용합니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Load-Acquire, Store-Release instructions&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt; C++11,&amp;nbsp;C11,&amp;nbsp;Java&amp;nbsp;메모리&amp;nbsp;모델에&amp;nbsp;맞춰&amp;nbsp;설계되었습니다.&amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;명시적인&amp;nbsp;메모리&amp;nbsp;배리어&amp;nbsp;명령어를&amp;nbsp;제거하여&amp;nbsp;스레드&amp;nbsp;안전&amp;nbsp;코드의&amp;nbsp;성능을&amp;nbsp;향상시킵니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;NEON double-precision floating-point advanced SIMD&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt; 이를&amp;nbsp;통해&amp;nbsp;SIMD&amp;nbsp;벡터화는&amp;nbsp;과학&amp;nbsp;계산,&amp;nbsp;고성능&amp;nbsp;컴퓨팅(HPC)&amp;nbsp;및&amp;nbsp;슈퍼컴퓨터와&amp;nbsp;같은&amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;훨씬&amp;nbsp;더&amp;nbsp;광범위한&amp;nbsp;알고리즘에&amp;nbsp;적용될&amp;nbsp;수&amp;nbsp;있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>System Programming/Arm</category>
      <category>ARMv8-A Programmer's Guide</category>
      <author>줄람이</author>
      <guid isPermaLink="true">https://julrams.tistory.com/48</guid>
      <comments>https://julrams.tistory.com/48#entry48comment</comments>
      <pubDate>Wed, 25 Mar 2026 16:31:26 +0900</pubDate>
    </item>
    <item>
      <title>Linux Kernel DRM (Direct Rendering Manager)</title>
      <link>https://julrams.tistory.com/47</link>
      <description>&lt;h2 id=&quot;1.-DRM&quot; style=&quot;background-color: #ffffff; color: #292a2e; text-align: start;&quot; data-renderer-start-pos=&quot;3&quot; data-ke-size=&quot;size26&quot;&gt;1. DRM&lt;span&gt;&lt;span style=&quot;color: #505258;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p style=&quot;background-color: #ffffff; color: #292a2e; text-align: start;&quot; data-renderer-start-pos=&quot;11&quot; data-ke-size=&quot;size16&quot;&gt;DRM (Direct Rendering Manager)은 Linux Kernel에서 &lt;b&gt;디스플레이 및 그래픽 장치를 관리하는 서브 시스템&lt;/b&gt;으로 유저 공간 애플리케이션과 GPU/디스플레이 하드웨어 사이의 인터페이스 역할을 합니다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #292a2e; text-align: start;&quot; data-renderer-start-pos=&quot;138&quot; data-ke-size=&quot;size16&quot;&gt;Linux Kernel에는 이미 그래픽 어댑터의 프레임버퍼를 관리하는 데 사용되는 fbdev 드라이버 및 API가 있었지만 최신 3D 가속 GPU 기반 비디오 하드웨어의 요구 사항을 처리하는 데는 어려움이 있었습니다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #292a2e; text-align: start;&quot; data-renderer-start-pos=&quot;261&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #292a2e; text-align: start;&quot; data-renderer-start-pos=&quot;263&quot; data-ke-size=&quot;size16&quot;&gt;이러한 장치는 일반적으로 자체 메모리(VRAM 및 CMA)에서 명령 대기열을 설정하고 관리하여 GPU에 명령을 전송해야 하며 해당 메모리 내의 버퍼와 여유 공간을 관리해야 합니다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #292a2e; text-align: start;&quot; data-renderer-start-pos=&quot;365&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #292a2e; text-align: start;&quot; data-renderer-start-pos=&quot;367&quot; data-ke-size=&quot;size16&quot;&gt;처음에는 사용자 공간 프로그램(X Server)이 이러한 리소스를 직접 관리했지만 일반적으로 자신만이 액세스할 수 있는 것처럼 작동했습니다. 두 개 이상의 프로그램이 동시에 같은 하드웨어를 제어하고 각기 다른 방식으로 리소스를 설정하려고 하면 대부분의 상황에서 문제가 발생하였습니다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #292a2e; text-align: start;&quot; data-renderer-start-pos=&quot;527&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #292a2e; text-align: start;&quot; data-renderer-start-pos=&quot;529&quot; data-ke-size=&quot;size16&quot;&gt;Direct Rendering Manager는 여러 프로그램이 비디오 하드웨어 리소스를 공동으로 사용할 수 있도록 만들어졌습니다. DRM은 GPU에 독점적으로 접근하며 명령 대기열, 메모리 및 기타 하드웨어 리소스를 초기화하고 유지 관리합니다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #292a2e; text-align: start;&quot; data-renderer-start-pos=&quot;529&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;image-20250901-053156.png&quot; data-origin-width=&quot;1634&quot; data-origin-height=&quot;984&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bLbiZq/dJMcaf6dToE/kmHj9kwNVOB1v5oGiHpr8K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bLbiZq/dJMcaf6dToE/kmHj9kwNVOB1v5oGiHpr8K/img.png&quot; data-alt=&quot;Without DRM&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bLbiZq/dJMcaf6dToE/kmHj9kwNVOB1v5oGiHpr8K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbLbiZq%2FdJMcaf6dToE%2FkmHj9kwNVOB1v5oGiHpr8K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1634&quot; height=&quot;984&quot; data-filename=&quot;image-20250901-053156.png&quot; data-origin-width=&quot;1634&quot; data-origin-height=&quot;984&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Without DRM&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;image-20250901-053224.png&quot; data-origin-width=&quot;1633&quot; data-origin-height=&quot;983&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bXBG9V/dJMcab3OXzJ/rFfJN9ohuty3KLd8ZDfzw0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bXBG9V/dJMcab3OXzJ/rFfJN9ohuty3KLd8ZDfzw0/img.png&quot; data-alt=&quot;With DRM&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bXBG9V/dJMcab3OXzJ/rFfJN9ohuty3KLd8ZDfzw0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbXBG9V%2FdJMcab3OXzJ%2FrFfJN9ohuty3KLd8ZDfzw0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1633&quot; height=&quot;983&quot; data-filename=&quot;image-20250901-053224.png&quot; data-origin-width=&quot;1633&quot; data-origin-height=&quot;983&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;With DRM&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #292a2e; text-align: start;&quot; data-renderer-start-pos=&quot;699&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;GPU를 사용하려는 프로그램은 DRM에 요청을 보내면 DRM은 중재자 역할을 하며 충돌 가능성을 방지합니다.&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #292a2e; text-align: start;&quot; data-renderer-start-pos=&quot;762&quot; data-ke-size=&quot;size16&quot;&gt;위의 주된 이유로 인하여 DRM 형태로 전환하여 Linux Kernel이 발전하였으며 모드 설정, 메모리 공유 개체 및 동기화와 같이 이전에 사용자 공간에서 처리해야 했던 더 많은 기능을 포함하도록 확장되어 왔습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #292a2e; text-align: start;&quot; data-indent-level=&quot;1&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;사용자 공간으로부터의 디스플레이 제어 요청 처리&lt;/li&gt;
&lt;li&gt;프레임버퍼 관리&lt;/li&gt;
&lt;li&gt;페이지 플립(Page Flip), VBlank 이벤트 등 스케줄링&lt;/li&gt;
&lt;li&gt;멀티 디스플레이 환경 지원&lt;/li&gt;
&lt;li&gt;GPU 메모리 관리 및 버퍼 공유 (GEM, DMA-BUF)&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote style=&quot;background-color: #ffffff; color: #292a2e; text-align: start;&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-renderer-start-pos=&quot;1026&quot; data-ke-size=&quot;size16&quot;&gt;주 목적은 &lt;b&gt;렌더링 버퍼 관리, 화면 출력, VBlank 이벤트, atomic state 변경&lt;/b&gt;, 그리고 &lt;b&gt;플러그 앤 플레이 디스플레이 제어&lt;/b&gt;입니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p style=&quot;background-color: #ffffff; color: #292a2e; text-align: start;&quot; data-renderer-start-pos=&quot;1108&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 id=&quot;DRM-구성-요소-요약&quot; style=&quot;background-color: #ffffff; color: #292a2e; text-align: start;&quot; data-renderer-start-pos=&quot;1110&quot; data-ke-size=&quot;size23&quot;&gt;DRM 구성 요소 요약&lt;/h3&gt;
&lt;div style=&quot;background-color: #ffffff; color: #292a2e; text-align: start;&quot; data-testid=&quot;table-container&quot; data-layout=&quot;custom&quot;&gt;
&lt;div data-vc=&quot;table-node-wrapper&quot; data-table-width=&quot;760&quot; data-table-local-id=&quot;16058675-dd5e-4260-83e2-22cc1be8142e&quot; data-autosize=&quot;false&quot; data-layout=&quot;default&quot; data-number-column=&quot;false&quot;&gt;
&lt;p data-renderer-start-pos=&quot;1127&quot; data-ke-size=&quot;size16&quot;&gt;구성 요소&lt;/p&gt;
&lt;div&gt;
&lt;div style=&quot;background-color: #ffffff;&quot; aria-hidden=&quot;false&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-renderer-start-pos=&quot;1136&quot; data-ke-size=&quot;size16&quot;&gt;설명&lt;/p&gt;
&lt;div&gt;
&lt;div style=&quot;background-color: #ffffff;&quot; aria-hidden=&quot;false&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-layout=&quot;default&quot; data-table-width=&quot;760&quot; data-number-column=&quot;false&quot; data-testid=&quot;renderer-table&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;background-color: #ffffff; text-align: left;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; data-colwidth=&quot;285&quot;&gt;&lt;span&gt;&lt;b&gt;DRM Core&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;background-color: #ffffff; text-align: left;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; data-colwidth=&quot;474&quot;&gt;&lt;span&gt;/drivers/gpu/drm/drm*.c 등에서 구현. 공통 로직을 담당&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;background-color: #ffffff; text-align: left;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; data-colwidth=&quot;285&quot;&gt;&lt;span&gt;&lt;b&gt;DRM (Platform) Driver&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;background-color: #ffffff; text-align: left;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; data-colwidth=&quot;474&quot;&gt;&lt;span&gt;각 하드웨어에 특화된 드라이버 (예: i915, amdgpu, rockchip, exynos 등)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;background-color: #ffffff; text-align: left;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; data-colwidth=&quot;285&quot;&gt;&lt;span&gt;&lt;b&gt;DRM Helper&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;background-color: #ffffff; text-align: left;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; data-colwidth=&quot;474&quot;&gt;&lt;span&gt;공통된 코드 재사용을 위한 helper 함수 (예: drm_gem_cma_helper)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;background-color: #ffffff; text-align: left;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; data-colwidth=&quot;285&quot;&gt;&lt;span&gt;&lt;b&gt;DRM KMS (Kernel Mode Setting)&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;background-color: #ffffff; text-align: left;&quot; colspan=&quot;1&quot; rowspan=&quot;1&quot; data-colwidth=&quot;474&quot;&gt;&lt;span&gt;해상도, 모니터 제어, 플립 등을 위한 인터페이스&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;div data-vc=&quot;table-sticky-scrollbar-container&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;p style=&quot;background-color: #ffffff; color: #292a2e; text-align: start;&quot; data-renderer-start-pos=&quot;1421&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 id=&quot;2.-DRM-Software-Archtecture&quot; style=&quot;background-color: #ffffff; color: #292a2e; text-align: start;&quot; data-renderer-start-pos=&quot;1423&quot; data-ke-size=&quot;size26&quot;&gt;2. DRM Software Archtecture&lt;span&gt;&lt;span style=&quot;color: #505258;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p style=&quot;background-color: #ffffff; color: #292a2e; text-align: start;&quot; data-renderer-start-pos=&quot;1452&quot; data-ke-size=&quot;size16&quot;&gt;DRM은 Kernel Space에 존재하므로 유저 공간 프로그램은 Kernel의 System Call을 통해 DRM에 필요한 서비스를 요청해야 합니다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #292a2e; text-align: start;&quot; data-renderer-start-pos=&quot;1539&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #292a2e; text-align: start;&quot; data-renderer-start-pos=&quot;1541&quot; data-ke-size=&quot;size16&quot;&gt;DRM에서 감지한 각 GPU는 DRM 장치로 인식되며 디바이스 노드(/dev/dri/cardX)가 생성되어 이와 상호 작용 합니다. GPU와 통신하려는 유저 공간 프로그램은 디바이스 장치 파일을 열어 ioctl 호출을 사용하여 DRM과 통신해야 합니다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #292a2e; text-align: start;&quot; data-renderer-start-pos=&quot;1685&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #292a2e; text-align: start;&quot; data-renderer-start-pos=&quot;1687&quot; data-ke-size=&quot;size16&quot;&gt;libdrm은 Kernel의 &lt;b&gt;DRM드라이버를 사용하기 위한 user space 라이브러리(wrapper)&lt;/b&gt; 입니다. libdrm을 사용하면 커널 인터페이스가 사용자 공간에 직접 노출되는 것을 피할 수 있을 뿐만 아니라 프로그램 간에 코드를 재사용하고 공유할 수 있는 이점이 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;image-20250901-060040.png&quot; data-origin-width=&quot;1759&quot; data-origin-height=&quot;983&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/KCDtI/dJMcaaX9iUR/HdfbhXLH0pq2uyKyevtNIK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/KCDtI/dJMcaaX9iUR/HdfbhXLH0pq2uyKyevtNIK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/KCDtI/dJMcaaX9iUR/HdfbhXLH0pq2uyKyevtNIK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FKCDtI%2FdJMcaaX9iUR%2FHdfbhXLH0pq2uyKyevtNIK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1759&quot; height=&quot;983&quot; data-filename=&quot;image-20250901-060040.png&quot; data-origin-width=&quot;1759&quot; data-origin-height=&quot;983&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #292a2e; text-align: start;&quot; data-renderer-start-pos=&quot;1851&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #292a2e; text-align: start;&quot; data-renderer-start-pos=&quot;1851&quot; data-ke-size=&quot;size16&quot;&gt;위의 그림과 같이 DRM은 크게 두 부분으로 구성됩니다. 일반적인 Kernel의 DRM Core 와 각 유형의 지원 하드웨어에 대한 DRM (Platform) Driver 입니다. DRM Core는 다양한 DRM Driver가 등록할 수 있는 기본 프레임워크를 제공하고 사용자 공간에 공통적인 하드웨어 독립적인 기능을 갖춘 최소한의 ioctl 기능을 제공합니다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #292a2e; text-align: start;&quot; data-renderer-start-pos=&quot;2055&quot; data-ke-size=&quot;size16&quot;&gt;반면 DRM 드라이버는 지원하는 GPU 유형에 따라 특정 API의 하드웨어 종속 부분을 구현합니다. DRM 코어에서 다루지 않는 나머지 ioctl 구현을 제공해야 하지만 API를 확장하여 해당 하드웨어에서만 사용할 수 있는 추가 기능을 갖춘 추가 ioctl을 제공할 수도 있습니다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #292a2e; text-align: start;&quot; data-renderer-start-pos=&quot;2215&quot; data-ke-size=&quot;size16&quot;&gt;특정 DRM 드라이버가 향상된 API를 제공하는 경우 사용자 공간 libdrm도 추가 ioctl과 인터페이스 하기 위해 사용자 공간에서 사용할 수 있는 추가 라이브러리 libdrm-specific_driver 형태로 확장됩니다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #292a2e; text-align: start;&quot; data-renderer-start-pos=&quot;2344&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #292a2e; text-align: start;&quot; data-renderer-start-pos=&quot;2346&quot; data-ke-size=&quot;size16&quot;&gt;DRM Core는 사용자 공간 애플리케이션에 여러 인터페이스를 내보내며, 일반적으로 해당 래퍼 함수를 ​​통해 사용됩니다. 또한 드라이버는 ioctls 및 sysfs 파일을 통해 사용자 공간 드라이버 및 장치 인식 애플리케이션에서 사용할 수 있도록 장치별 인터페이스를 내보냅니다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #292a2e; text-align: start;&quot; data-renderer-start-pos=&quot;2505&quot; data-ke-size=&quot;size16&quot;&gt;외부 인터페이스에는 메모리 매핑, 컨텍스트 관리, DMA 작업, AGP 관리, vblank 제어, fence 관리, 메모리 관리 및 출력 관리가 포함됩니다.&lt;/p&gt;
&lt;h2 id=&quot;3.-Kernel-Mode-Setting-(KMS)&quot; style=&quot;background-color: #ffffff; color: #292a2e; text-align: start;&quot; data-renderer-start-pos=&quot;2594&quot; data-ke-size=&quot;size26&quot;&gt;3. Kernel Mode Setting (KMS)&lt;span&gt;&lt;span style=&quot;color: #505258;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p style=&quot;background-color: #ffffff; color: #292a2e; text-align: start;&quot; data-renderer-start-pos=&quot;2624&quot; data-ke-size=&quot;size16&quot;&gt;리눅스 그래픽 스택에서 &lt;b&gt;KMS (Kernel Mode Setting)&lt;/b&gt; 는 디스플레이 장치의 출력 모드를 설정하고 제어하는 핵심 기능입니다.&lt;br /&gt;여기서 모드(mode) 란 해상도(Resolution), 컬러 포맷(Color Format), 주사율(Refresh Rate) 등 디스플레이가 출력할 수 있는 상태를 의미합니다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #292a2e; text-align: start;&quot; data-renderer-start-pos=&quot;2803&quot; data-ke-size=&quot;size16&quot;&gt;즉, KMS는 GPU 장치가 &lt;b&gt;연결된 디스플레이가 지원하는 값 범위 내에서 올바른 모드&lt;/b&gt;를 선택하고, 이를 하드웨어 레벨에서 설정하는 역할을 합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;image-20250905-023631.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1064&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cnkhSY/dJMcac2GBBO/IizJP8H1Bir8BeSMKajr9k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cnkhSY/dJMcac2GBBO/IizJP8H1Bir8BeSMKajr9k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cnkhSY/dJMcac2GBBO/IizJP8H1Bir8BeSMKajr9k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcnkhSY%2FdJMcac2GBBO%2FIizJP8H1Bir8BeSMKajr9k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1920&quot; height=&quot;1064&quot; data-filename=&quot;image-20250905-023631.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1064&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #292a2e; text-align: start;&quot; data-renderer-start-pos=&quot;2904&quot; data-ke-size=&quot;size16&quot;&gt;과거에는 X.Org Server 또는 특정 그래픽 애플리케이션이 직접 하드웨어에 접근하여 모드를 설정했습니다.&lt;br /&gt;이 방식에는 두 가지 문제가 있었습니다:&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal; background-color: #ffffff; color: #292a2e; text-align: start;&quot; data-indent-level=&quot;1&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;보안 문제&lt;/b&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-indent-level=&quot;2&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;사용자 공간 프로그램이 직접 하드웨어를 제어하기 위해 루트 권한으로 실행되어야 했습니다.&lt;/li&gt;
&lt;li&gt;이는 안정성과 보안 측면에서 위험 요소가 많았습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;일관성 부족&lt;/b&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-indent-level=&quot;2&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;여러 애플리케이션이 각각 하드웨어를 제어하려고 하면 충돌이나 비정상적인 동작이 발생할 수 있었습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p style=&quot;background-color: #ffffff; color: #292a2e; text-align: start;&quot; data-renderer-start-pos=&quot;3161&quot; data-ke-size=&quot;size16&quot;&gt;이러한 문제를 해결하기 위해 &lt;b&gt;커널이 모드 설정을 담당(Kernel Mode Setting)&lt;/b&gt; 하도록 변경되었고,&lt;br /&gt;사용자 공간에서는 안전하게 &lt;b&gt;DRM(Direct Rendering Manager) 인터페이스&lt;/b&gt;를 통해 제어 명령을 전달하는 구조로 발전했습니다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #292a2e; text-align: start;&quot; data-renderer-start-pos=&quot;3303&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 id=&quot;KMS의-주요-구성-요소&quot; style=&quot;background-color: #ffffff; color: #292a2e; text-align: start;&quot; data-renderer-start-pos=&quot;3305&quot; data-ke-size=&quot;size23&quot;&gt;KMS의 주요 구성 요소&lt;span&gt;&lt;span style=&quot;color: #505258;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #292a2e; text-align: start;&quot; data-renderer-start-pos=&quot;3320&quot; data-ke-size=&quot;size16&quot;&gt;KMS는 단일 하드웨어 블록이 아니라, 디스플레이 파이프라인을 구성하는 여러 요소의 조합으로 동작합니다. DRM 드라이버는 일반적으로 다음 세 가지 주요 객체를 관리합니다:&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal; background-color: #ffffff; color: #292a2e; text-align: start;&quot; data-indent-level=&quot;1&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;CRTC&lt;/b&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-indent-level=&quot;2&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;프레임 버퍼 메모리에서 픽셀 데이터를 읽어와 화면에 출력하는 역할&lt;/li&gt;
&lt;li&gt;스캔아웃(scanout) 동작을 담당하며, vsync와 같은 타이밍 제어를 관리&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Encoder&lt;/b&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-indent-level=&quot;2&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;CRTC에서 출력된 데이터를 특정 디스플레이 신호 형식(HDMI, DisplayPort, DVI 등)으로 변환&lt;/li&gt;
&lt;li&gt;하나의 CRTC는 여러 Encoder와 연결될 수 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Connector&lt;/b&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-indent-level=&quot;2&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;실제 물리적인 디스플레이 장치(모니터, 패널 등)에 연결되는 지점&lt;/li&gt;
&lt;li&gt;EDID(Extended Display Identification Data)를 읽어 디스플레이가 지원하는 모드를 파악&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p style=&quot;background-color: #ffffff; color: #292a2e; text-align: start;&quot; data-renderer-start-pos=&quot;3754&quot; data-ke-size=&quot;size16&quot;&gt;이 세 가지 객체를 조합하여 커널은 &lt;b&gt;'어떤 프레임 버퍼를 어떤 방식으로 어떤 출력 장치에 보여줄 것인가'&lt;/b&gt;를 결정하게 됩니다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #292a2e; text-align: start;&quot; data-renderer-start-pos=&quot;3825&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #292a2e; text-align: start;&quot; data-renderer-start-pos=&quot;3827&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #292a2e; text-align: start;&quot; data-renderer-start-pos=&quot;3829&quot; data-ke-size=&quot;size16&quot;&gt;이번 글에서는 DRM과 KMS의 기본 개념과 필요성, 그리고 주요 객체(CRTC/Encoder/Connector)의 역할을 살펴보았습니다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #292a2e; text-align: start;&quot; data-renderer-start-pos=&quot;3909&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #292a2e; text-align: start;&quot; data-renderer-start-pos=&quot;3911&quot; data-ke-size=&quot;size16&quot;&gt;다음 글에서는 이 추상화 구조가 실제 SoC에서 어떻게 매핑 되는지, 그리고 Simple Pipe와 전통적인 구현 방식이 어떻게 다른지 구체적으로 다루어 보겠습니다.&lt;/p&gt;</description>
      <category>System Programming/Linux Device Driver</category>
      <author>줄람이</author>
      <guid isPermaLink="true">https://julrams.tistory.com/47</guid>
      <comments>https://julrams.tistory.com/47#entry47comment</comments>
      <pubDate>Tue, 16 Dec 2025 12:17:19 +0900</pubDate>
    </item>
    <item>
      <title>CRC16/32 &amp;amp; Checksum C언어 코드</title>
      <link>https://julrams.tistory.com/43</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;간단한 CRC 체크를 위한 함수는 아래와 같습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CRC Check할 데이터의 address(pointer) 및 data length를 parameter로 crc 및 checksum 값을 확인할 수 있습니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;- crc.h&lt;/h4&gt;
&lt;pre id=&quot;code_1731571010276&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#ifndef CRC_H
#define CRC_H

#include &amp;lt;stdint.h&amp;gt;
#include &amp;lt;stddef.h&amp;gt;

//EDB88320 Table
static const uint32_t crc32_table[256] = {
    0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
    0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
    0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
    0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
    0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
    0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
    0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
    0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
    0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
    0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
    0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
    0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
    0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
    0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
    0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
    0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
    0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
    0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
    0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
    0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
    0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
    0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
    0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
    0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
    0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
    0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,
    0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
    0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
    0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
    0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
    0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
    0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
};

uint32_t crc32(const uint8_t *data, size_t length);

unsigned short crc16_ccitt( const void *buf, int len);
uint8_t calculate_checksum(const uint8_t *data, uint16_t length);

#endif&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;- crc.c&amp;nbsp;&lt;/h4&gt;
&lt;pre id=&quot;code_1731570972766&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;crc.h&amp;gt;

uint32_t crc32(const uint8_t *data, size_t length) {
    uint32_t crc = 0xFFFFFFFF;
    for (size_t i = 0; i &amp;lt; length; i++) {
        uint8_t byte = data[i];
        uint32_t table_index = (crc ^ byte) &amp;amp; 0xFF;
        crc = (crc &amp;gt;&amp;gt; 8) ^ crc32_table[table_index];
    }
    return crc ^ 0xFFFFFFFF;
}

unsigned short crc16_ccitt( const void *buf, int len )
{
	unsigned short crc = 0;
	while( len-- ) {
		int i;
		crc ^= *(char *)buf++ &amp;lt;&amp;lt; 8;
		for( i = 0; i &amp;lt; 8; ++i ) {
			if( crc &amp;amp; 0x8000 )
				crc = (crc &amp;lt;&amp;lt; 1) ^ 0x1021;
			else
				crc = crc &amp;lt;&amp;lt; 1;
		}
	}
	return crc;
}

uint8_t calculate_checksum(const uint8_t *data, uint16_t length) {
    uint8_t checksum = 0;
    while (length--) {
        checksum += *data++;
    }
    return checksum;
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Programming Language/C&amp;amp;C++</category>
      <category>checksum</category>
      <category>crc code</category>
      <category>CRC16</category>
      <category>CRC32</category>
      <author>줄람이</author>
      <guid isPermaLink="true">https://julrams.tistory.com/43</guid>
      <comments>https://julrams.tistory.com/43#entry43comment</comments>
      <pubDate>Thu, 14 Nov 2024 16:59:14 +0900</pubDate>
    </item>
    <item>
      <title>XMODEM Protocol</title>
      <link>https://julrams.tistory.com/42</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;- XMODEM&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;XMODEM은 시리얼 통신 매체를 활용하여 CP/M 플로피 디스크에 사용된 기본 블록 크기인 128Byte를 채택해 128byte의 데이터 단위 전송 및 프로토콜 규약으로 당시 모뎀을 통한 파일 전송을 보다 쉽게 만들기 위해 탄생했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;XMODEM은 간단하면서도 신뢰성 있는 데이터 전송방식을 제공하여, 이후 YMODEM, ZMODEM 같은 확장 프로토콜이 탄생할 수 있는 기초가 되었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #202122; text-align: start;&quot;&gt;대부분의 파일 전송 프로토콜과 같이 XMODEM은 원래의 데이터를 일련의&lt;span&gt;&amp;nbsp;패킷&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #202122; text-align: start;&quot;&gt;으로 쪼개어 수신자에게 보내며 여기에 추가 정보를 담고 있어서 수신자가 어느 패킷을 올바르게 받았는지를 결정할 수 있게 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #202122;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;128Byte 프로토콜에서 1Kbyte 형태로 발전하기도 했으며, Checksum 이외에 CRC16 형태로 확장되기도 하여 각 상황 및 설정에 맞춰 통신을 할 수 있도록 설계되어야 합니다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이번 글에서는 XMODEM 프로토콜의 작동 방식과 패킷 구조, 전송 흐름을 알아보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;- XMODEM 프로토콜의 기본 개념&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;XMODEM은 &lt;b&gt;양방향 통신을 기반으로 하는 오류 검출 방식&lt;/b&gt;을 채택하여 데이터를 전송합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;특히 &lt;b&gt;종단 간 오류 제어&lt;/b&gt;를 위해 체크섬(Checksum) 방식이 사용됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;데이터 전송 시 오류가 발생하면 수신 측에서 오류 패킷을 다시 요청하여 재전송하는 방식으로 파일의 신뢰성을 유지합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;XMODEM은 전송 중 패킷 손실이나 손상된 데이터를 감지할 수 있어 당시 모뎀 환경에서 매우 유용했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;- Data Packet Structure&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;XMODEM 패킷은 128바이트 크기의 고정된 데이터 블록으로 이루어져 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;각 패킷은 다음과 같은 형식으로 구성됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;SOH (Start of Header)&lt;/b&gt;: 1바이트, 패킷의 시작을 나타내며 ASCII 코드 0x01로 표시됩니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;블록 번호&lt;/b&gt;: 1바이트, 현재 패킷의 순서를 표시합니다. 0부터 시작하여 1씩 증가하며, 255를 넘어가면 다시 0으로 돌아갑니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;블록 번호의 보수&lt;/b&gt;: 1바이트, 블록 번호의 보수를 저장하여 오류를 검증하는 데 사용됩니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;데이터&lt;/b&gt;: 128바이트의 실제 데이터 내용입니다. 파일의 마지막 패킷에서는 부족한 바이트를 0x1A(EOF 문자)로 채웁니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;체크섬&lt;/b&gt;: 1바이트, 오류 검출을 위한 값으로, 데이터 필드의 모든 바이트의 합을 1바이트로 나타냅니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Checksum 과 CRC16 프로토콜의 차이는 Data Packet 이후 에러 검출을 위하여 Checksum 1 byte 또는 CRC16의 2 byte 에 따른 데이터 끝부분의 차이가 존재합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 기본 패킷(Checksum)&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 20%;&quot;&gt;SOH&lt;/td&gt;
&lt;td style=&quot;width: 20%;&quot;&gt;Packet&lt;br /&gt;Number&lt;/td&gt;
&lt;td style=&quot;width: 20%;&quot;&gt;1's Compliment of&lt;br /&gt;Packet Number&lt;/td&gt;
&lt;td style=&quot;width: 20%;&quot;&gt;Data Packet&lt;/td&gt;
&lt;td style=&quot;width: 20%;&quot;&gt;Checksum&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 20%;&quot;&gt;1 Byte&lt;/td&gt;
&lt;td style=&quot;width: 20%;&quot;&gt;1 Byte&lt;/td&gt;
&lt;td style=&quot;width: 20%;&quot;&gt;1 Byte&lt;/td&gt;
&lt;td style=&quot;width: 20%;&quot;&gt;128 Byte&lt;/td&gt;
&lt;td style=&quot;width: 20%;&quot;&gt;1 Byte&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- CRC16 패킷&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 20%;&quot;&gt;SOH&lt;/td&gt;
&lt;td style=&quot;width: 20%;&quot;&gt;Packet&lt;br /&gt;Number&lt;/td&gt;
&lt;td style=&quot;width: 20%;&quot;&gt;1's Compliment of&lt;br /&gt;Packet Number&lt;/td&gt;
&lt;td style=&quot;width: 20%;&quot;&gt;Data Packet&lt;/td&gt;
&lt;td style=&quot;width: 20%;&quot;&gt;Checksum&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 20%;&quot;&gt;1 Byte&lt;/td&gt;
&lt;td style=&quot;width: 20%;&quot;&gt;1 Byte&lt;/td&gt;
&lt;td style=&quot;width: 20%;&quot;&gt;1 Byte&lt;/td&gt;
&lt;td style=&quot;width: 20%;&quot;&gt;128 Byte&lt;/td&gt;
&lt;td style=&quot;width: 20%;&quot;&gt;2 Byte&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;- Transfer flow&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;XMODEM 프로토콜은 간단하지만 규칙적인 전송 과정을 따릅니다. 송신 측과 수신 측이 데이터를 주고받는 과정을 단계별로 살펴보겠습니다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;전송 시작 신호&lt;/b&gt;: 수신 측이 준비되면 ASCII 코드 0x15(NAK) 또는 0x43(C)을 송신 측으로 보내 파일 전송을 시작합니다. 이를 통해 송신 측은 수신 측이 준비되었음을 알 수 있습니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;데이터 패킷 전송&lt;/b&gt;: 송신 측은 각 데이터 블록을 패킷 구조에 맞추어 순차적으로 전송합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;ACK/NAK 확인&lt;/b&gt;: 수신 측은 패킷을 수신한 후 체크섬을 확인합니다. 오류가 없는 경우 ACK(0x16) 신호를, 오류가 있는 경우 NAK 신호를 송신 측에 보냅니다. NAK(0x15) 신호를 받으면 송신 측은 해당 패킷을 다시 전송합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;파일 전송 완료&lt;/b&gt;: 모든 데이터 패킷 전송이 완료되면 송신 측은 EOT(End of Transmission) 신호를 보내 파일 전송을 마무리합니다. 수신 측이 EOT(0x04) 신호를 확인하면 전송이 끝났음을 인지하게 됩니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;아래의 표와 같이 위에 설명한 수신 측에서 CRC의 경우 0x43('C')를 전송하여 전송측에 전송 요청을 보내어 통신 시작 및 싱크를 맞춰 진행합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;CRC 방식이 아닌 Checksum의 경우 0x15(NAK)를 보내어 시작합니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;전송 측으로 전달된 첫 패킷을 수신측에서 제대로 수신할 수 없는 경우 Checksum에서는 0x15(NAK)를 보내지만 CRC의 경우 0x43('C') 값을 보내야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;해당 상황에서 CRC 전송에서 첫 패킷에 0x15(NAK)를 보내게 될 경우 Tera Term 등의 프로토콜에서는 자동으로 Checksum으로 전환되니 해당 시퀀스에 대해 주의해야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;951&quot; data-origin-height=&quot;679&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cAdvUJ/btsKv6uBQ7T/jUjJ0lHCnAiZXFbTe6xZ8K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cAdvUJ/btsKv6uBQ7T/jUjJ0lHCnAiZXFbTe6xZ8K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cAdvUJ/btsKv6uBQ7T/jUjJ0lHCnAiZXFbTe6xZ8K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcAdvUJ%2FbtsKv6uBQ7T%2FjUjJ0lHCnAiZXFbTe6xZ8K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;951&quot; height=&quot;679&quot; data-origin-width=&quot;951&quot; data-origin-height=&quot;679&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;전송 시작 이후 SOH 와 각 Data Format에 맞춰 파일 데이터를 수신하며 Checksum 또는 CRC 패킷을 통해 Data 오류 검출 및 정합성을 확인하여 파일 데이터를 수신하고 EOT를 수신하게 되면 통신이 모두 종료되게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;결론&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;XMODEM은 초기 파일 전송 프로토콜로서 통신 기술 발전에 중요한 기여를 했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이 프로토콜은 기본적인 오류 검출 기능을 통해 파일 전송의 신뢰성을 보장하며, 데이터 통신의 기초 개념을 잘 보여줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;XMODEM을 이해하면, 이후 발전한 다양한 프로토콜의 배경과 원리를 쉽게 이해할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이상으로 XMODEM의 개념과 작동 방식을 알아보았습니다.&lt;/p&gt;</description>
      <category>System Programming/Tips</category>
      <category>xmodem</category>
      <category>xmodem 전송</category>
      <category>xmodem 프로토콜</category>
      <author>줄람이</author>
      <guid isPermaLink="true">https://julrams.tistory.com/42</guid>
      <comments>https://julrams.tistory.com/42#entry42comment</comments>
      <pubDate>Mon, 4 Nov 2024 18:09:59 +0900</pubDate>
    </item>
    <item>
      <title>CMSIS USART XMODEM Code</title>
      <link>https://julrams.tistory.com/40</link>
      <description>&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;#include &quot;Driver_USART.h&quot;
#include &quot;xmodem_lib.h&quot;
#include &quot;crc.h&quot;

#define PACKET_SIZE 128

extern ARM_DRIVER_USART Driver_USART0;
static ARM_DRIVER_USART *USARTdrv = &amp;amp;Driver_USART0;

static const uint8_t SOH = 0x01;
static const uint8_t EOT = 0x04;
static const uint8_t ACK = 0x06;
static const uint8_t NAK = 0x15;

#ifdef XMODEM_CRC16
static uint8_t rx_buffer[PACKET_SIZE + 5]; // SOH, Block, ~Block, Data[128], CRC[2]
static const uint8_t SELC = 0x43;
#else
static uint8_t rx_buffer[PACKET_SIZE + 4]; // SOH, Block, ~Block, Data[128], checksum
#endif

void USART_Callback(uint32_t event) {
    // Handle USART events here
}

void XMODEM_Init(void) {
    USARTdrv-&amp;gt;Initialize(USART_Callback);
    USARTdrv-&amp;gt;PowerControl(ARM_POWER_FULL);
    USARTdrv-&amp;gt;Control(ARM_USART_MODE_ASYNCHRONOUS |
                      ARM_USART_DATA_BITS_8 |
                      ARM_USART_PARITY_NONE |
                      ARM_USART_STOP_BITS_1 |
                      ARM_USART_FLOW_CONTROL_NONE, 115200);
    USARTdrv-&amp;gt;Control(ARM_USART_CONTROL_RX, 0);
}

unsigned short crc16_ccitt( const void *buf, int len )
{
	unsigned short crc = 0;
	while( len-- ) {
		int i;
		crc ^= *(char *)buf++ &amp;lt;&amp;lt; 8;
		for( i = 0; i &amp;lt; 8; ++i ) {
			if( crc &amp;amp; 0x8000 )
				crc = (crc &amp;lt;&amp;lt; 1) ^ 0x1021;
			else
				crc = crc &amp;lt;&amp;lt; 1;
		}
	}
	return crc;
}

uint8_t calculate_checksum(const uint8_t *data, uint16_t length) {
    uint8_t checksum = 0;
    while (length--) {
        checksum += *data++;
    }
    return checksum;
}

int XMODEM_Receive(uint8_t *data, uint32_t length) {
    uint8_t block_number = 1, started = 0;
    uint32_t received = 0, timeout = 0;
    uint32_t count;

    //Clear RXFIFO
    while (USARTdrv-&amp;gt;GetRxCount() &amp;gt; 0) {
        uint8_t dummy;
        USARTdrv-&amp;gt;Receive(&amp;amp;dummy, 1);
    }

#ifdef XMODEM_CRC16
    USARTdrv-&amp;gt;Send(&amp;amp;SELC, 1);
#else
    USARTdrv-&amp;gt;Send(&amp;amp;ACK, 1);
#endif
    
    while (received &amp;lt; length) {
        memset(rx_buffer, 0x0, sizeof(rx_buffer));
        USARTdrv-&amp;gt;Receive(rx_buffer, sizeof(rx_buffer));
        count = USARTdrv-&amp;gt;GetRxCount();
        if((!started) &amp;amp;&amp;amp; (count &amp;gt; 0))
            started = 1;
        // Wait for data reception to complete
        // Implement timeout handling here

        if (rx_buffer[0] == SOH &amp;amp;&amp;amp; rx_buffer[1] == block_number &amp;amp;&amp;amp; rx_buffer[2] == (uint8_t)~block_number) {
#ifdef XMODEM_CRC16
            uint16_t crc_received = (rx_buffer[PACKET_SIZE + 3] &amp;lt;&amp;lt; 8) | rx_buffer[PACKET_SIZE + 4];
            uint16_t crc_calculated = crc16_ccitt(&amp;amp;rx_buffer[3], PACKET_SIZE);
            if (crc_received == crc_calculated) {
#else
            uint8_t checksum_received = rx_buffer[PACKET_SIZE + 3];
            uint8_t checksum_calculated = calculate_checksum(&amp;amp;rx_buffer[3], PACKET_SIZE);
            if (checksum_received == checksum_calculated) {
#endif
                memcpy(&amp;amp;data[received], &amp;amp;rx_buffer[3], PACKET_SIZE);
                received += PACKET_SIZE;
                started = 1;
                block_number++;
                USARTdrv-&amp;gt;Send(&amp;amp;ACK, 1);
                timeout = 0;
            } else {
                if(block_number == 1)
                    USARTdrv-&amp;gt;Send(&amp;amp;SELC, 1);
                else
                    USARTdrv-&amp;gt;Send(&amp;amp;NAK, 1);
            }
        } else if (rx_buffer[0] == EOT) {
            USARTdrv-&amp;gt;Send(&amp;amp;ACK, 1);
            break;
        } else {
            //Clear Read Buffer For Packet align
            if(count &amp;gt; 0) {
                do {
                    USARTdrv-&amp;gt;Receive(rx_buffer, sizeof(rx_buffer));
                } while (USARTdrv-&amp;gt;GetRxCount());
            }
#ifdef XMODEM_CRC16
            if(block_number == 1)
                    USARTdrv-&amp;gt;Send(&amp;amp;SELC, 1);
            else
#endif
                USARTdrv-&amp;gt;Send(&amp;amp;NAK, 1);
            
            if(started &amp;amp;&amp;amp; timeout &amp;gt; 15) {
                block_number = 1;
                received = 0;
                started = 0;
                timeout = 0;
            } else if (started) {
                timeout++;
            }
        }
    }

    return received;
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Programming Language/C&amp;amp;C++</category>
      <author>줄람이</author>
      <guid isPermaLink="true">https://julrams.tistory.com/40</guid>
      <comments>https://julrams.tistory.com/40#entry40comment</comments>
      <pubDate>Tue, 29 Oct 2024 17:50:23 +0900</pubDate>
    </item>
    <item>
      <title>ARM aarch64 Ubuntu 22.04 Base Rootfs 작업 &amp;amp; 설치</title>
      <link>https://julrams.tistory.com/39</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;ARM aarch64 System에서 Ubuntu 22.04 Base Rootfs 작업을 위해서는 하기와 같은 작업을 통해 진행해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;작업을 할 Host PC에는 Qemu 명령이 설치 되어 있어야 하고 없다면 하기 명령을 통해 미리 설치해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1722566309976&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sudo apt update -y
sudo apt install -y qemu-user-static qemu-aarch64-static&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Ubuntu-Base 22.04 등의 Release 버전은 하기의 링크에서 다운로드가 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://cdimage.ubuntu.com/ubuntu-base/releases/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://cdimage.ubuntu.com/ubuntu-base/releases/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1722566430382&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Index of /ubuntu-base/releases&quot; data-og-description=&quot;&quot; data-og-host=&quot;cdimage.ubuntu.com&quot; data-og-source-url=&quot;https://cdimage.ubuntu.com/ubuntu-base/releases/&quot; data-og-url=&quot;https://cdimage.ubuntu.com/ubuntu-base/releases/&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://cdimage.ubuntu.com/ubuntu-base/releases/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://cdimage.ubuntu.com/ubuntu-base/releases/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Index of /ubuntu-base/releases&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;cdimage.ubuntu.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1061&quot; data-origin-height=&quot;895&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cA4Ieb/btsITtkj9lp/oMhKmCjYo3MtmtCmvaGTEk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cA4Ieb/btsITtkj9lp/oMhKmCjYo3MtmtCmvaGTEk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cA4Ieb/btsITtkj9lp/oMhKmCjYo3MtmtCmvaGTEk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcA4Ieb%2FbtsITtkj9lp%2FoMhKmCjYo3MtmtCmvaGTEk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1061&quot; height=&quot;895&quot; data-origin-width=&quot;1061&quot; data-origin-height=&quot;895&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 해당 사이트를 통해 'ubuntu-base-22.04-base-amd64.tar.gz' 를 다운로드 한 것을 가정으로 작업 방법에 대해 설명한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다운로드 이후 하기의 명령과 같이 ubuntu_base 디렉토리를 생성 후 압축 파일을 해제하여 작업할 영역을 생성해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;chroot 명령을 통해 aarch64 시스템을 사용해야 하기 때문에 'qemu-aarch64-static' 또한 root filesystem의 bin 안에 qemu-aarch64-static을 복사해준다.&lt;/p&gt;
&lt;pre id=&quot;code_1722566710267&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;mkdir -p ./ubuntu_base
tar zxvf ubuntu-base-22.04-base-amd64.tar.gz -C ubuntu_base
sudo cp /usr/bin/qemu-aarch64-static ./ubuntu_base/bin/qemu-aarch64-static&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ubuntu_base Filesystem이 생성되면 작업 시 사용할 proc 및 sysfs 등을 mount 해주어야 하는데 하기의 스크립트를 통해&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;chroot 이전에 mount/umount 작업을 진행할 수 있도록 준비한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;#mnt_ubuntu.sh&lt;/p&gt;
&lt;pre id=&quot;code_1722566576206&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#!/bin/bash
mnt() {
    echo &quot;MOUNTING&quot;
    sudo mount -t proc /proc ${2}proc
    sudo mount -t sysfs /sys ${2}sys
    sudo mount -o bind /dev ${2}dev
    sudo mount -o bind /dev/pts ${2}dev/pts
    sudo chroot ${2}
}
umnt() {
    echo &quot;UNMOUNTING&quot;
    sudo umount ${2}proc
    sudo umount ${2}sys
    sudo umount ${2}dev/pts
    sudo umount ${2}dev
}

if [ &quot;$1&quot; == &quot;-m&quot; ] &amp;amp;&amp;amp; [ -n &quot;$2&quot; ] ;
then
    mnt $1 $2
elif [ &quot;$1&quot; == &quot;-u&quot; ] &amp;amp;&amp;amp; [ -n &quot;$2&quot; ];
then
    umnt $1 $2
else
    echo &quot;&quot;
    echo &quot;Either 1'st, 2'nd or both parameters were missing&quot;
    echo &quot;&quot;
    echo &quot;1'st parameter can be one of these: -m(mount) OR -u(umount)&quot;
    echo &quot;2'nd parameter is the full path of rootfs directory(with trailing '/')&quot;
    echo &quot;&quot;
    echo &quot;For example: ch-mount -m /media/sdcard/&quot;
    echo &quot;&quot;
    echo 1st parameter : ${1}
    echo 2nd parameter : ${2}
fi&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 스크립트 실행 방법은 './mnt_ubuntu.sh -m ./ubuntu_base' './mnt_ubuntu.sh -u ./ubuntu_base' 와 같이 작업 시작 전에 '-m' 을 통해 mount 후 작업 완료 시 '-u'를 통해 umount 작업을 진행한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ubuntu base 작업 이전에 dns 등 network 환경을 잡아주기 위하여 하기와 같이 resolv.conf를 복사해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1722567757062&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;cp -vrfp /etc/resolv.conf ubuntu_base/etc/resolv.conf&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또는 하기와 같이 nameserver를 8.8.8.8로 설정하여 google nameserver를 활용한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;982&quot; data-origin-height=&quot;288&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/0r8Zq/btsITV1NEJz/ekjcEA1VO8YLqkMr6Jqly0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/0r8Zq/btsITV1NEJz/ekjcEA1VO8YLqkMr6Jqly0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/0r8Zq/btsITV1NEJz/ekjcEA1VO8YLqkMr6Jqly0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F0r8Zq%2FbtsITV1NEJz%2FekjcEA1VO8YLqkMr6Jqly0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;982&quot; height=&quot;288&quot; data-origin-width=&quot;982&quot; data-origin-height=&quot;288&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같은 네트워크 환경까지 준비가 되면 하기의 명령을 통해 chroot을 진행하여 filesystem 작업을 진행한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1722568062110&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;chmod a+x mnt_ubuntu.sh
./mnt_ubuntu.sh -m ubuntu_base/&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 명령을 진행하면 ubuntu_base 디렉토리를 기준으로 chroot가 진행되어야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정상적으로 전환이 완료되었다면 하기와 같은 필수 유틸을 설치하고 필요한 명령 및 패키지가 있다면 apt를 통해 설치를 해준다.&lt;/p&gt;
&lt;pre id=&quot;code_1722568387723&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;chmod 777 /tmp
apt update -y
apt install -y systemd
apt install -y vim htop
apt install -y net-tools ethtool ifupdown udhcpc ssh iputils-ping rsyslog&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이와 더불어 추가적으로 ttyS0 등의 getty 로그인이 필요하다면 하기의 내용을 토대로&lt;br /&gt;'./etc/systemd/system/getty.target.wants/getty@ttyS0.service' 경로에 파일을 추가해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1722568846785&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#  SPDX-License-Identifier: LGPL-2.1-or-later
#
#  This file is part of systemd.
#
#  systemd is free software; you can redistribute it and/or modify it
#  under the terms of the GNU Lesser General Public License as published by
#  the Free Software Foundation; either version 2.1 of the License, or
#  (at your option) any later version.

[Unit]
Description=Getty on %I
Documentation=man:agetty(8) man:systemd-getty-generator(8)
Documentation=http://0pointer.de/blog/projects/serial-console.html
After=systemd-user-sessions.service plymouth-quit-wait.service getty-pre.target
After=rc-local.service

# If additional gettys are spawned during boot then we should make
# sure that this is synchronized before getty.target, even though
# getty.target didn't actually pull it in.
Before=getty.target
IgnoreOnIsolate=yes

# IgnoreOnIsolate causes issues with sulogin, if someone isolates
# rescue.target or starts rescue.service from multi-user.target or
# graphical.target.
Conflicts=rescue.service
Before=rescue.service

# On systems without virtual consoles, don't start any getty. Note
# that serial gettys are covered by serial-getty@.service, not this
# unit.
ConditionPathExists=/dev/tty0

[Service]
# the VT is cleared by TTYVTDisallocate
# The '-o' option value tells agetty to replace 'login' arguments with an
# option to preserve environment (-p), followed by '--' for safety, and then
# the entered username.
ExecStart=-/sbin/agetty -o '-p -- \\u' --noclear %I $TERM
Type=idle
Restart=always
RestartSec=0
UtmpIdentifier=%I
TTYPath=/dev/%I
TTYReset=yes
TTYVHangup=yes
TTYVTDisallocate=yes
IgnoreSIGPIPE=no
SendSIGHUP=yes

# Unset locale for the console getty since the console has problems
# displaying some internationalized messages.
UnsetEnvironment=LANG LANGUAGE LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT LC_IDENTIFICATION

[Install]
WantedBy=getty.target
DefaultInstance=ttyS0&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 과정이 완료되면, 하기와 같이 'exit' 명령을 통해 chroot를 종료한다. 그 후 이전에 mount 한 proc 등 sysfs 를 스크립트를 실행하여 종료한다.&lt;/p&gt;
&lt;pre id=&quot;code_1722568548320&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;./mnt_ubuntu.sh -u ubuntu_base/&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한, 사용할 이미지에 이미 넣어두었던 qemu 파일을 aarch64 시스템에서는 필요하지 않으므로 삭제해준다.&lt;/p&gt;
&lt;pre id=&quot;code_1722568616876&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;rm -rf ./ubuntu_base/bin/qemu-aarch64-static&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 작업이 완료되었다면 다시 ubuntu_base 디렉토리로 이동하여 '/' 경로에서 압축을 진행해주어 파일시스템 만드는 것을 완료한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1722568704516&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;cd ubuntu_base
tar zcvf ubuntu_base.tar.gz *
mv ubuntu_base.tar.gz ../
cd -&lt;/code&gt;&lt;/pre&gt;</description>
      <category>System Programming/Linux Kernel</category>
      <author>줄람이</author>
      <guid isPermaLink="true">https://julrams.tistory.com/39</guid>
      <comments>https://julrams.tistory.com/39#entry39comment</comments>
      <pubDate>Fri, 2 Aug 2024 12:21:55 +0900</pubDate>
    </item>
    <item>
      <title>ARM64(AArch64) Page Table Normal Memory Attribute</title>
      <link>https://julrams.tistory.com/38</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;AArch64(ARMv8) Page Table의 Normal Memory에 대한 속성에 대하여 설명하겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;메모리 영역에 대하여 속성들(ex.&lt;span style=&quot;background-color: #ffffff; color: #242424; text-align: start;&quot;&gt; memory type, cacheability, shareability...)은 해당 메모리 영역과 관련되어 속성에 의해 제어됩니다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242424; text-align: start;&quot;&gt;Normal Memory는 일반적으로 페이지로 구성 및 나누어지고 Page Table을 탐색하도록 구현된 프로세서의 하드웨어 메커니즘에 의해 접근됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242424; text-align: start;&quot;&gt;각각의 메모리 접근은 Page Table Entry와 관련된 Attribute(속성)에 의해 제어되고 제한됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #ffffff; color: #242424; text-align: start;&quot;&gt;- Table Descriptors&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #242424;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;이 글에서는 다양한 페이지 테이블 항목의 형식에 대해 설명합니다. 빠른 참조를 위해 Format 형식을 상단에 배치해두겠습니다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #242424;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;페이지 테이블의 테이블 디스크립터 항목은 비트[1:0]가 0b11이며, AArch64에서 Stage 3까지 지원하기에 Stage 3의 descriptor 형식은 0b11이 될 수 없습니다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #242424;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;- Table descriptor format&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;726&quot; data-origin-height=&quot;295&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/DLlyS/btsFgqeJMQT/uVWkbVUbyKZUWn8slvLO8K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/DLlyS/btsFgqeJMQT/uVWkbVUbyKZUWn8slvLO8K/img.png&quot; data-alt=&quot;AArch64 Page Table Descriptor Type (TG Size 4KB)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/DLlyS/btsFgqeJMQT/uVWkbVUbyKZUWn8slvLO8K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FDLlyS%2FbtsFgqeJMQT%2FuVWkbVUbyKZUWn8slvLO8K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;726&quot; height=&quot;295&quot; data-origin-width=&quot;726&quot; data-origin-height=&quot;295&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;AArch64 Page Table Descriptor Type (TG Size 4KB)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;- Table descriptor attributes&lt;/b&gt;&lt;/h2&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div data-message-model-slug=&quot;gpt-4o&quot; data-message-id=&quot;5d0c223a-3f5b-4583-b85d-894e1ff80683&quot; data-message-author-role=&quot;assistant&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Stage 2 테이블 디스크립터에는 속성 필드가 포함되지 않음을 유의하세요. 다음 표는 Stage 1 테이블 항목에 연결된 속성을 설명합니다.&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;802&quot; data-origin-height=&quot;190&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Gf800/btsKfxGNBsy/HD1NOPZIKyKLYcmrwqfOP1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Gf800/btsKfxGNBsy/HD1NOPZIKyKLYcmrwqfOP1/img.png&quot; data-alt=&quot;AArch Page Table descriptor attributes&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Gf800/btsKfxGNBsy/HD1NOPZIKyKLYcmrwqfOP1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FGf800%2FbtsKfxGNBsy%2FHD1NOPZIKyKLYcmrwqfOP1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;802&quot; height=&quot;190&quot; data-origin-width=&quot;802&quot; data-origin-height=&quot;190&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;AArch Page Table descriptor attributes&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&amp;nbsp;NSTable&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이 비트는 디스크립터의 테이블 식별자가 보안 상태(Secure state)에서의 접근을 위해 보안 PA(Secure PA) 공간(NSTable == 0) 또는 Non-Secure(NSTable == 1) 메모리에 위치하는지를 나타냅니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;NSTable이 1이면, 후속 조회되는 하위 페이지 또는 블록 디스크립터의 NS 비트 값은 무시되며 참조된 블록이나 페이지는 비보안 메모리에 속하게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;또한, 이후 조회된 테이블에서의 NSTable 값도 무시되며 이러한 테이블 항목들은 비보안 메모리를 참조합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;추가적으로, 보안 상태에서 가져온 항목은 nG == 1(non-global)로 간주됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;참고: NSTable 비트의 설정은 변환 테이블 탐색의 모든 후속 조회에 적용됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&amp;nbsp;APTable&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;APTable 비트는 변환의 한 단계에서 이후 조회되는 항목들에 대한 권한을 설정합니다. 이는 동일한 변환 단계 내에서 적용됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Secure EL3 및 Non-Secure EL2의 경우&amp;nbsp; &lt;span style=&quot;font-size: 1.12em; letter-spacing: 0px;&quot;&gt;APTable 비트 0이 RES0로 설정되어 비트 1만 유효합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;APTable[1:0]이 0b1x로 설정되면, 이후 레벨 조회의 권한과 상관없이 모든 예외 레벨에서 쓰기 권한이 허용되지 않습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;여러 단계 변환이 있는 TR(Translation Regimes)에서는 APTable이 Stage 1 변환 제어만 담당합니다. Stage 2 디스크립터의 경우, APTable 비트가 RES0로 설정되어 하드웨어가 해당 값을 무시합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;여러 예외 레벨 변환 체제를 위한 APTable 비트의 전체 설명은 다음과 같습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;787&quot; data-origin-height=&quot;214&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/STIxW/btsKfGjhPji/KwwadNkLxHX5xUC5BkzEiK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/STIxW/btsKfGjhPji/KwwadNkLxHX5xUC5BkzEiK/img.png&quot; data-alt=&quot;APTable fields&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/STIxW/btsKfGjhPji/KwwadNkLxHX5xUC5BkzEiK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSTIxW%2FbtsKfGjhPji%2FKwwadNkLxHX5xUC5BkzEiK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;787&quot; height=&quot;214&quot; data-origin-width=&quot;787&quot; data-origin-height=&quot;214&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;APTable fields&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&amp;nbsp;UXNTable/XNTable&lt;/b&gt;&lt;/h4&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div data-message-model-slug=&quot;gpt-4o&quot; data-message-id=&quot;5ceabdc8-1341-44a3-bd9c-0466f718f372&quot; data-message-author-role=&quot;assistant&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Unprivileged eXecute Never (UXN) / eXecute Never (XN)을 나타냅니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Stage 1에서 여러 VA(Virtual Address) 범위가 지원되는 경우, 이 필드는 UXNTable이라고 불리며, 이후 레벨 조회에서 참조된 영역에서 가져온 명령어가 EL0에서 실행될 수 있는지 여부를 결정합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Stage 1에서 하나의 VA만 지원되는 경우, 이 필드는 XNTable이며 동일한 변환 단계에서 eXecute Never 동작을 제어합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;UXNTable 비트가 1로 설정되면, 실제 디스크립터에 설정된 값과 관계없이 모든 후속 레벨 조회에서 UXN 비트가 설정된 것으로 간주됩니다.&lt;/li&gt;
&lt;li&gt;XNTable 비트가 1로 설정되면, 실제 디스크립터에 설정된 값과 관계없이 모든 후속 레벨 조회에서 XN 비트가 설정된 것으로 간주됩니다.&lt;/li&gt;
&lt;li&gt;0으로 설정되면, 이 비트는 아무런 영향을 미치지 않습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p id=&quot;a5bf&quot; style=&quot;background-color: #ffffff; color: #242424; text-align: start;&quot; data-selectable-paragraph=&quot;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;background-color: #ffffff; color: #242424; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&amp;nbsp;PXNTable&lt;/b&gt;&lt;/h4&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div data-message-model-slug=&quot;gpt-4o&quot; data-message-id=&quot;0b113dd2-41e9-408d-a3c9-388faa0e0734&quot; data-message-author-role=&quot;assistant&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Privileged eXecute Never(PXN)을 나타냅니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이 비트는 두 개의 VA(Virtual Address) 범위를 지원할 수 있는 Stage 1 변환에서만 유효하며, 하나의 VA 범위만 지원하는 Stage 1 변환에서는 RES0로 간주됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;PXNTable 비트가 1로 설정되면, 실제 디스크립터에 설정된 값과 상관없이 이후 모든 레벨 조회에서 PXN 비트가 1로 설정된 것으로 간주됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이에 따라 해당 영역에서 가져온 명령어는 EL1 및 더 높은 예외 레벨에서 실행될 수 없습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;- Block/Page descrioptors&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div data-message-model-slug=&quot;gpt-4o&quot; data-message-id=&quot;bf044c5e-5c2a-47aa-8128-27390e441b90&quot; data-message-author-role=&quot;assistant&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이 글에서는 다양한 페이지 테이블 항목의 형식에 대해 설명합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;페이지 테이블의 블록 디스크립터 항목은 비트[1:0]이 0b01입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;페이지 디스크립터 항목은 비트[1:0]이 0b11이며, AARCH64에서의 페이지 레벨은 반드시 3개 이어야 합니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;726&quot; data-origin-height=&quot;201&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/DBjfw/btsKhnbfUam/tOKKhSvWW1cN6XyO7G59J0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/DBjfw/btsKhnbfUam/tOKKhSvWW1cN6XyO7G59J0/img.png&quot; data-alt=&quot;AArch64 Page descriptor format (TG size = 4KB)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/DBjfw/btsKhnbfUam/tOKKhSvWW1cN6XyO7G59J0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FDBjfw%2FbtsKhnbfUam%2FtOKKhSvWW1cN6XyO7G59J0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;726&quot; height=&quot;201&quot; data-origin-width=&quot;726&quot; data-origin-height=&quot;201&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;AArch64 Page descriptor format (TG size = 4KB)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;726&quot; data-origin-height=&quot;237&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Cs9qc/btsKfHvNYJH/epdwcK6I6m4mXlgD4TjIY1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Cs9qc/btsKfHvNYJH/epdwcK6I6m4mXlgD4TjIY1/img.png&quot; data-alt=&quot;AArch64 Block descriptor format (TG size = 4KB)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Cs9qc/btsKfHvNYJH/epdwcK6I6m4mXlgD4TjIY1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FCs9qc%2FbtsKfHvNYJH%2FepdwcK6I6m4mXlgD4TjIY1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;726&quot; height=&quot;237&quot; data-origin-width=&quot;726&quot; data-origin-height=&quot;237&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;AArch64 Block descriptor format (TG size = 4KB)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div data-message-model-slug=&quot;gpt-4o&quot; data-message-id=&quot;9209dd33-b90e-46d3-a68e-ca3296223ba9&quot; data-message-author-role=&quot;assistant&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;페이지 테이블 항목(블록 디스크립터, 페이지 디스크립터, 테이블 디스크립터)의 필드 의미는 사용 중인 변환 체제(translation regime)에 따라 달라집니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&quot;b703&quot; style=&quot;background-color: #ffffff; color: #242424; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;- Page/Block descriptor attributes&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;809&quot; data-origin-height=&quot;384&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cPJm6Z/btsKgfZvnXL/PmNBg7vyuCmnEGVTkDifqk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cPJm6Z/btsKgfZvnXL/PmNBg7vyuCmnEGVTkDifqk/img.png&quot; data-alt=&quot;AArch64 Page/Block descriptor attributes&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cPJm6Z/btsKgfZvnXL/PmNBg7vyuCmnEGVTkDifqk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcPJm6Z%2FbtsKgfZvnXL%2FPmNBg7vyuCmnEGVTkDifqk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;809&quot; height=&quot;384&quot; data-origin-width=&quot;809&quot; data-origin-height=&quot;384&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;AArch64 Page/Block descriptor attributes&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;UXN&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;br /&gt;비트 54는 Stage 1에서 두 개의 VA(Virtual Address) 범위를 지원하는 변환 체제에 대한 Stage 1 테이블 항목에서만 UXN으로 정의됩니다. 이 필드는 EL0 코드 실행에만 적용됩니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;0일 경우, EL0에서 코드 실행이 허용됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;XN&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;br /&gt;비트 54는 Stage 1에서 하나의 VA 범위만 지원하는 변환 체제에 대해 XN으로 정의됩니다. 이 필드는 변환이 적용되는 모든 예외 레벨에 적용됩니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;0일 경우, 코드 실행이 허용되며, 그렇지 않으면 실행이 금지됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;PXN&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;br /&gt;비트 53은 Stage 1에서 두 개의 VA 범위를 지원하는 변환 체제에 대한 Stage 1 테이블 항목에서만 PXN으로 정의됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;하나의 VA 범위만 지원하는 TR에서는 이 비트가 RES0로 설정되어 하드웨어에서 무시됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이 필드는 EL0 이상의 예외 레벨에서만 적용됩니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;0일 경우, 코드 실행이 허용됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Contiguous&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;br /&gt;Stage 2의 초기 조회에만 적용되며, 동일한 속성 및 권한을 공유하는 항목들이 단일 TLB 항목에 캐시될 수 있음을 하드웨어에 정보를 제공합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;DBM (Dirty Bit Modification)&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;br /&gt;이 비트는 페이지 또는 메모리 섹션의 내용이 수정되었음을 나타냅니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;하드웨어 액세스 플래그 관리가 활성화되면 이 비트는 하드웨어에서 옵션으로 제어될 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이를 활성화하려면 TCR_ELx 레지스터의 HD 필드(TCR_ELx.HD)를 설정합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이 기능은 하드웨어 구현에 따라 옵션으로 제공되고 지원되지 않으면 TCR_ELx.HD는 RES0로 간주됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;nG (non-Global)&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;br /&gt;비트 11은 Stage 1에서 두 개의 VA 범위를 지원하는 변환 체제의 테이블 항목에서만 nG로 정의됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;하나의 VA 범위를 지원하는 TR에서는 이 비트가 RES0로 설정되고 하드웨어에서 무시됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;AF (Access Flag)&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이 비트는 ARMv8.0에서 소프트웨어에 의해 관리되며, ARMv8.1-TTHM 확장이 구현된 경우 하드웨어에 의해 옵션으로 관리될 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이 비트는 페이지나 블록이 처음 액세스되었을 때 설정됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;AF == 0으로 설정된 디스크립터 항목이 TLB로 읽히려고 할 때마다 액세스 오류가 발생하며, 소프트웨어는 해당 디스크립터의 AF를 1로 설정해야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;SH[1:0] (Shareability)&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;br /&gt;이는 캐시 가능한 메모리에만 적용되며(AttrInx[2:0]에 의해 결정), Stage 1 및 Stage 2에서 다음과 같은 의미를 가집니다(0b01은 예약됨):&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;0b00: 비공유 가능&lt;/li&gt;
&lt;li&gt;0b10: 외부 공유 가능&lt;/li&gt;
&lt;li&gt;0b11: 내부 공유 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;AP[2:1] (Access Permissions)&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;br /&gt;Stage 1 변환에서(여러 예외 레벨을 포함하는 TR의 경우):&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;0b00: EL0에서 액세스 불가, 상위 레벨에서 읽기/쓰기 가능&lt;/li&gt;
&lt;li&gt;0b01: EL0에서 읽기/쓰기 가능, 상위 레벨에서 읽기/쓰기 가능&lt;/li&gt;
&lt;li&gt;0b10: EL0에서 액세스 불가, 상위 레벨에서 읽기만 가능&lt;/li&gt;
&lt;li&gt;0b11: EL0에서 읽기만 가능, 상위 레벨에서 읽기만 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Stage 1 변환(TR이 단일 예외 레벨을 포함하는 경우), AP[1]은 RES1로 설정됩니다:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;0b0: 읽기/쓰기 가능&lt;/li&gt;
&lt;li&gt;0b1: 읽기만 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Stage 2 변환에서는 S2AP 필드가 액세스 권한에 영향을 미치며 AP[2:1]과 결합됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;NS (Non-Secure Access Control)&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;0b1: 보안 및 비보안 실행 상태에서 액세스 허용&lt;/li&gt;
&lt;li&gt;0b0: 보안 실행 상태에서만 액세스 허용&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;MemAttr[3:0] (Memory Attribute Index)&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;br /&gt;MAIR_ELx 레지스터에서 메모리 속성 인덱스를 나타내며, 디바이스 메모리와 일반 메모리를 구분할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;일반 메모리의 경우 캐시 가능성(Writeback/Writethrough), 공유 가능성(내부/외부), 할당 정책(Read/Write) 등의 정보를 포함합니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Writable 메모리에서 실행 방지&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;br /&gt;추가 보안 조치로 AArch64는 모든 예외 레벨과 변환 체제에서 쓰기 가능한 메모리에서의 실행을 방지하는 기능을 제공합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이 기능은 레지스터 필드 SCTLR_ELx.WXN에 의해 제어됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;EL0와 상위 EL에 적용되는 TR에서 해당 SCTLR_ELx.WXN == 1로 설정되면:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Stage 1 변환의 EL0에서 쓰기 가능한 모든 영역은 XN == 1로 처리됩니다.&lt;/li&gt;
&lt;li&gt;Stage 1 변환의 EL1에서 쓰기 가능한 모든 영역은 PXN == 1로 처리됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;단일 예외 레벨에만 적용되는 TR에서 SCTLR_ELx.WXN == 1로 설정되면, Stage 1 변환에서 쓰기 가능한 모든 영역은 UXN == 1로 처리됩니다.&lt;/p&gt;</description>
      <category>System Programming/Arm</category>
      <author>줄람이</author>
      <guid isPermaLink="true">https://julrams.tistory.com/38</guid>
      <comments>https://julrams.tistory.com/38#entry38comment</comments>
      <pubDate>Sun, 31 Mar 2024 16:50:21 +0900</pubDate>
    </item>
    <item>
      <title>라즈베리파이(RPI)4 OpenOCD JTAG 연결 디버깅 방법</title>
      <link>https://julrams.tistory.com/37</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;임베디드 시스템 개발 및 분석 중 라즈베리 파이4를 통해 디버깅 및 테스트를 하는 것이 제일 간단하고 유용할 것으로 예상되어 찾아본 결과 라즈베리파이4 자체의 JTAG Pin을 활용하여 ARM64 환경의 Bare-Metal Code 테스트를 진행 할 수 있으며 쉽게 테스트 및 디버깅이 가능하여 테스트 및 응용에 매우 강력하고 유용한 플랫폼으로 활용이 가능할 것으로 생각한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대략적인 연결 방법은 라즈베리파이4 Bare-Metal Code 로드 및 디버깅과 커널 디버깅에 사용할 수 있도록 OpenOCD를 사용하여 JTAG Interface를 활용 및 연결해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러기 위해서 라즈베리파이의 JTAG Pin을 소유하고 있는 JTAG Debugger (Olimex ARM-USB-OCD-H) 연결하여 TAP 인식 및 ARM Core Debugging 이 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;라즈베리파이4의 JTAG Pin 위치는 하기와 같다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;372&quot; data-origin-height=&quot;243&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oSRDT/btskhMhBcUj/pv9rFox6sGQuKr6qhgkAg1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oSRDT/btskhMhBcUj/pv9rFox6sGQuKr6qhgkAg1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oSRDT/btskhMhBcUj/pv9rFox6sGQuKr6qhgkAg1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FoSRDT%2FbtskhMhBcUj%2Fpv9rFox6sGQuKr6qhgkAg1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;372&quot; height=&quot;243&quot; data-origin-width=&quot;372&quot; data-origin-height=&quot;243&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위에 나와있는 그림처럼 RPI의 JTAG Pin을 참고하여 사용하고자 하는 JTAG(여기서는 Olimex ARM-USB-OCD-H)의 Pin Map을 확인하여 1대1 연결하여 JTAG 통신 환경을 구축한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1047&quot; data-origin-height=&quot;1321&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cFjoZv/btsqHT2oMuj/vDFJi4kb5bdtBvLHlFOTx1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cFjoZv/btsqHT2oMuj/vDFJi4kb5bdtBvLHlFOTx1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cFjoZv/btsqHT2oMuj/vDFJi4kb5bdtBvLHlFOTx1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcFjoZv%2FbtsqHT2oMuj%2FvDFJi4kb5bdtBvLHlFOTx1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1047&quot; height=&quot;1321&quot; data-origin-width=&quot;1047&quot; data-origin-height=&quot;1321&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;라즈베리파이에서 JTAG Pin을 사용하기 위해서는 Default Pin Func(Mux)가 JTAG 용도로 정의 되어 있지 않기 때문에&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하기와 같이 booting 시 config.txt에 기입하여 Pin Mux를 진행하여야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1691547738493&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[all]
# Disable pull downs
gpio=22-27=np

# Enable jtag pins (i.e. GPIO22-GPIO27)
enable_jtag_gpio=1&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;OpenOCD에서 rpi4 디버깅 연결을 위하여 하기와 같이 rpi4 관련된 config 파일을 생성해야 하는데 하기와 같이 작성하여&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;rpi4.cfg를 /share/openocd/script/targets 내에 저장해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1691551300481&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# SPDX-License-Identifier: GPL-2.0-or-later

# The Broadcom BCM2711 used in Raspberry Pi 4
# No documentation was found on Broadcom website

# Partial information is available in raspberry pi website:
# https://www.raspberrypi.org/documentation/hardware/raspberrypi/bcm2711/

if { [info exists CHIPNAME] } {
    set  _CHIPNAME $CHIPNAME
} else {
    set  _CHIPNAME bcm2711
}

if { [info exists CHIPCORES] } {
    set _cores $CHIPCORES
} else {
    set _cores 4
}

if { [info exists USE_SMP] } {
    set _USE_SMP $USE_SMP
} else {
    set _USE_SMP 0
}

if { [info exists DAP_TAPID] } {
    set _DAP_TAPID $DAP_TAPID
} else {
    set _DAP_TAPID 0x4ba00477
}

jtag newtap $_CHIPNAME cpu -expected-id $_DAP_TAPID -irlen 4
adapter speed 3000

dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu

# MEM-AP for direct access
target create $_CHIPNAME.ap mem_ap -dap $_CHIPNAME.dap -ap-num 0

# these addresses are obtained from the ROM table via 'dap info 0' command
set _DBGBASE {0x80410000 0x80510000 0x80610000 0x80710000}
set _CTIBASE {0x80420000 0x80520000 0x80620000 0x80720000}

set _smp_command &quot;target smp&quot;

for { set _core 0 } { $_core &amp;lt; $_cores } { incr _core } {
    set _CTINAME $_CHIPNAME.cti$_core
    set _TARGETNAME $_CHIPNAME.cpu$_core

    cti create $_CTINAME -dap $_CHIPNAME.dap -ap-num 0 -baseaddr [lindex $_CTIBASE $_core]
    target create $_TARGETNAME aarch64 -dap $_CHIPNAME.dap -ap-num 0 -dbgbase [lindex $_DBGBASE $_core] -cti $_CTINAME

    set _smp_command &quot;$_smp_command $_TARGETNAME&quot;
}

if {$_USE_SMP} {
    eval $_smp_command
}

# default target is cpu0
targets $_CHIPNAME.cpu0&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;OpenOCD 실행을 하기와 같이 JTAG Interface와 RPI4에 관련된 cfg 파일을 -f 매개인자를 통하여 실행한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1691551238774&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;.\bin\openocd.exe -f .\share\openocd\scripts\interface\ftdi\olimex-arm-usb-ocd-h.cfg -f .\share\openocd\scripts\target\rpi4.cfg&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 명령을 통해 OpenOCD를 터미널 혹은 PowerShell 상에서 실행하여&amp;nbsp; 아래의 그림과 같이 GDB Server 와 Telnet Port가 생성되는 것을 확인 할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1097&quot; data-origin-height=&quot;437&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eAauLB/btsqFrY9mM5/xmtoadfKqDmzqK9jK1hdl1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eAauLB/btsqFrY9mM5/xmtoadfKqDmzqK9jK1hdl1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eAauLB/btsqFrY9mM5/xmtoadfKqDmzqK9jK1hdl1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeAauLB%2FbtsqFrY9mM5%2FxmtoadfKqDmzqK9jK1hdl1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1097&quot; height=&quot;437&quot; data-origin-width=&quot;1097&quot; data-origin-height=&quot;437&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GDB Server가 정상적으로 실행되면 Rpi4의 Kernel 또는 Bare-metal Code를 작성하여 빌드 후 테스트 할 수 있는 환경을 갖추게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 이후의 GDB Server Remote 연결 및 GDB 디버깅은 다음 포스트에서 진행하도록 하겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>System Programming/Arm</category>
      <author>줄람이</author>
      <guid isPermaLink="true">https://julrams.tistory.com/37</guid>
      <comments>https://julrams.tistory.com/37#entry37comment</comments>
      <pubDate>Sun, 18 Jun 2023 23:40:34 +0900</pubDate>
    </item>
    <item>
      <title>VirtualBox 우분투 공유 폴더 권한 설정</title>
      <link>https://julrams.tistory.com/36</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;Virtualbox 사용 시 윈도우와 서로 파일을 주고 받기 편하기 위해 공유 폴더를 설정 할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만, 아래의 그림처럼 설정을 완료하고 사용하려 해도 권한 문제가 발생한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1273&quot; data-origin-height=&quot;897&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bEo8XI/btrdxn2qJuS/gkKJ7QY6gSSkZ2NuF1iPa1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bEo8XI/btrdxn2qJuS/gkKJ7QY6gSSkZ2NuF1iPa1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bEo8XI/btrdxn2qJuS/gkKJ7QY6gSSkZ2NuF1iPa1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbEo8XI%2Fbtrdxn2qJuS%2FgkKJ7QY6gSSkZ2NuF1iPa1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1273&quot; height=&quot;897&quot; data-origin-width=&quot;1273&quot; data-origin-height=&quot;897&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;654&quot; data-origin-height=&quot;306&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/x3WRx/btrdrl5Tmer/MN6vwvstvjzdk0zVnUY2c0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/x3WRx/btrdrl5Tmer/MN6vwvstvjzdk0zVnUY2c0/img.png&quot; data-alt=&quot;폴더 권한 예시&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/x3WRx/btrdrl5Tmer/MN6vwvstvjzdk0zVnUY2c0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fx3WRx%2Fbtrdrl5Tmer%2FMN6vwvstvjzdk0zVnUY2c0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;654&quot; height=&quot;306&quot; data-origin-width=&quot;654&quot; data-origin-height=&quot;306&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;폴더 권한 예시&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자동 마운트 되는 경로는 '/media' 내에 모두 디렉토리가 생성되어 마운트 되어 있을 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래의 그림과 같이 'media' 경로 안에서 'ls -al' 명령어를 통해 확인해 보면 그룹 권한이 'vboxsf' 로 되어 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;749&quot; data-origin-height=&quot;259&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/JXtuY/btrdr4iww2k/fWRWunTZSQa3lWFrhtNdD0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/JXtuY/btrdr4iww2k/fWRWunTZSQa3lWFrhtNdD0/img.png&quot; data-alt=&quot;디렉토리 권한 체크&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/JXtuY/btrdr4iww2k/fWRWunTZSQa3lWFrhtNdD0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJXtuY%2Fbtrdr4iww2k%2FfWRWunTZSQa3lWFrhtNdD0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;749&quot; height=&quot;259&quot; data-origin-width=&quot;749&quot; data-origin-height=&quot;259&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;디렉토리 권한 체크&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 상황에서 간단한 해결 방법은 내가 사용하는 유저를 'vboxsf' 그룹에 포함 시켜주어야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;708&quot; data-origin-height=&quot;108&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/enN6Ml/btrdzPqRRHV/B1XjWdA9KNY3USylqQmHGk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/enN6Ml/btrdzPqRRHV/B1XjWdA9KNY3USylqQmHGk/img.png&quot; data-alt=&quot;vboxsf 그룹 등록 명령&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/enN6Ml/btrdzPqRRHV/B1XjWdA9KNY3USylqQmHGk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FenN6Ml%2FbtrdzPqRRHV%2FB1XjWdA9KNY3USylqQmHGk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;708&quot; height=&quot;108&quot; data-origin-width=&quot;708&quot; data-origin-height=&quot;108&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;vboxsf 그룹 등록 명령&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 그림과 같이 'sudo gpasswd -a USER_ID vboxsf' 명령을 통해 그룹 등록을 진행해주어야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;주의해야 할 점은 그룹 등록이 완료되었다 하더라도 이미 로그인된 세션에는 해당 권한이 적용되지 않으므로&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;재부팅 또는 로그아웃을 진행해주어야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;675&quot; data-origin-height=&quot;476&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/OfpZv/btrdpMiPDZz/yoQAnG2Xje7R9YkzJJVCIK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/OfpZv/btrdpMiPDZz/yoQAnG2Xje7R9YkzJJVCIK/img.png&quot; data-alt=&quot;재부팅 후 공유 폴더 내용 확인 예시&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/OfpZv/btrdpMiPDZz/yoQAnG2Xje7R9YkzJJVCIK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FOfpZv%2FbtrdpMiPDZz%2FyoQAnG2Xje7R9YkzJJVCIK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;675&quot; height=&quot;476&quot; data-origin-width=&quot;675&quot; data-origin-height=&quot;476&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;재부팅 후 공유 폴더 내용 확인 예시&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>System Programming/Tips</category>
      <author>줄람이</author>
      <guid isPermaLink="true">https://julrams.tistory.com/36</guid>
      <comments>https://julrams.tistory.com/36#entry36comment</comments>
      <pubDate>Sun, 29 Aug 2021 19:37:04 +0900</pubDate>
    </item>
  </channel>
</rss>