xaizek / tos (License: GPLv3 only) (since 2018-12-07)
This is an alternative version of sources presented as part of Write Your Own OS video tutorial by Viktor Engelmann.
Commit 1be74550a6ab6b6e7176fb9e9eacc2df79e87d3b

Use span class in more places
Author: xaizek
Author date (UTC): 2018-04-12 09:03
Committer name: xaizek
Committer date (UTC): 2018-04-12 13:51
Parent(s): ab4ef349f8e17a60646f91e998b0c522de771692
Signing key: 99DC5E4DB05F6BE2
Tree: 8b6eccc348e1b1ddea2e0ff83bf46a377205928b
File Lines added Lines deleted
src/drv/ATA.cpp 13 14
src/drv/ATA.hpp 5 5
src/fs/fat.cpp 4 6
src/fs/mbr.cpp 1 1
src/net/icmp.cpp 2 3
src/net/ipv4.cpp 6 6
src/net/ipv4.hpp 1 2
src/net/tcp.cpp 1 1
src/utils/span.hpp 9 0
File src/drv/ATA.cpp changed (mode: 100644) (index cb0a753..b5735dc)
... ... ATA::identify()
59 59 } }
60 60
61 61 void void
62 ATA::read28(std::uint32_t sectorNum, std::uint8_t data[], int count)
62 ATA::read28(std::uint32_t sectorNum, span<std::uint8_t> buf)
63 63 { {
64 64 if (sectorNum > 0x0fffffff) { if (sectorNum > 0x0fffffff) {
65 65 return; return;
 
... ... ATA::read28(std::uint32_t sectorNum, std::uint8_t data[], int count)
80 80 return; return;
81 81 } }
82 82
83 for (int i = 0; i < count; i += 2) {
83 for (int i = 0; i < buf.size(); i += 2) {
84 84 const std::uint16_t wdata = dataPort.read(); const std::uint16_t wdata = dataPort.read();
85 data[i] = wdata & 0x00FF;
86 if (i + 1 < count) {
87 data[i + 1] = (wdata >> 8) & 0xff;
85 buf[i] = wdata & 0x00FF;
86 if (i + 1 < buf.size()) {
87 buf[i + 1] = (wdata >> 8) & 0xff;
88 88 } }
89 89 } }
90 90
91 for (int i = count + count%2; i < 512; i += 2) {
91 for (int i = buf.size() + buf.size()%2; i < 512; i += 2) {
92 92 dataPort.read(); dataPort.read();
93 93 } }
94 94 } }
95 95
96 96 void void
97 ATA::write28(std::uint32_t sectorNum,
98 const std::uint8_t data[], std::uint32_t count)
97 ATA::write28(std::uint32_t sectorNum, span<const std::uint8_t> buf)
99 98 { {
100 99 if (sectorNum > 0x0fffffff) { if (sectorNum > 0x0fffffff) {
101 100 return; return;
102 101 } }
103 if (count > 512) {
102 if (buf.size() > 512) {
104 103 return; return;
105 104 } }
106 105
 
... ... ATA::write28(std::uint32_t sectorNum,
116 115
117 116 kprint("Writing to ATA Drive: "); kprint("Writing to ATA Drive: ");
118 117
119 for (std::uint32_t i = 0; i < count; i += 2) {
120 std::uint16_t wdata = data[i];
121 if (i + 1 < count) {
122 wdata |= static_cast<std::uint16_t>(data[i + 1]) << 8;
118 for (int i = 0; i < buf.size(); i += 2) {
119 std::uint16_t wdata = buf[i];
120 if (i + 1 < buf.size()) {
121 wdata |= static_cast<std::uint16_t>(buf[i + 1]) << 8;
123 122 } }
124 123 dataPort.write(wdata); dataPort.write(wdata);
125 124
 
... ... ATA::write28(std::uint32_t sectorNum,
129 128 kprint(text); kprint(text);
130 129 } }
131 130
132 for (int i = count + (count%2); i < 512; i += 2) {
131 for (int i = buf.size() + (buf.size()%2); i < 512; i += 2) {
133 132 dataPort.write(0x0000); dataPort.write(0x0000);
134 133 } }
135 134 } }
File src/drv/ATA.hpp changed (mode: 100644) (index 319f582..67d6ec0)
3 3
4 4 #include <cstdint> #include <cstdint>
5 5
6 #include <hwcomm/Port.hpp>
7 #include <hwcomm/interrupts.hpp>
6 #include "hwcomm/Port.hpp"
7 #include "hwcomm/interrupts.hpp"
8 #include "utils/span.hpp"
8 9
9 10 namespace drv { namespace drv {
10 11
 
... ... public:
15 16
16 17 public: public:
17 18 void identify(); void identify();
18 void read28(std::uint32_t sectorNum, std::uint8_t data[], int count = 512);
19 void write28(std::uint32_t sectorNum,
20 const std::uint8_t data[], std::uint32_t count);
19 void read28(std::uint32_t sectorNum, span<std::uint8_t> buf);
20 void write28(std::uint32_t sectorNum, span<const std::uint8_t> buf);
21 21 void flush(); void flush();
22 22
23 23 private: private:
File src/fs/fat.cpp changed (mode: 100644) (index 73d5fce..a8659ca)
... ... using namespace fs;
7 7
8 8 FAT::FAT(drv::ATA &hd, std::uint32_t partitionOffset) : hd(hd) FAT::FAT(drv::ATA &hd, std::uint32_t partitionOffset) : hd(hd)
9 9 { {
10 hd.read28(partitionOffset, reinterpret_cast<std::uint8_t *>(&bpb),
11 sizeof(BiosParameterBlock32));
10 hd.read28(partitionOffset, as_writable_bytes(bpb));
12 11
13 12 kprint("sectors per cluster: ", bpb.sectorsPerCluster, "\n"); kprint("sectors per cluster: ", bpb.sectorsPerCluster, "\n");
14 13
 
... ... void
21 20 FAT::printFiles() FAT::printFiles()
22 21 { {
23 22 DirectoryEntryFat32 dirent[16]; DirectoryEntryFat32 dirent[16];
24 hd.read28(rootStart, reinterpret_cast<std::uint8_t *>(&dirent[0]),
25 16*sizeof(DirectoryEntryFat32));
23 hd.read28(rootStart, as_writable_bytes(dirent));
26 24
27 25 for (int i = 0; i < 16; ++i) { for (int i = 0; i < 16; ++i) {
28 26 if (dirent[i].name[0] == 0x00) { if (dirent[i].name[0] == 0x00) {
 
... ... FAT::printFileContents(const DirectoryEntryFat32 &ent) const
62 60 int sectorOffset = 0; int sectorOffset = 0;
63 61
64 62 while (size > 0) { while (size > 0) {
65 hd.read28(sector + sectorOffset, buffer, 512);
63 hd.read28(sector + sectorOffset, { buffer, 512 });
66 64
67 65 buffer[size > 512 ? 512 : size] = '\0'; buffer[size > 512 ? 512 : size] = '\0';
68 66 kprint(reinterpret_cast<const char *>(buffer)); kprint(reinterpret_cast<const char *>(buffer));
 
... ... FAT::printFileContents(const DirectoryEntryFat32 &ent) const
80 78
81 79 std::uint8_t fat[512]; std::uint8_t fat[512];
82 80 std::uint32_t fatSector = currentCluster/(512/sizeof(std::uint32_t)); std::uint32_t fatSector = currentCluster/(512/sizeof(std::uint32_t));
83 hd.read28(fatStart + fatSector, fat, 512);
81 hd.read28(fatStart + fatSector, fat);
84 82 std::uint32_t fatOffset = currentCluster%(512/sizeof(std::uint32_t))*4; std::uint32_t fatOffset = currentCluster%(512/sizeof(std::uint32_t))*4;
85 83
86 84 currentCluster = fat[fatOffset + 3] & 0x0f; currentCluster = fat[fatOffset + 3] & 0x0f;
File src/fs/mbr.cpp changed (mode: 100644) (index 4b977ad..09c1e21)
... ... MBR::readPartitions(drv::ATA &hd)
14 14
15 15 kprint("MBR: "); kprint("MBR: ");
16 16
17 hd.read28(0, (uint8_t*)&mbr, sizeof(MasterBootRecord));
17 hd.read28(0, as_writable_bytes(mbr));
18 18
19 19 if (mbr.magicnumber != 0xAA55) { if (mbr.magicnumber != 0xAA55) {
20 20 kprint("illegal MBR"); kprint("illegal MBR");
File src/net/icmp.cpp changed (mode: 100644) (index ae58a4f..465cc95)
... ... ICMP::onIPReceived(NetOrder<std::uint32_t> srcIP,
27 27 case 8: case 8:
28 28 icmpMsg.type = netOrder<std::uint8_t>(0); icmpMsg.type = netOrder<std::uint8_t>(0);
29 29 icmpMsg.checksum = netOrder<std::uint16_t>(0); icmpMsg.checksum = netOrder<std::uint16_t>(0);
30 icmpMsg.checksum = IPProvider::checksum(msg.data(),
31 ICMPMsg::size());
30 icmpMsg.checksum = IPProvider::checksum(msg.first(ICMPMsg::size()));
32 31 return true; return true;
33 32 } }
34 33
 
... ... ICMP::requestEchoReply(NetOrder<std::uint32_t> ip)
44 43 icmp.code = netOrder<std::uint8_t>(0); icmp.code = netOrder<std::uint8_t>(0);
45 44 icmp.data = toNetOrder<std::uint32_t>(0x13370000); icmp.data = toNetOrder<std::uint32_t>(0x13370000);
46 45 icmp.checksum = netOrder<std::uint16_t>(0); icmp.checksum = netOrder<std::uint16_t>(0);
47 icmp.checksum = IPProvider::checksum(data, ICMPMsg::size());
46 icmp.checksum = IPProvider::checksum(data);
48 47
49 48 send(ip, data); send(ip, data);
50 49 } }
File src/net/ipv4.cpp changed (mode: 100644) (index 9ba6d06..a7068c3)
... ... IPProvider::onEtherFrameReceived(span<std::uint8_t> msg)
62 62 ipHdr.srcIP = temp; ipHdr.srcIP = temp;
63 63
64 64 ipHdr.timeToLive = netOrder<std::uint8_t>(0x40); ipHdr.timeToLive = netOrder<std::uint8_t>(0x40);
65 ipHdr.checksum = checksum(msg.data(), headerLength);
65 ipHdr.checksum = checksum(msg.first(headerLength));
66 66 } }
67 67
68 68 return sendBack; return sendBack;
 
... ... IPProvider::send(NetOrder<std::uint32_t> dstIP, std::uint8_t protocol,
91 91 ipHdr.srcIP = backend.getIPAddress(); ipHdr.srcIP = backend.getIPAddress();
92 92
93 93 ipHdr.checksum = netOrder<std::uint16_t>(0); ipHdr.checksum = netOrder<std::uint16_t>(0);
94 ipHdr.checksum = checksum(buffer.get(), IPv4Msg::size());
94 ipHdr.checksum = checksum({ buffer.get(), IPv4Msg::size() });
95 95
96 96 std::uint8_t* databuffer = buffer.get() + IPv4Msg::size(); std::uint8_t* databuffer = buffer.get() + IPv4Msg::size();
97 97 for (int i = 0; i < msg.size(); ++i) { for (int i = 0; i < msg.size(); ++i) {
 
... ... IPProvider::send(NetOrder<std::uint32_t> dstIP, std::uint8_t protocol,
108 108 } }
109 109
110 110 NetOrder<std::uint16_t> NetOrder<std::uint16_t>
111 IPProvider::checksum(std::uint8_t data[], std::uint32_t size)
111 IPProvider::checksum(span<const std::uint8_t> data)
112 112 { {
113 113 std::uint32_t temp = 0U; std::uint32_t temp = 0U;
114 114
115 for (std::uint32_t i = 0U; i + 1 < size; i += 2) {
115 for (int i = 0U; i + 1 < data.size(); i += 2) {
116 116 temp += (static_cast<std::uint16_t>(data[i]) << 8) | data[i + 1]; temp += (static_cast<std::uint16_t>(data[i]) << 8) | data[i + 1];
117 117 } }
118 118
119 if (size % 2) {
120 temp += static_cast<uint16_t>(data[size - 1U]) << 8;
119 if (data.size() % 2) {
120 temp += static_cast<uint16_t>(data[data.size() - 1U]) << 8;
121 121 } }
122 122
123 123 while (temp & 0xffff0000) { while (temp & 0xffff0000) {
File src/net/ipv4.hpp changed (mode: 100644) (index 1758d3b..1aadf28)
... ... public:
70 70 span<const std::uint8_t> msg); span<const std::uint8_t> msg);
71 71
72 72 public: public:
73 static NetOrder<std::uint16_t> checksum(std::uint8_t data[],
74 std::uint32_t size);
73 static NetOrder<std::uint16_t> checksum(span<const std::uint8_t> data);
75 74
76 75 private: private:
77 76 virtual bool onEtherFrameReceived(span<std::uint8_t> msg) override; virtual bool onEtherFrameReceived(span<std::uint8_t> msg) override;
File src/net/tcp.cpp changed (mode: 100644) (index 88aaae0..632b4e2)
... ... TCPProvider::send(TCPSocket &socket, span<const std::uint8_t> buf,
235 235 phdr.totalLength = toNetOrder(totalLength); phdr.totalLength = toNetOrder(totalLength);
236 236
237 237 tcpHdr.checksum = toNetOrder<std::uint16_t>(0); tcpHdr.checksum = toNetOrder<std::uint16_t>(0);
238 tcpHdr.checksum = IPProvider::checksum(buffer.get(), lengthInclPHdr);
238 tcpHdr.checksum = IPProvider::checksum({ buffer.get(), lengthInclPHdr });
239 239
240 240 IPHandler::send(socket.remoteIP, IPHandler::send(socket.remoteIP,
241 241 { buffer.get() + TCPPseudoHeader::size(), totalLength }); { buffer.get() + TCPPseudoHeader::size(), totalLength });
File src/utils/span.hpp changed (mode: 100644) (index a88307b..17d9339)
... ... as_bytes(span<T> s) noexcept
125 125 }; };
126 126 } }
127 127
128 template <typename T>
129 constexpr span<std::uint8_t>
130 as_writable_bytes(T &d) noexcept
131 {
132 return span<std::uint8_t> {
133 reinterpret_cast<std::uint8_t *>(&d), sizeof(d)
134 };
135 }
136
128 137 #endif // TOS__UTILS__SPAN_HPP__ #endif // TOS__UTILS__SPAN_HPP__
Hints

Before first commit, do not forget to setup your git environment:
git config --global user.name "your_name_here"
git config --global user.email "your@email_here"

Clone this repository using HTTP(S):
git clone https://code.reversed.top/user/xaizek/tos

Clone this repository using ssh (do not forget to upload a key first):
git clone ssh://rocketgit@code.reversed.top/user/xaizek/tos

You are allowed to anonymously push to this repository.
This means that your pushed commits will automatically be transformed into a pull request:
... clone the repository ...
... make some changes and some commits ...
git push origin master